I wrote an MP3 player for my phone. I wanted it to automatically start playing when certain bluetooth devices connect - like in my car, for instance. And stop playing when they disconnect. It works on my old Samsung Galaxy S9 (Android ver. 10), but not in my new Samsung Galaxy S24 (Android ver. 14). I assume something changed in the operating system between version 10 and version 14. I can't find anything in the android documents about this.
The manifest looks like this:
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH" />
...
<application
...
tools:targetApi="31">
...
<activity
android:name=".MainActivity"
android:exported="true"
In MainActivity, it asks for bluetooth permission and gets it:
ActivityCompat.requestPermissions(getMainActivity(),
new String[]{Manifest.permission.BLUETOOTH},
MY_BLUETOOTH_PERMISSION);
The code in MainActivity looks like this:
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
checkPermission(android.Manifest.permission.BLUETOOTH_CONNECT,BLUETOOTH_PERMISSION);
Toast.makeText(mainActivity, "Bluetooth device " + device.getName(), Toast.LENGTH_LONG).show();
addBluetoothDevice(device);
} else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
bluetoothConnected = addBluetoothDevice(device);
if (bluetoothConnected != null && bluetoothConnected.isPlayOnConnect()) {
mediaService.resume();
}
Toast.makeText(mainActivity, "Bluetooth device connected " + device.getName(), Toast.LENGTH_LONG).show();
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
addBluetoothDevice(device);
Toast.makeText(mainActivity, "Bluetooth device discovery finished " + device.getName(), Toast.LENGTH_LONG).show();
} else if (BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) {
addBluetoothDevice(device);
Toast.makeText(mainActivity, "Bluetooth device disconnect requested " + device.getName(), Toast.LENGTH_LONG).show();
} else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
bluetoothDisconnected = addBluetoothDevice(device);
if (bluetoothDisconnected != null && bluetoothDisconnected.isPauseOnDisconnect()) {
mediaService.pause();
}
Toast.makeText(mainActivity, "Bluetooth device disconnected " + device.getName(), Toast.LENGTH_LONG).show();
} else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_OFF:
System.out.println("STATE_OFF");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
break;
case BluetoothAdapter.STATE_ON:
break;
case BluetoothAdapter.STATE_TURNING_ON:
break;
}
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);type here
int receiverFlags = 0;
this.registerReceiver(mReceiver, filter, receiverFlags);
I tried also listening for ACTION_STATE_CHANGED (see above code), although I don't need that. I do receive broadcasts for ACTION_STATE_CHANGED on the S24 when I turn bluetooth on and off, however. What I need are ACTION_ACL_CONNECTED and ACTION_ACL_DISCONNECTED, which I don't get when the S24 phone connects to a bluetooth speaker. Again, it does work on my S9 phone. Clearly something changed between Android version 10 and 14. Anyone know what it is?
You need to request the BLUETOOTH_CONNECT
permission, both in the manifest and at runtime, in order to receive those broadcasts, per the documentation.
Clearly something changed between Android version 10 and 14.
The permission requirement was added in Android 11 for apps targeting Android 11 or higher.