9

Я делаю приложение, которое использует соединение Bluetooth. Я звоню соединение Bluetooth в onCreate() и закрыть его в onDestroy() из MainActivity:Как я могу закрыть BluetoothSocket на экране вращения на Android?

// Bluetooth 
private Bluetooth bt; 
private boolean registered = false; 

@Override 
protected void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    bt = new Bluetooth(this); 
    bt.enableBluetooth(); 
    bt.setCommunicationCallback(this); 
    bt.connectToName(bt.getBluetoothDevice(this)); 
    IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); 
    registerReceiver(mReceiver, filter); 
    registered = true; 
} 

@Override  
public void onDestroy() { 
    super.onDestroy(); 
    if(registered) { 
     unregisterReceiver(mReceiver); 
     registered=false; 
    } 
    bt.removeCommunicationCallback(); 
    bt.disconnect(); 
    if (handler != null && runnable != null) { 
     handler.removeCallbacks(runnable); 
    } 
} 

Приложение также поддерживает альбомные и портретные режимы (с использованием двух различных макетов). Когда экран повернут, MainActivity вызывает функции onCreate() и onDestroy, из-за различной компоновки. По этой причине, я получил следующее сообщение об ошибке:

@@@ ABORTING: INVALID HEAP ADDRESS IN dlfree addr=0x5a71aa38 
A/libc: Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 1051 (le.bluetoothled) 

Как я нашел в Invalid heap address and fatal signal 11, он был из close() метода BluetoothSocket в. Во-первых, я думаю, что мы не нуждаемся в близком bluetooth, когда мы поворачиваем экран, следовательно, я пытался использовать метод для detect rotation event телефона и игнорировать закрытие, когда происходит поворот, однако он не работает. Следовательно, мне кажется, нам нужно закрыть bluetooth при повороте экрана, но я получил вышеуказанную ошибку. Я понятия не имею, как я могу это решить, не могли бы вы помочь мне решить эту проблему? Я использую this Bluetooth LIB с disconnect() следующим образом:

public void disconnect() { 
     try { 
      socket.close(); 
     } catch (IOException e) { 
      if(communicationCallback!=null) 
       communicationCallback.onError(e.getMessage()); 
     } 
    } 

В мое текущее решение использует сон. Я добавил Thread.sleep (1000) перед ближайшей розеткой. Это работает. Но я думаю, что это не очень хорошее решение.

+0

Какой у вас класс 'Bluetooth'? Это «Сервис»? – Bryan

+0

Нет. Это просто нормальный класс, как https://github.com/omaflak/Bluetooth-Library/blob/master/bluetooth/src/main/java/me/aflak/bluetooth/Bluetooth.java – Jame

+0

Что происходит, когда один из потоки, созданные для подключения Bluetooth, все еще работают, и вы поворачиваете устройство? Они ссылаются на старую деятельность. Вы пытаетесь очистить ссылку на обратный вызов активности, но также проверяете другой поток, если он равен нулю. Это небезопасно. – masp

ответ

0

В вашей деятельности вы можете добавить Fragment и позвонить setRetainInstnce, чтобы этот фрагмент обрабатывал изменения ориентации. Переместите свою логику с помощью bluetooth в Fragment. Посмотрите, как реализовать это here и here.

+0

Это не хорошо. На самом деле, я пытаюсь решить выше ошибки – Jame

0

попробуйте этот код

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 
    //disconnect your bluetooth 
} 
+0

Это не хорошо. На самом деле, я пытаюсь решить вышеописанную ошибку – Jame

0

Добавьте этот тег в файле манифеста в уважаемой теге деятельности. После добавления этого тега для проявления в уважаемой деятельности активность может сохранять свое состояние и при изменении ориентации onDestroy() не вызывается и гнездо bluetooth не закрывается.

андроида: configChanges = "keyboardHidden | ориентация | Размер экрана"

1

Вы не должны использовать Bluetooth - связанные вещи внутри деятельности (см SOLID) принципы. Активность - это только пользовательский интерфейс. Вы должны создать отдельную службу, которая будет работать независимо от пользовательского интерфейса в фоновом режиме и управлять всеми действиями, связанными с Bluetooth. Из привязки Activity к этой службе в методе onResume() и отвяжите ее в методе onPause(). Вы можете получить интерфейс управления bt из ServiceConnection, переданный службой во время привязки. В Google есть отличный пример Bluetooth - https://github.com/googlesamples/android-BluetoothChat. Единственный недостаток - он использует обработчик для передачи сообщений. Я немного изменил его - теперь есть еще один поток, получающий все сообщения состояния и вызывающий обратный вызов. Не стесняйтесь использовать этот код: https://github.com/AlexShutov/LEDLights

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