Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Holding android bluetooth connection through multiple activities

I am building an Android app that communicates with an Arduino board via bluetooth, I have the bluetooth code in a class of it's own called BlueComms. To connect to the device I use the following methord:

public boolean connectDevice() {
    CheckBt();
    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
    Log.d(TAG, "Connecting to ... " + device);
    mBluetoothAdapter.cancelDiscovery();
    try {
        btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
        btSocket.connect();
        outStream = btSocket.getOutputStream();
        Log.d(TAG, "Connection made.");
        return true;

    } catch (IOException e) {
        try {
            btSocket.close();
        } catch (IOException e2) {
            Log.d(TAG, "Unable to end the connection");
            return false;
        }
        Log.d(TAG, "Socket creation failed");
    }
    return false;

}
    private void CheckBt() {
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    if (!mBluetoothAdapter.isEnabled()) {
        System.out.println("Bt dsbld");
    }

    if (mBluetoothAdapter == null) {
        System.out.println("Bt null");
    }
}

This connects fine but as soon as I leave the activity I connected through it drops the connection, showing this through LogCat,

 D/dalvikvm(21623): GC_CONCURRENT freed 103K, 10% free 2776K/3056K, paused 5ms+2ms, total 35ms

I can no longer connect to the device, but if I call killBt() it throws a fatal error and if I try to send data I get a 'Socket creation failed' error. My send message code is as follows:

public void sendData(String data, int recvAct) {
    try {
        outStream = btSocket.getOutputStream();
    } catch (IOException e) {
        Log.d(TAG, "Bug BEFORE Sending stuff", e);
    }

    String message = data;
    byte[] msgBuffer = message.getBytes();

    try {
        outStream.write(msgBuffer);
    } catch (IOException e) {
        Log.d(TAG, "Bug while sending stuff", e);
    }
}

How should I go about preventing the connection from being paused by the activity I connect with when I switch a different activity, I am switching activities with this code:

Intent myIntent = new Intent(v.getContext(), Timelapse.class);
    startActivityForResult(myIntent, 0);

Many Thanks, Rozz

like image 219
Rory Crispin Avatar asked Jul 10 '13 10:07

Rory Crispin


People also ask

Can Android Bluetooth connect to two things at the same time?

Android users need to go to Bluetooth Settings and pair either Bluetooth headphones or speakers one by one. Once connected, tap the three-dot icon on the right and click on Advanced Settings. Toggle on the 'dual audio' option if not already turned on. This should enable users to connect to two devices at once.

How many Bluetooth devices can Android connect to at once?

Can Android Connect to Multiple Bluetooth Devices? Most Android devices can connect to two or five Bluetooth devices simultaneously, while others support up to seven devices. The number of supported connections depends on the Bluetooth module your device is equipped with.


1 Answers

Where did you store the instance of your BlueComms class? If you put it in the first activity then the class instance would have been killed when that activity was destroyed as you left it and moved to the next activity (NB activities also get destroyed on screen rotation)

So you need to find a way to keep the instance of BlueComms class alive for as long as you need it. You could pass it between activities via public properties and store it in onRetainNonConfigurationInstance() during rotations.

An easier trick is to create a class that extends Application use it as the application delegate for your app and add public property to it to store the instance of BlueComms class within it. That way the instance of BlueComms class would be alive for the lifetime of you app.

Extend Application

import android.app.Application;

public class cBaseApplication extends Application {

    public BlueComms myBlueComms;

    @Override
    public void onCreate() 
    {
        super.onCreate();
        myBlueComms = new BlueComms();
    }

}

Make your class the application delegate in the app manifest

<application
    android:name="your.app.namespace.cBaseApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name" >

Access the base app from any of your Activities like this

((cBaseApplication)this.getApplicationContext()).myBlueComms.SomeMethod();
like image 122
Martin Belcher - AtWrk Avatar answered Sep 20 '22 13:09

Martin Belcher - AtWrk