2015-02-23 37 views
3

由于我工作的OBD阅读器演示。通过我的应用我试图连接OBD读取器设备与我的应用程序安装在的Nexus 7.OBD阅读器设备正在连接到其他应用程序,这是可用的谷歌播放,但如果我与我的应用程序连接它得到错误java.io.IOException:bt套接字关闭,读取返回:-1连接后建立。任何建议... == ================================================== =====产生java.io.IOException:BT插座关闭,读返回:-1

**MainActivity:-** 

     import java.io.BufferedReader; 
     import java.io.IOException; 
     import java.io.InputStream; 
     import java.io.InputStreamReader; 
     import java.io.OutputStream; 
     import java.lang.reflect.Method; 
     import java.util.ArrayList; 
     import java.util.Set; 
     import java.util.UUID; 

     import android.annotation.SuppressLint; 
     import android.app.AlertDialog; 
     import android.bluetooth.BluetoothAdapter; 
     import android.bluetooth.BluetoothDevice; 
     import android.bluetooth.BluetoothSocket; 
     import android.content.DialogInterface; 
     import android.content.Intent; 
     import android.os.Bundle; 
     import android.util.Log; 
     import android.view.Menu; 
     import android.view.View; 
     import android.widget.ArrayAdapter; 
     import android.widget.Button; 
     import android.widget.ListView; 
     import android.widget.TextView; 
     import android.widget.Toast; 

     import com.virgosys.demo.commands.SpeedObdCommand; 
     import com.virgosys.demo.commands.engine.EngineRPMObdCommand; 
     import com.virgosys.demo.commands.fuel.FindFuelTypeObdCommand; 

     public class MainActivity extends Bluetooth { 

      @SuppressWarnings("unused") 
      private Button On, Off, Visible, list; 
      private BluetoothAdapter BA; 
      private Set<BluetoothDevice> pairedDevices; 
      @SuppressWarnings("unused") 
      private ListView lv; 
      private BluetoothDevice device; 
      // private UUID uuid; 

      // private BluetoothSocketWrapper bluetoothSocket; 

      private BluetoothSocket socket; 
      private String deviceAddress; 
      String RPM, Speed, FuelType; 
      private TextView uuidTextView, deviceTextView, showRpm, showSpeed, 
        showFuelType, tv_connection_e, tv_connection_f; 

      @Override 
      protected void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
       setContentView(R.layout.activity_main); 
       showRpm = ((TextView) findViewById(R.id.show_rpm)); 
       showSpeed = ((TextView) findViewById(R.id.txt_speed)); 
       showFuelType = ((TextView) findViewById(R.id.txt_fueltype)); 
       uuidTextView = ((TextView) findViewById(R.id.txt_uuid)); 
       deviceTextView = ((TextView) findViewById(R.id.txt_device)); 
       // tv_connection_e = ((TextView) findViewById(R.id.txt_device)); 
       // tv_connection_f = ((TextView) findViewById(R.id.show_error)); 
       On = (Button) findViewById(R.id.button1); 
       Off = (Button) findViewById(R.id.button2); 
       Visible = (Button) findViewById(R.id.button3); 
       list = (Button) findViewById(R.id.button4); 

       lv = (ListView) findViewById(R.id.listView1); 

       BA = BluetoothAdapter.getDefaultAdapter(); 

       try { 
        Process process = Runtime.getRuntime().exec("logcat -d"); 
        BufferedReader bufferedReader = new BufferedReader(
          new InputStreamReader(process.getInputStream())); 

        StringBuilder log = new StringBuilder(); 
        String line = ""; 
        while ((line = bufferedReader.readLine()) != null) { 
         log.append(line); 
        } 
        TextView tv_connection_e = (TextView) findViewById(R.id.show_error); 
        tv_connection_e.setText(log.toString()); 
       } catch (IOException e) { 
       } 
      } 

      public void on(View view) { 
       if (!BA.isEnabled()) { 
        Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
        startActivityForResult(turnOn, 0); 
        Toast.makeText(getApplicationContext(), "Turned on", 
          Toast.LENGTH_LONG).show(); 
       } else { 
        Toast.makeText(getApplicationContext(), "Already on", 
          Toast.LENGTH_LONG).show(); 
       } 
      } 

      @SuppressWarnings("unchecked") 
      public void list(View view) { 
       ArrayList deviceStrs = new ArrayList(); 
       final ArrayList devices = new ArrayList(); 

       BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); 

       pairedDevices = btAdapter.getBondedDevices(); 
       if (pairedDevices.size() > 0) { 
        for (BluetoothDevice device : pairedDevices) { 
         deviceStrs.add(device.getName() + "\n" + device.getAddress()); 
         devices.add(device.getAddress()); 

        } 
       } 
       // show list 
       final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this); 

       ArrayAdapter adapter = new ArrayAdapter(this, 
         android.R.layout.select_dialog_singlechoice, 
         deviceStrs.toArray(new String[deviceStrs.size()])); 

       alertDialog.setSingleChoiceItems(adapter, -1, 
         new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialog, int which) { 
           dialog.dismiss(); 
           int position = ((AlertDialog) dialog).getListView() 
             .getCheckedItemPosition(); 
           deviceAddress = (String) devices.get(position); 

           System.out.println("Device Address-->" + deviceAddress); 

           /* 
           * Intent i = new Intent(MainActivity.this, 
           * SecondActivity.class); i.putExtra("uuid", 
           * "00001101-0000-1000-8000-00805F9B34FB"); 
           * i.putExtra("deviceAddress", deviceAddress); 
           * i.putExtra("RPM", RPM); i.putExtra("Speed", Speed); 
           * startActivity(i); 
           */ 
           try { 
            dothings(); 
           } catch (InterruptedException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
           } 

           // save deviceAddress 
          } 

         }); 

       alertDialog.setTitle("Choose Bluetooth device"); 
       alertDialog.show(); 

      } 

      @SuppressLint("NewApi") 
      protected void dothings() throws InterruptedException { 

       System.out.println("Inside Do things"); 
       System.out.println("Device address in Do things -->" + deviceAddress); 
       device = BA.getRemoteDevice(deviceAddress); 
       // UUID SERIAL_UUID = device.getUuids()[0].getUuid(); 
       // uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 
       System.out.println("Device Name-->" + device.getName()); 
       System.out.println("Device Address-->" + device.getAddress()); 
       System.out.println("Device Bond State-->" + device.getBondState()); 
       System.out.println("Device Type-->" + device.getType()); 
       System.out.println("Device UUIDS-->" + device.getUuids()); 

       ConnectThread t = new ConnectThread(device); 
       t.start(); 

       showRpm.setText(RPM); 
       showSpeed.setText(Speed); 
       showFuelType.setText(FuelType); 
       uuidTextView.setText("00001101-0000-1000-8000-00805F9B34FB"); 
       deviceTextView.setText(deviceAddress); 

      } 

      public void off(View view) { 
       BA.disable(); 
       Toast.makeText(getApplicationContext(), "Turned off", Toast.LENGTH_LONG) 
         .show(); 
      } 

      public void visible(View view) { 
       Intent getVisible = new Intent(
         BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); 
       startActivityForResult(getVisible, 0); 

      } 

      @Override 
      public boolean onCreateOptionsMenu(Menu menu) { 
       // Inflate the menu; this adds items to the action bar if it is present. 
       getMenuInflater().inflate(R.menu.main, menu); 

       return true; 

      } 

      private class ConnectThread extends Thread { 
       private final BluetoothSocket mmSocket; 

       private final UUID WELL_KNOWN_UUID = UUID 
         .fromString("00001101-0000-1000-8000-00805f9b34fb"); 

       private Object e; 

       public ConnectThread(BluetoothDevice device) { 
        // Use a temporary object that is later assigned to mmSocket,because 
        // mmSocket is final 
        BluetoothSocket tmp = null; 

        // Get a BluetoothSocket to connect with the given BluetoothDevice 
        try { 
         tmp = device.createRfcommSocketToServiceRecord(WELL_KNOWN_UUID); 
         // This is the trick 
         Method m = device.getClass().getMethod("createRfcommSocket", 
           new Class[] { int.class }); 
         tmp = (BluetoothSocket) m.invoke(device, 1); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 

        mmSocket = tmp; 
       } 

       public void run() { 

        System.out.println("Trying to connect..."); 
        // Cancel discovery because it will slow down the connection 
        BA.cancelDiscovery(); 

        try { 
         // Connect the device through the socket. This will block 
         // until it succeeds or throws an exception 
         mmSocket.connect(); 
         System.out.println("Connection established"); 
         // tv_connection_e.setText(e.print.stacktrace); 
         ConnectedThread tc = new ConnectedThread(mmSocket); 
         tc.start(); 

        } catch (IOException connectException) { 
         // Unable to connect; close the socket and get out 
         System.out.println("Fail to connect!"); 

         try { 
          mmSocket.close(); 
         } catch (IOException closeException) { 
          System.out.println("Fail to close connection"); 

         } 
         return; 
        } 
       } 

       /** Will cancel an in-progress connection, and close the socket */ 
       public void cancel() { 
        try { 
         mmSocket.close(); 
        } catch (IOException e) { 
        } 
       } 
      } 

      private class ConnectedThread extends Thread { 
       private final BluetoothSocket mmSocket; 
       private final InputStream mmInStream; 
       private final OutputStream mmOutStream; 

       public ConnectedThread(BluetoothSocket socket) { 
        mmSocket = socket; 
        InputStream tmpIn = null; 
        OutputStream tmpOut = null; 
        try { 
         tmpIn = socket.getInputStream(); 
         tmpOut = socket.getOutputStream(); 
        } catch (IOException e) { 
        } 
        System.out.println("Inside the thread"); 
        mmInStream = tmpIn; 
        mmOutStream = tmpOut; 
        try { 
         EngineRPMObdCommand engineRpmCommand = new EngineRPMObdCommand(); 
         SpeedObdCommand speedCommand = new SpeedObdCommand(); 
         FindFuelTypeObdCommand fueltypeCommand = new FindFuelTypeObdCommand(); 
         System.out.println("Inside the try block"); 

         while (!Thread.currentThread().isInterrupted()) { 
          System.out.println("Inside while"); 

          // TODO handle commands result 
          Log.d("Poonam", 
            "RPM: " + engineRpmCommand.getFormattedResult()); 
          Log.d("Poonam", 
            "Speed: " + speedCommand.getFormattedResult()); 
          Log.d("Poonam", 
            "FuelType: " + fueltypeCommand.getFormattedResult()); 

          RPM = engineRpmCommand.getFormattedResult(); 
          Speed = speedCommand.getFormattedResult(); 
          FuelType = fueltypeCommand.getFormattedResult(); 

          try { 
           engineRpmCommand.run(mmInStream, mmOutStream); 
           speedCommand.run(mmInStream, mmOutStream); 
           fueltypeCommand.run(mmInStream, mmOutStream); 
           System.out.println("Commands Processed"); 
          } catch (InterruptedException e) { 
           // TODO Auto-generated catch block 
           e.printStackTrace(); 
          } 
          System.out.println("outside try catch"); 
         } 
        } catch (Exception e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
         System.out.println("inside catch before while"); 
        } 
        // Get the input and output streams, using temp objects because 
        // member streams are final 

       } 

       public void run() { 
        byte[] buffer = new byte[1024]; // buffer store for the stream 
        int bytes; // bytes returned from read() 

        // Keep listening to the InputStream until an exception occurs 
        while (true) { 
        } 

       } 

       /* Call this from the main activity to send data to the remote device */ 
       public void write(byte[] bytes) { 
        try { 
         mmOutStream.write(bytes); 
        } catch (IOException e) { 
        } 
       } 

       /* Call this from the main activity to shutdown the connection */ 
       public void cancel() { 
        try { 
         mmSocket.close(); 
        } catch (IOException e) { 
        } 
       } 
      } 
     } 






    **Bluetooth.java** 

    import java.io.IOException; 
    import java.io.InputStream; 
    import java.io.OutputStream; 
    import java.lang.reflect.InvocationTargetException; 
    import java.lang.reflect.Method; 
    import java.util.ArrayList; 
    import java.util.List; 
    import java.util.UUID; 

    import android.app.Activity; 
    import android.bluetooth.BluetoothAdapter; 
    import android.bluetooth.BluetoothDevice; 
    import android.bluetooth.BluetoothSocket; 
    import android.util.Log; 

    public class Bluetooth extends Activity{ 

     private BluetoothSocketWrapper bluetoothSocket; 
     private BluetoothDevice device; 
     private boolean secure; 
     private BluetoothAdapter adapter; 
     private List<UUID> uuidCandidates; 
     private int candidate; 


     /** 
     * @param device the device 
     * @param secure if connection should be done via a secure socket 
     * @param adapter the Android BT adapter 
     * @param uuidCandidates a list of UUIDs. if null or empty, the Serial PP id is used 
     * @return 
     */ 
     public void BluetoothConnector(BluetoothDevice device, boolean secure, BluetoothAdapter adapter, 
       List<UUID> uuidCandidates) { 
      this.device = device; 
      this.secure = secure; 
      this.adapter = adapter; 
      this.uuidCandidates = uuidCandidates; 

      if (this.uuidCandidates == null || this.uuidCandidates.isEmpty()) { 
       this.uuidCandidates = new ArrayList<UUID>(); 
       this.uuidCandidates.add(UUID.fromString("00001101-0000-1000-8000-00805f9b34fb")); 
      } 
     } 

     public BluetoothSocketWrapper connect() throws IOException { 
      boolean success = false; 
      while (selectSocket()) { 
       adapter.cancelDiscovery(); 

       try { 
        bluetoothSocket.connect(); 
        success = true; 
        break; 
       } catch (IOException e) { 
        //try the fallback 
        try { 
         bluetoothSocket = new FallbackBluetoothSocket(bluetoothSocket.getUnderlyingSocket()); 
         Thread.sleep(500);     
         bluetoothSocket.connect(); 
         success = true; 
         break; 
        } catch (FallbackException e1) { 
         Log.w("BT", "Could not initialize FallbackBluetoothSocket classes.", e); 
        } catch (InterruptedException e1) { 
         Log.w("BT", e1.getMessage(), e1); 
        } catch (IOException e1) { 
         Log.w("BT", "Fallback failed. Cancelling.", e1); 
        } 
       } 
      } 

      if (!success) { 
       throw new IOException("Could not connect to device: "+ device.getAddress()); 
      } 

      return bluetoothSocket; 
     } 

     private boolean selectSocket() throws IOException { 
      if (candidate >= uuidCandidates.size()) { 
       return false; 
      } 

      BluetoothSocket tmp = null; 
      UUID uuid = uuidCandidates.get(candidate++); 

      Log.i("BT", "Attempting to connect to Protocol: "+ uuid); 
      if (secure) { 
       Method m = null; 


       try { 
        m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class}); 
       } catch (NoSuchMethodException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       try { 
        tmp = (BluetoothSocket) m.invoke(device, 1); 
       } catch (IllegalAccessException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (IllegalArgumentException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (InvocationTargetException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 


      } else { 
       tmp = device.createInsecureRfcommSocketToServiceRecord(uuid); 

      } 
      bluetoothSocket = new NativeBluetoothSocket(tmp); 

      return true; 
     } 

     public static interface BluetoothSocketWrapper { 

      InputStream getInputStream() throws IOException; 

      OutputStream getOutputStream() throws IOException; 

      String getRemoteDeviceName(); 

      void connect() throws IOException; 

      String getRemoteDeviceAddress(); 

      void close() throws IOException; 

      BluetoothSocket getUnderlyingSocket(); 

     } 


     public static class NativeBluetoothSocket implements BluetoothSocketWrapper { 

      private BluetoothSocket socket; 

      public NativeBluetoothSocket(BluetoothSocket tmp) { 
       this.socket = tmp; 
      } 

      @Override 
      public InputStream getInputStream() throws IOException { 
       return socket.getInputStream(); 
      } 

      @Override 
      public OutputStream getOutputStream() throws IOException { 
       return socket.getOutputStream(); 
      } 

      @Override 
      public String getRemoteDeviceName() { 
       return socket.getRemoteDevice().getName(); 
      } 

      @Override 
      public void connect() throws IOException { 
       socket.connect(); 
      } 

      @Override 
      public String getRemoteDeviceAddress() { 
       return socket.getRemoteDevice().getAddress(); 
      } 

      @Override 
      public void close() throws IOException { 
       socket.close(); 
      } 

      @Override 
      public BluetoothSocket getUnderlyingSocket() { 
       return socket; 
      } 

     } 

     public class FallbackBluetoothSocket extends NativeBluetoothSocket { 

      private BluetoothSocket fallbackSocket; 

      public FallbackBluetoothSocket(BluetoothSocket tmp) throws FallbackException { 
       super(tmp); 
       try 
       { 
        Class<?> clazz = tmp.getRemoteDevice().getClass(); 
        Class<?>[] paramTypes = new Class<?>[] {Integer.TYPE}; 
        Method m = clazz.getMethod("createRfcommSocket", paramTypes); 
        Object[] params = new Object[] {Integer.valueOf(1)}; 
        fallbackSocket = (BluetoothSocket) m.invoke(tmp.getRemoteDevice(), params); 
       } 
       catch (Exception e) 
       { 
        throw new FallbackException(e); 
       } 
      } 

      @Override 
      public InputStream getInputStream() throws IOException { 
       return fallbackSocket.getInputStream(); 
      } 

      @Override 
      public OutputStream getOutputStream() throws IOException { 
       return fallbackSocket.getOutputStream(); 
      } 


      @Override 
      public void connect() throws IOException { 
       fallbackSocket.connect(); 
      } 


      @Override 
      public void close() throws IOException { 
       fallbackSocket.close(); 
      } 

     } 

     public static class FallbackException extends Exception { 

      /** 
      * 
      */ 
      private static final long serialVersionUID = 1L; 

      public FallbackException(Exception e) { 
       super(e); 
      } 

     } 
    } 





(MainActivity.java:367) 
try { 
         engineRpmCommand.run(mmInStream, mmOutStream); 
         speedCommand.run(mmInStream, mmOutStream); 
         fueltypeCommand.run(mmInStream, mmOutStream); 
         System.out.println("Commands Processed"); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
     367-->    e.printStackTrace(); 
        } 
        System.out.println("outside try catch"); 
       } 
(ObdCommand.java:164) 
protected void readRawData(InputStream in) throws IOException { 
     byte b = 0; 
     StringBuilder res = new StringBuilder(); 

     // read until '>' arrives 
164-->  while ((char) (b = (byte) in.read()) != '>') 
      res.append((char) b); 
+2

在将来发布时,向用户提供与您在堆栈跟踪帖子中提供的行号相匹配的特定行是有帮助的。第164行的OdbCommand.readRawData和MainActivity第367行应该是有用的信息。 – 2015-02-23 11:26:31

+0

@ Jay Snayder现在检查已编辑的帖子。 – 2015-02-23 12:14:44

+1

我没有回答你,因为我无法逐行检查你的代码(常见的是该死的太多了......),你可以使用我的简单测试应用程序https://github.com/Hesamedin/ELM327 – Hesam 2015-02-26 10:14:53

回答

0

你有没有检查过,如果你的字符串生成器/缓冲区包含任何异常被引发时?

我在Nexus 7 2012上遇到了蓝牙问题,我唯一可以建议的就是您在等待数据时使用Thread.sleep(),并使用流中的.available()来确保您不会阅读的内容比可用的内容更多。

你可以睡循环而.available()为零,不等于金额为最后的循环,再假设你有所有的数据,当它稳定。或者,您可以简单地捕捉异常并假定您已经收到了该点的所有数据。