Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I close BluetoothSocket's on screen rotation in Android?

I am making an application which uses bluetooth connection. I am calling bluetooth connection in onCreate() and closing it in onDestroy() of MainActivity:

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

The app also supports LANDSCAPE and PORTRAIT modes (using two different layouts). When screen is rotated, the MainActivity calls the onCreate() and onDestroy functions, due to different layout. For that reason, I got the following error:

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

As I found in the Invalid heap address and fatal signal 11, it was from BluetoothSocket's close() method. First, I think that we don't need close bluetooth when we rotate the screen, hence, I tried to use the method to detect rotation event of phone and ignore closing when the rotation happen, however, it does not work. Hence, I think we may need to close bluetooth when screen rotation, but I got the above error. I have no idea how can I solve this, could you help me to solve that issue? I am using this Bluetooth lib with disconnect() as follows:

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

As my current solution is using sleep. I added Thread.sleep (1000) before close socket. It is working. But I think it is not a very good solution.

like image 367
Jame Avatar asked Sep 18 '16 14:09

Jame


1 Answers

You MUST NOT use Bluetooth - related stuff inside Activity (see SOLID) principles. Activity is just a UI. You should create separate Service, which will be running independently from UI in background and managing all Bluetooth - related action. From your Activity bind to that Service in onResume() method and unbind from it in onPause() method. You can get bt- control interface from ServiceConnection, passed by Service during binding. There is a great Bluetooth example from Google - https://github.com/googlesamples/android-BluetoothChat . The only drawback - it uses Handler for passing messages. I've modified it slightely - now there is another thread, receiving all state messages and calling callback. Feel free to use this code: https://github.com/AlexShutov/LEDLights

like image 125
Alex Shutov Avatar answered Oct 02 '22 08:10

Alex Shutov