java.io.IOException:bt socket关闭,读取返回:-1

时间:2015-02-23 11:09:04

标签: java android eclipse obd-ii

当我正在研究OBD Reader演示时。通过我的应用程序,我正在尝试连接obd阅读器设备,我的应用程序安装在Nexus 7.OBD阅读器设备正在连接到谷歌播放中可用的其他应用程序,但如果我是连接我的应用程序它得到错误java.io.IOException:bt socket关闭,读取返回:-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 个答案:

答案 0 :(得分:0)

您是否检查过字符串构建器/缓冲区在抛出异常时是否包含任何内容?

我在Nexus 7 2012上遇到蓝牙故障,我唯一可以建议你在等待数据时使用Thread.sleep()并从流中使用.available()来确保你不要阅读的内容超过可用内容。

你可以睡眠循环,而.available()为零并且不等于最后一个循环的数量,然后假设你在稳定时拥有所有数据。或者,您可以简单地捕获异常,并假设您已经收到了该点的所有数据。

答案 1 :(得分:0)

我认为这是read()方法中的错误。来自@Keilaron的回答..我尝试了这个,这可行:

    while (inputStream.available() == 0);
    val available = inputStream.available()
    val bytes = ByteArray(available)
    inputStream.read(bytes, 0, available)
    val text = String(bytes)