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 中。
我正在尝试从 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 中。