androidbluetoothglobal-variables

Saving a BluetoothDevice object after the application closes


I would like to save the last bluetooth device my application has connected to. I want to not prompt the user at all, if there is a previous bluetooth connection. They will have the option of connecting to a new device, but they do not need to. If they opt to not choose a connection, they will use the application regularly, and then when the bluetooth device is needed, it will connect to the most recent device.

I have tried using the code provided in Tudor Luca's answer below, but the object will not write to the file. I am getting a NotSerializableException. The object which I am trying to save is a BluetoothDevice which is imported with import android.bluetooth.BluetoothDevice.

This is what I have tried to do to make the bluetooth device serializable:

import java.io.Serializable;
import android.bluetooth.BluetoothDevice;

public class SerializableObjects implements Serializable {
    private BluetoothDevice device;

    public SerializableObjects( BluetoothDevice device ) {
        this.device = device;
    }

    public BluetoothDevice getDevice() {
        return this.device;
    }
}

The LogCat Returns this:

12-11 17:46:24.032: W/System.err(24641): java.io.NotSerializableException: android.bluetooth.BluetoothDevice
12-11 17:46:24.032: W/System.err(24641):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1535)
12-11 17:46:24.032: W/System.err(24641):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
12-11 17:46:24.032: W/System.err(24641):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
12-11 17:46:24.032: W/System.err(24641):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
12-11 17:46:24.032: W/System.err(24641):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
12-11 17:46:24.032: W/System.err(24641):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
12-11 17:46:24.032: W/System.err(24641):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
12-11 17:46:24.032: W/System.err(24641):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
12-11 17:46:24.032: W/System.err(24641):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
12-11 17:46:24.032: W/System.err(24641):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
12-11 17:46:24.032: W/System.err(24641):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
12-11 17:46:24.032: W/System.err(24641):    at my.eti.commander.LocalObjects.writeObjectToFile(LocalObjects.java:29)
12-11 17:46:24.032: W/System.err(24641):    at my.eti.commander.MainMenu$1.handleMessage(MainMenu.java:460)
12-11 17:46:24.032: W/System.err(24641):    at android.os.Handler.dispatchMessage(Handler.java:99)
12-11 17:46:24.036: W/System.err(24641):    at android.os.Looper.loop(Looper.java:130)
12-11 17:46:24.036: W/System.err(24641):    at android.app.ActivityThread.main(ActivityThread.java:3687)
12-11 17:46:24.036: W/System.err(24641):    at java.lang.reflect.Method.invokeNative(Native Method)
12-11 17:46:24.036: W/System.err(24641):    at java.lang.reflect.Method.invoke(Method.java:507)
12-11 17:46:24.036: W/System.err(24641):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
12-11 17:46:24.036: W/System.err(24641):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
12-11 17:46:24.036: W/System.err(24641):    at dalvik.system.NativeStart.main(Native Method)

Solution

  • There is no way to directly serialize the BluetoothDevice class. Even if you serialize it, I do not think you will be able to re-use the object after the application closed. Instead, I have a helper class that will store the address of the device. You can save the device address and name and read that information later. You can then perform a discovery/search for bonded devices and obtain corresponding device.

    Here is a helper class I typically use

    public class BluetoothState implements Serializable {
        public static final int STATE_NOT_CONNECTED = 1;
        public static final int STATE_CONNECTED = 1;
    
        public static final String filename = "btState.pref";
        
        public static int connectionState = STATE_NOT_CONNECTED;
        public static String deviceAddress = "00:00:00:00:00:00";
        public static String deviceName = "";
            
        public static void setConnectionState(boolean connected,BluetoothDevice device) {
            if (connected)
                connectionState = STATE_CONNECTED;
            else
                connectionState = STATE_NOT_CONNECTED;
            
            if (device != null) {
                deviceAddress = device.getAddress();
                deviceName = device.getName();
            }
            
        }
        
        public static void saveConnectionState(Context cxt) throws IOException {        
            FileOutputStream fos = cxt.openFileOutput(filename, Context.MODE_PRIVATE);
            ObjectOutputStream oos = new ObjectOutputStream(fos);       
            oos.writeInt(connectionState);
            oos.writeUTF(deviceAddress);
            oos.writeUTF(deviceName);
        }
        
        public static void loadConnectionState(Context cxt) throws IOException {        
            FileInputStream fis = cxt.openFileInput(filename);
            ObjectInputStream ois = new ObjectInputStream(fis);     
            connectionState = ois.readInt();
            deviceAddress = ois.readUTF();
            deviceName = ois.readUTF();
        }
        
        public static BluetoothDevice getDevice() {
            BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
            if (!btAdapter.isEnabled())
                btAdapter.enable();
            
            Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();
            
            for (BluetoothDevice d : pairedDevices)
                if (d.getAddress().equalsIgnoreCase(deviceAddress))
                    return d;
            
            return null;        
        }
    }