Android 蓝牙连接抛出读取失败,套接字可能关闭或超时,读取 ret android

Android bluetooth connection throwing read failed, socket might closed or timeout, read ret android

我正在尝试从 android 与使用 HC-05 的微处理器控制的设备进行通信,我已经尝试了所有可能的解决方案,但是 btSocket.connect() 正在抛出

read failed, socket might closed or timeout, read ret android

相关代码片段如下:-

/**
 * Sends the data Over BlueTooth
 * @param data 
 *              bytes which is to be send to the bibox.
 * 
 * */

private void sendDataToBlueTooth(byte[] data){
    SharedPreferences pref  =   PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    String mMacChecking     =   pref.getString("BL", "bl");

    if (!mMacChecking.equals("bl")) {

//            Intent in     =   new Intent(getApplicationContext(), DataSendReceive.class);
//            in.putExtra("isBtRemoteData", true);
//            in.putExtra("bData", data);
//            startActivity(in);

         final SharedPreferences pre    =   PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
         this.mDeviceMACAddress         =   pre.getString("BL", "");
         this.mSendArray                =   data;                       


         this.mBluetoothAdapter         =   BluetoothAdapter.getDefaultAdapter();
         if (this.mBluetoothAdapter == null) {
             Toast.makeText(this, R.string.no_bt_device, Toast.LENGTH_LONG).show();
             this.finish();
             return;
         }

         this.connectTOdevice();

         this.mHandler                  =   new Handler() {
             @SuppressLint("ShowToast")
             @Override
             public void handleMessage(final android.os.Message msg) {

                 if (msg.what == 1) {
                     mConnectStatus = true;

                     for (int i = 0; i < mSendArray.length; i++) {
                         write(mSendArray[i]);
                     }


                     String str = Arrays.toString(mSendArray);                    

                     Log.d("", str);

                    //Added an alert dialog to show the  data..
                    // To activate the alert, put the below 3 lines inside the on click of the OK button...

                      onBackPressed();

                     try {
                         Thread.sleep(1000);
                     } catch (final InterruptedException e) {
                         e.printStackTrace();
                     }

                 } else if (msg.what == 2) {
                     // Set button to display current status
                     // connectStat = true;
                     final byte[] readBuf = (byte[]) msg.obj;
                     System.out.println("InHandler  - ");
                     String receivedString = "";
                     for (final byte b : readBuf) {
                         // `byte` to `Byte`
                         final int temp             =   b;
                         final String tempString =  String.valueOf(temp);
                         receivedString             =   receivedString.concat("," + tempString);
                     }
                     Log.d("received string", receivedString);

                     for (final byte element : readBuf) {
                         System.out.print(element + ",");
                     }
                     // System.out.println("" + readBuf);
                 } else if (mBluetoothAdapter.isEnabled()) {
                     final Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                     startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
                 } else {
                     // Connection failed
                     mFailToast.show();
                     /* Intent scan = new Intent(getApplicationContext(), BluetoothDeviceDiscover.class); */
                     finish();
                     // startActivity(scan);
                 }
             }
         };

         mFailToast                     =   Toast.makeText(this, "Failed to connect please on   " + this.mDeviceMACAddress + "   or scan for new device", Toast.LENGTH_SHORT);

         this.mBluetoothAdapter         =   BluetoothAdapter.getDefaultAdapter();
         if (this.mBluetoothAdapter == null) {
             Toast.makeText(this, R.string.no_bt_device, Toast.LENGTH_LONG).show();
             this.finish();
             return;
         }

         this.connectTOdevice();

    }
}

 @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            if (this.mBtSocket != null) {
                this.mBtSocket.close();
            }
        } catch (final IOException e2) {}
    }

public void write(final byte arr2) {

    if (this.mConnectStatus == true) if (this.mOutStream != null) {
        try {
            this.mOutStream.write(arr2);
        } catch (final IOException e) {
            showToast(getString(R.string.dataNotSendMessage), false);
        }
    } else {
            showToast(getString(R.string.switchOnBlueToothDevice), false);
    }
 }

  public void connectTOdevice() {
        this.mConnectThread     = new ConnectThread(this.mDeviceMACAddress);
        this.mConnectThread.start();
    }

  private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
        boolean isUnpairToastToBeDisplayed = true;
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            String DEVICE_PIN = getString(R.string.device_pin);

            final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);


            if (action.equals("android.bluetooth.device.action.BOND_STATE_CHANGED")) {
                byte[] pin;
                try {
                    pin = (byte[]) BluetoothDevice.class.getMethod("convertPinToBytes", String.class).invoke(BluetoothDevice.class, DEVICE_PIN);
                    BluetoothDevice.class.getMethod("setPin", byte[].class).invoke(device, pin); 
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }

            if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
                 final int state        = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
                 final int prevState    = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);

                 if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {

                     //Continue work here....

                     //If the number of paired devices greater than 3, unpair everything except the current one...
                     //Causing problem in lenovo tablet...
                     //Problem :- Tablet hang for more than 4 paired devices...
                     BluetoothAdapter btAdapter =   BluetoothAdapter.getDefaultAdapter();
                     Set<BluetoothDevice> mPairedDevices;
                     mPairedDevices = btAdapter.getBondedDevices();

                     final SharedPreferences pref   = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());                
                     String deviceAddress           = pref.getString("BL", "NoDevice");

                    if (mPairedDevices.size() > MAX_ALLOWED_PAIRED_DEVICES) {
                        // findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
                        for (final BluetoothDevice deviceForLoop : mPairedDevices) {
                            //if the device for loop doesn't match the latest saved address...
                            //unpair the device...
                            if(!deviceAddress.equals(deviceForLoop.getAddress())){
                                isUnpairToastToBeDisplayed  =   false;
                                unpairDevice(deviceForLoop);
                                isUnpairToastToBeDisplayed  =   true;
                            }
                        }
                    }

                     showToast(getString(R.string.pairedToastMessage),false);

                 } else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED){
                     if(!isUnpairToastToBeDisplayed)
                         showToast(getString(R.string.unpairedToastMessage),false);
                 }
            }


            try {
                device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
                Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
                sendBroadcast(i);

            } catch (IllegalArgumentException e1) {
                e1.printStackTrace();
            } catch (IllegalAccessException e1) {
                e1.printStackTrace();
            } catch (InvocationTargetException e1) {
                e1.printStackTrace();
            } catch (NoSuchMethodException e1) {
                e1.printStackTrace();
            }
        }
    };

    private void unpairDevice(final BluetoothDevice device) {
        try {
            final Method m = device.getClass().getMethod("removeBond", (Class[]) null);
            m.invoke(device, (Object[]) null);
        } catch (final Exception e) {
            // Log.e(TAG, e.getMessage());
        }
    }


  public class ConnectThread extends Thread {
        private final String address;
        private boolean connectionStatus;

        ConnectThread(final String MACaddress) {
            this.address = MACaddress;
            this.connectionStatus = false;
        }

        @Override
        public void run() {

            mBluetoothAdapter.cancelDiscovery();

            try {
                final BluetoothDevice device        =   mBluetoothAdapter.getRemoteDevice(this.address);

                IntentFilter intent                 =   new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
                registerReceiver(mPairReceiver, intent);
                try {

                    SPP_UUID                    =       device.getUuids()[0].getUuid();
                    BluetoothSocket tmp         =   device.createInsecureRfcommSocketToServiceRecord(SPP_UUID);

                    Class<?> clazz              =   tmp.getRemoteDevice().getClass();
                    Class<?>[] paramTypes       =   new Class<?>[] {Integer.TYPE};

                    Method m                    =   clazz.getMethod("createRfcommSocket", paramTypes);
                    Object[] params             =   new Object[] {Integer.valueOf(1)};

                    mBtSocket                   =  (BluetoothSocket) m.invoke(tmp.getRemoteDevice(), params);

                } catch (final IOException e) {
                    this.connectionStatus           =   false;
                } catch (Exception e) {

                }
            } catch (final IllegalArgumentException e) {
                this.connectionStatus = false;
            }

            try {
                mBtSocket.connect();
                this.connectionStatus = true;
            } catch (final IOException e1) {
                try {
                 mBtSocket.close();
                 Log.d("check", "check");
                } catch (final IOException e2) {}
            }
            // Create a data stream so we can talk to server.
            try {
                mOutStream =    mBtSocket.getOutputStream();

            } catch (final IOException e2) {
                this.connectionStatus = false;
            }
            // Send final result
            if (this.connectionStatus) {
                mHandler.sendEmptyMessage(1);
            } else {
               mHandler.sendEmptyMessage(0);
            }
        }
    }
}

我在以下问题中找到了答案:-

IOException: read failed, socket might closed - Bluetooth on Android 4.3

实际上我不得不只在回退时使用反射,即在连接失败时在 catch 中。