我的手机连接了一个蓝牙设备,一切正常。它可以连接并且连接保持稳定。我可以改变方向,在后台运行应用程序,关闭应用程序,重新打开时它会自动连接。但是,我收到了一些来自应用程序用户的报告,说连接在一段时间后断开了(没有发现任何规律)。我尝试重现这个问题,但没有成功。因此,为了避免这个问题,我想实现一个如果连接断开就自动重新连接到上次选择的设备。
我进行了一些研究,发现可以通过实现一个广播接收器来检测:android.bluetooth.device.action.ACL_DISCONNECTED
我的问题如下:
1. 我已经有一个在设备启动时触发的广播接收器。我应该扩展这个接收器以添加ACL_DISCONNECTED,还是应该添加一个单独的接收器?
2. 我的BluetoothService是在我的MainActivity中初始化的,但我需要从Intent重新连接。如何做到这一点。
谢谢您的回答。
BluetoothServis代码:
我进行了一些研究,发现可以通过实现一个广播接收器来检测:android.bluetooth.device.action.ACL_DISCONNECTED
我的问题如下:
1. 我已经有一个在设备启动时触发的广播接收器。我应该扩展这个接收器以添加ACL_DISCONNECTED,还是应该添加一个单独的接收器?
2. 我的BluetoothService是在我的MainActivity中初始化的,但我需要从Intent重新连接。如何做到这一点。
谢谢您的回答。
BluetoothServis代码:
public class BluetoothService
{
// Debugging
private static final String TAG = "BluetoothService";
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Member fields
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private final Context mContext;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_CONNECTING = 1; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 2; // now connected to a remote device
public BluetoothService(Context context, Handler handler)
{
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
mContext = context;
}
private synchronized void setState(int state)
{
mState = state;
mHandler.obtainMessage(MainActivity.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
public synchronized int getState()
{
return mState;
}
public synchronized void start()
{
if (mConnectThread != null)
{
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
}
public synchronized void connect(BluetoothDevice device)
{
if (mState == STATE_CONNECTING)
{
if (mConnectThread != null)
{
mConnectThread.cancel();
mConnectThread = null;
}
}
if (mConnectedThread != null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device, final String socketType)
{
if (mConnectThread != null)
{
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
mConnectedThread = new ConnectedThread(socket, socketType);
mConnectedThread.start();
Message msg = mHandler.obtainMessage(MainActivity.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(MainActivity.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
public synchronized void stop()
{
if (mConnectThread != null)
{
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
setState(STATE_NONE);
}
public void write(byte[] out)
{
ConnectedThread r;
synchronized (this)
{
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
r.write(out);
}
private void connectionFailed()
{
Message msg = mHandler.obtainMessage(MainActivity.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(MainActivity.TOAST, mContext.getResources().getString(R.string.cant_connect));
msg.setData(bundle);
mHandler.sendMessage(msg);
BluetoothService.this.start();
}
private class ConnectThread extends Thread
{
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
private String mSocketType;
public ConnectThread(BluetoothDevice device)
{
mmDevice = device;
BluetoothSocket tmp = null;
mSocketType = "Secure";
// another option createInsecureRfcommSocketToServiceRecord
try
{
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
}
catch (IOException e)
{
Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
}
/*
Method m = null;
try {
m = mmDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmp = (BluetoothSocket) m.invoke(mmDevice, 1);
} catch (Exception e) {
e.printStackTrace();
}*/
mmSocket = tmp;
}
public void run()
{
Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
setName("ConnectThread" + mSocketType);
mAdapter.cancelDiscovery();
try
{
mmSocket.connect();
Log.i(TAG, "ConnectThread running");
}
catch (IOException e)
{
try
{
mmSocket.close();
}
catch (IOException e2)
{
Log.e(TAG, "unable to close() " + mSocketType + " socket during connection failure", e2);
}
connectionFailed();
return;
}
synchronized (BluetoothService.this)
{
mConnectThread = null;
}
connected(mmSocket, mmDevice, mSocketType);
}
public void cancel()
{
try
{
mmSocket.close();
}
catch (IOException e)
{
Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);
}
}
}
private class ConnectedThread extends Thread
{
private final BluetoothSocket mmSocket;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType)
{
mmSocket = socket;
OutputStream tmpOut = null;
try
{
tmpOut = socket.getOutputStream();
}
catch (IOException e)
{
Log.e(TAG, "temp sockets not created", e);
}
mmOutStream = tmpOut;
}
public void run()
{
}
public void write(byte[] buffer)
{
try
{
mmOutStream.write(buffer);
try
{
sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
catch (IOException e)
{
Log.e(TAG, "Exception during write", e);
}
}
public void cancel()
{
try
{
mmSocket.close();
}
catch (IOException e)
{
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}