4

Мой телефон подключается к устройству Bluetooth и работает нормально. Он подключается и соединение выполняется. Я могу изменить ориентацию, иметь приложение в фоновом режиме, я могу закрыть приложение, и когда я верну его, он автоматически подключится. Но от пользователей приложений я получаю сообщения о том, что соединение теряется через некоторое время (не обнаружено никакого шаблона). Я попытался воссоздать это, но не повезло. Поэтому, чтобы избежать этой проблемы, я хочу реализовать автоматическое повторное подключение к ранее выбранному устройству, если соединение потеряно.Android подключается к устройству Bluetooth, если соединение потеряно

Я сделал некоторые Reasearch, что это может быть сделано путем осуществления широковещательного приемника, который будет обнаружить: android.bluetooth.device.action.ACL_DISCONNECTED

Что мои вопросы:

  • У меня уже есть вещательный приемник, который срабатывает на устройстве Bootup. Должен ли я распространять этот приемник, чтобы добавить ACL_DISCONNECTED или добавить отдельный приемник?
  • My BluetoothService инициализирован в моей основной деятельности, но мне нужно будет снова подключиться от намерения. Как это сделать.

Спасибо за ваш ответ.

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

}

ответ

5

Я решил это в 2 этапа. Сначала я создал новый приемник трансляции, потому что мой существующий был для 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); 
     } 

И в моем приемнике я попробовал новое подключение к принтеру. Я добавил дополнительный параграф 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; 
     } 
    } 
} 

Я также модернизировал свою службу Bluetooth, так что, если соединение не было успешным (метод 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); 
    } 

Надеются, что это помогает кто-нибудь с такой же проблемой.

+0

Я хотел бы поблагодарить вас за ваш код. Это очень полезно для меня. Если это возможно, вы можете отправить свой проект мне по электронной почте [email protected] Мне это действительно нужно – Jame

+1

Я не могу отправить вам свой проект, но я отправил вам несколько самых важных классов. Надеюсь, поможет. –

+0

Спасибо. Мой самый важный класс - это автоматическое соединение Bluetooth. – Jame

 Смежные вопросы

  • Нет связанных вопросов^_^