Android Broadcast Receiver Bluetooth Events Catching

Android Broadcast Receiver bluetooth events catching

In order to catch Bluetooth state changes (STATE_OFF, STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF), do this:

First, add Bluetooth permission to your AndroidManifest file:

<uses-permission android:name="android.permission.BLUETOOTH" />

Create a BroadcastReceiver in your Activity or Service:

    private final BroadcastReceiver mBroadcastReceiver1 = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();

if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
switch(state) {
case BluetoothAdapter.STATE_OFF:
..
break;
case BluetoothAdapter.STATE_TURNING_OFF:
..
break;
case BluetoothAdapter.STATE_ON:
..
break;
case BluetoothAdapter.STATE_TURNING_ON:
..
break;
}

}
}
};

Create an IntentFilter and register it with BroadcastReceiver in your Activity/Service's onCreate() method:

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

IntentFilter filter1 = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mBroadcastReceiver1, filter1);

...
}

Unregister BroadcastReceiver in your onDestroy() method:

@Override
protected void onDestroy() {
super.onDestroy();

unregisterReceiver(mBroadcastReceiver1);
}

In order to catch changes of discoverability of device (SCAN_MODE_NONE, SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE), create another BroadcastReceiver and register/unregister to your Activity as I mentioned above. Only difference between those BroadcastReceivers is the first one uses BluetoothAdapter.EXTRA_STATE and the other one uses BluetoothAdapter.EXTRA_SCAN_MODE. Here is the example code for BroadcastReceiver to catch discoverability changes:

Create an IntentFilter and register it in onCreate() method:

IntentFilter filter2 = new IntentFilter();
filter2.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter2.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filter2.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
registerReceiver(mBroadcastReceiver2, filter2);

Create the BroadcastReciver in Activity/Service to catch discoverability changes:

    private final BroadcastReceiver mBroadcastReceiver2 = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();

if(action.equals(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)) {

int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.ERROR);

switch(mode){
case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
..
break;
case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
..
break;
case BluetoothAdapter.SCAN_MODE_NONE:
..
break;
}
}
}
};

And lastly unregister BroadcastReciver in onDestroy():

unregisterReceiver(mBroadcastReceiver2);

Note that, you don't need to add any <intent-filter> or <receiver> to your AndroidManifest file, except you need to add Bluetooth permission of course.

If you want to catch (ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECTED, ACTION_ACL_DISCONNECT_REQUESTED), now you need to add an <intent-filter> to your AndroidManifest file:

<intent-filter>
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
</intent-filter>

Create filter and register it in onCreate() method:

IntentFilter filter3 = new IntentFilter();
filter3.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
filter3.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
registerReceiver(mBroadcastReceiver3, filter3);

Then create the BroadcastReceiver in your Activity/Service:

    private final BroadcastReceiver mBroadcastReceiver3 = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();

switch (action){
case BluetoothDevice.ACTION_ACL_CONNECTED:
..
break;
case BluetoothDevice.ACTION_ACL_DISCONNECTED:
..
break;
}
}
};

And lastly, unregister:

unregisterReceiver(mBroadcastReceiver3);

If you want to read more about state constants, this is from the documentation:

public static final String EXTRA_STATE:

Used as an int extra field in ACTION_STATE_CHANGED intents to request
the current power state. Possible values are: STATE_OFF,
STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF

public static final String EXTRA_SCAN_MODE:

Used as an int extra field in ACTION_SCAN_MODE_CHANGED intents to
request the current scan mode. Possible values are: SCAN_MODE_NONE,
SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE

BroadcastReceiver not called on bluetooth pairing

Hi you need to register you broadcast receiver for following filters

ACTION_BOND_STATE_CHANGED

and then in onReceive

add them like this

    if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){
mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (mDevice .getBondState() == BluetoothDevice.BOND_BONDED) {
//means device paired
}

}

Read more Here Bluetooth Device Page

int     BOND_BONDED     //Indicates the remote device is bonded (paired).
int BOND_BONDING //Indicates bonding (pairing) is in progress with the remote device.
int BOND_NONE //Indicates the remote device is not bonded (paired).

Edit: after last Comment

you also need to add

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(mReceiver, filter);

Broadcast Receiver inside an object or inside a service?

Android Broadcast Receiver bluetooth events catching

It seems that what I was looking for it was:

IntentFilter filter2 = new IntentFilter();
filter2.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter2.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filter2.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
registerReceiver(mBroadcastReceiver2, filter2);

with this, when the adapter is scanning is trigered.

Broadcast if a bluetooth device is connecting/disconnecting?

<intent-filter>
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
</intent-filter>

These are the filters you have to add with your broadcast receiver.

ACL_CONNECTED signals when bluetooth is connected and ACL_DISCONNECTED signals bluetooth disconnection

For specific device you have to check intents/context in broadcast receiver

The two permission you have to add are:

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />

I think this should solve your problem.

setting up broadcast Receiver to turn on bluetooth

BatteryManager: Seems like using the ACTION_BATTERY_CHANGED intent is the way to go, and setting up a broadcast receiver for when this changes. Is it correct?

Yes, that is one way to monitor things like when a charger has been connected (including plugging to a USB port with charge capability). You can also use ACTION_POWER_CONNECTED.

is plugging in the phone a explicit user action?

NO - most definitely not unless you create a pop-up asking for the user's consent. To quote the docs for the enable() method...

Bluetooth should never be enabled without direct user consent. If you want to turn on Bluetooth in order to create a wireless connection, you should use the ACTION_REQUEST_ENABLE Intent, which will raise a dialog that requests user permission to turn on Bluetooth. The enable() method is provided only for applications that include a user interface for changing system settings, such as a "power manager" app.

When I plug my device to charge, 9 times out of 10 I don't want it to do anything but charge. If I had your app installed on my phone and found out it was enabling Bluetooth silently and without my knowledge, your app would be un-installed straight away.

There are known security issues with Bluetooth and, depending on user settings, you could put somebody's device at risk if it is enabled without their knowledge.

Can an intent be a method, and not just activity?

No, an Intent is part of a messaging system. See Intents and Intent Filters. Yes, I know it's not very 'newbie-friendly' but Android is a complex beast and if you really want to program successfully for it you've got to read this sort of stuff.

BroadcastReceiver onRecive does not work correctly

Please turn on GPS and try again. Please make sure that you ask Location permission to your user.

Reason: From Android 6.0 you need Location permission for Bluetooth Discovery.

More reference:

  1. https://developer.android.com/guide/topics/connectivity/bluetooth
  2. https://getlief.zendesk.com/hc/en-us/articles/360007600233-Why-does-Android-require-Location-Permissions-for-Bluetooth-

Can't call a Bluetooth BroadcastReceiver method in a Service

maybe the fact that your receiver is static causing the problem.

BroadcastReceiver should never be static. it can cause lots of problems.

other really bad design problem with your code - holding reference to activity inside service, and using it to modify views is really wrong thing to do. it can cause easily to memory leek.
the right why to communicate between Service and Activity is by implement android's Messanger, or sending broadcasts between them via BroadcastReceiver.

if you'll listen to my advice - you won't be have to make your receiver static (I guess you've made it static only because you are using the mActivity static instance inside)
and I'm pretty sure it will solve your problem

you can read about Messanger here: http://developer.android.com/reference/android/os/Messenger.html

sure you'll find lots of usage examples in the net.

example of broadcasting updates to the activity from service:

public class MyService extends Service {

@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}

@Override
public void onCreate() {
super.onCreate();

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
this.registerReceiver(bluetoothReceiver, intentFilter);
}

@Override
public void onDestroy() {
if (bluetoothReceiver != null) {
this.unregisterReceiver(bluetoothReceiver);
}
super.onDestroy();
}

public BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
updateUIWithNewState(state);
}
}
};

protected void updateUIWithNewState(int state) {
Intent intent = new Intent("serviceUpdateReceivedAction");
intent.putExtra("state", state);
sendBroadcast(intent);
}

}

and that's the activity:

public class MyActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

Intent intent = new Intent(this, MyService.class);
startService(intent);
}

@Override
protected void onResume() {
super.onResume();

registerReceiver(mServiceUpdatesReceiver, new IntentFilter("serviceUpdateReceivedAction"));
}

@Override
protected void onPause() {
unregisterReceiver(mServiceUpdatesReceiver);
super.onPause();
}

private BroadcastReceiver mServiceUpdatesReceiver = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra("state", -1);
// do what ever you want in the UI according to the state
}
};
}


Related Topics



Leave a reply



Submit