如果连接断开,Android将重新连接到蓝牙设备

萨迪斯·文古斯特

我的手机正在连接到蓝牙设备,并且可以正常工作。它连接并保持连接。我可以更改方向,在后台运行我的应用程序,可以关闭应用程序,当我重新打开它时,它将自动连接。但是从应用程序用户那里,我得到一些报告,指出一段时间后连接丢失(未检测到任何模式)。我试图重新创建它,但是没有运气。因此,为避免此问题,如果连接断开,我想实现与先前选择的设备的自动重新连接。

我做了一些研究,可以通过实现一个可以检测到以下内容的广播接收器来做到这一点: android.bluetooth.device.action.ACL_DISCONNECTED

我的问题是:

  • 我已经有一个在设备启动时触发的广播接收器。我应该扩展此接收器以添加ACL_DISCONNECTED还是添加单独的接收器?
  • 我的BluetoothService已在我的mainactivity上初始化,但是我需要从该意图重新连接。怎么做。

感谢您的回答。

蓝牙服务代码:

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);
        }
    }
}

}

萨迪斯·文古斯特

我分两个阶段解决了这个问题。首先,我创建了一个新的广播接收器,因为我现有的接收器用于ACTION_BOOT_COMPLETED,并且必须在android清单中声明。我创建的一个必须动态,因为我需要一个MainActivity实例:

 if (bluetoothLostReceiver == null)
        {
            bluetoothLostReceiver = new BluetoothLostReceiver();
            bluetoothLostReceiver.setMainActivity(this);
            IntentFilter filter = new IntentFilter("android.bluetooth.device.action.ACL_DISCONNECTED");
            registerReceiver(bluetoothLostReceiver, filter);
        }

在接收者中,我尝试了与打印机的新连接。我添加了一个附加的paramenter tryBluetoothReconnect,这样,如果我想关闭连接,则不会尝试重新连接。

public class BluetoothLostReceiver extends BroadcastReceiver {

    MainActivity main = null;

    public void setMainActivity(MainActivity main)
    {
        this.main = main;
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        if(BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(intent.getAction()) && Global.tryBluetoothReconnect)
        {
            if(Global.PosPrinterDeviceName != null && !Global.PosPrinterDeviceName.equals(""))
                main.connectPrinter(Global.PosPrinterDeviceName);
        }else
        {
            Global.tryBluetoothReconnect = true;
        }
    }
}

我还升级了我的蓝牙服务,以便如果连接不成功(connectionFailed()方法),它将再尝试4次:

    if(tryCount >= 4)
    {
        tryCount = 0;

        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();
    }
    else
    {
        tryCount++;
        connect(bluetoothDevice);
    }

希望这对遇到同样问题的人有所帮助。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章