BroadcastReceiver onReceive() never called - java

I am trying to discover bluetooth devices nearby. I followed tutorials but I can't figure out why onReceive() method is never called. Even though startDiscovery() is successful,the method onReceive() never gets called. I have added the proper permissions to the manifest
if(adapter.isDiscovering()) {
adapter.cancelDiscovery();
if (adapter.startDiscovery())
test.setText("Searching >>>");
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
Receiver receiver = new Receiver();
registerReceiver(receiver, filter);
}
}
if(!adapter.isDiscovering()) {
if (adapter.startDiscovery())
test.setText("Searching >>>");
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
Receiver receiver = new Receiver();
registerReceiver(receiver, filter);
}
private class Receiver extends BroadcastReceiver {
public Receiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devices = new ArrayList<BluetoothDevice> ();
devices.add(device);
listAdapter = new DeviceListAdapter(context,R.layout.activity_bluetooth_connection,devices);
pairedDivices = (ListView) findViewById(R.id.pairedDevices);
pairedDivices.setAdapter(listAdapter);
if(devices.isEmpty())
test.setText("no devices");
}
}
}

Related

Scan discovery not work in android application

I am able to list unpaired devices on scan discovery only if other devices are on their 'bluetooth setting screen'.If other devices are on their homepage then my application cannot find those devices.
I have android 7 on my mobile phone and other devices have android 9 on them.
Any help is appreciated.Thanks:)
public void startDiscovery()
{
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
BA.startDiscovery();
registerReceiver(mReceiver, filter);
Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d("main","action found"+action);
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Toast.makeText(getApplicationContext(), "Discovery finished", Toast.LENGTH_SHORT).show();
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
Log.d("main","devicename"+deviceName);
Log.d("main","deviceHardwareAddress"+deviceHardwareAddress);
}
};
#Override
protected void onDestroy() {
Log.d("main","destroyed");
super.onDestroy();
BA.cancelDiscovery();
// Don't forget to unregister the ACTION_FOUND receiver.
unregisterReceiver(mReceiver);
}
Its not being discovered because its hidden according to the bt protocol however see https://stackoverflow.com/a/36984988/8461344

I don't receive an action on my BroadcastReceiver - AndroidStudio

It's my first time working with Bluetooth module in Android, I'm trying to scan devices not paired yet and show them in a message but it doesn't work. I have tried a lot of things but nothing. I have all the permissions needed. This is part of my code
mScanBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
//registerReceiver(mBroadcastReceiver, filter);
if(mBlueAdapter!=null && mBlueAdapter.isEnabled()) {
listAdapter.clear();
mBlueAdapter.startDiscovery();
showToast("Discovery");
IntentFilter filtera = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBroadcastReceiver, filter);
}
And this is my BroadcastReceiver
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
listAdapter.add(device.getName() + device.getAddress());
listAdapter.notifyDataSetChanged();
showToast("Action Scan Mode " );
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
mpossibleBtn.setText("Scanning Bluetooth Devices");
showToast("Scannning Bluetooth Devices... " );
} else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
mpossibleBtn.setText("Scanning in progress...");
showToast("Scanning in progress... " );
}
if (action.equals(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)) {
showToast("Action Scan Mode " );
int modeValue=intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.ERROR);
if(modeValue==BluetoothAdapter.SCAN_MODE_CONNECTABLE){
mPairedTv.setText("The device is not in discoverable mode but still can receive connections");
} else if(modeValue==BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){
mPairedTv.setText("The device is in discoverable mode");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
showToast("onReceive: " + device.getName() + ": " + device.getAddress());
} else if (modeValue==BluetoothAdapter.SCAN_MODE_NONE){
mPairedTv.setText("The device is not in discoverable mode and can't receive connection");
} else{
mPairedTv.setText("Error");
}
}
}
};
I'm testing the app on my Xiaomi cellphone.
you need to ADD after registering receiver
mBtAdapter.startDiscovery();
Start discovery after registering your receiver.
IntentFilter intent = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(mBroadcastReceiver, intent);
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mBroadcastReceiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBroadcastReceiver, filter);
mBtAdapter.startDiscovery();
Or in your case
IntentFilter filtera = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBroadcastReceiver, filter);
mBtAdapter.startDiscovery();
Also ensure you have bt permissions on your manifest
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
On some phones you will need to restart the adapter first.
mBluetoothAdapter.disable();
mBluetoothAdapter.enable();
for some time on the broadcast receiver if you don't receive BluetoothAdapter.ACTION_DISCOVERY_STARTED after starting discovery, you have to prompt device restart as the bt may not be working properly.you can use a timer to check this.
Ok so I just found my error. In this case BLUETOOTH and BLUETOOTH_ADMIN permissions have a protection Level of normal, and so all you need to do is request them in the manifest. The location permissions are dangerous, though, and so on Android 6.0+ devices, with a targetSdkVersion of 23 or higher, you need to request those at runtime.
I alredy have the permissions however, we do need to request ACCESS_COARSE_LOCATION at runtime.
This time the code works
mScanBtn.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(View v) {
if(mBlueAdapter!=null && mBlueAdapter.isEnabled()) {
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBroadcastReceiver, filter);
if (context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mMap != null) {
mMap.setMyLocationEnabled(true);
mBlueAdapter.startDiscovery();
}
}
else {
// Permission to access the location is missing. Show rationale and request permission
PermissionUtils.requestPermission(MainActivity.this, MY_PERMISSIONS_REQUEST_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION, true);
mBlueAdapter.startDiscovery();
}
}
});

Android - ArrayList containing Bluetooth devices remains empty

I am trying to discover all available bluetooth devices and pass to another activity.
However even when looking at the Android Docs, I am unable to figure out why I cannot discover any devices and my ArrayList remains empty.
OnClick execute this:
mBluetoothAdapter.startDiscovery();
My broadcast listener also works but nothing is every returned and ArrayList remains empty.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device);
showToast("Found device " + device.getName());
}
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if (state == BluetoothAdapter.STATE_ON) {
showToast("Enabled");
showEnabled();
}
}
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
mDeviceList = new ArrayList<>();
mProgressDlg.show();
}
if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
mProgressDlg.dismiss();
Intent newIntent = new Intent(MainScreen.this, DeviceListActivity.class);
if (mDeviceList.isEmpty()){
Log.d("onReceive: ", "EMPTY");
}
newIntent.putParcelableArrayListExtra("device.list", mDeviceList);
startActivity(newIntent);
}
}
};
GIST
Answered my own question.
The fix was to turn location on with app permissions.
Apparently this is required for Android Marshmallow

How to call onReceive method in another method?

Currently I developed a new method to discover bluetooh ready connections. Here is my code:
private void DiscoverOBDConnection() {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.startDiscovery();
BroadcastReceiver mReceiver;
// Create a BroadcastReceiver for ACTION_FOUND
final List<String> discoverableDevicesList = new ArrayList<String>();
mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
discoverableDevicesList.add(device.getName() + "\n" + device.getAddress() + "\n" + rssi);
String discoveredDeviceName = device.getName();
discoverableDevicesList.add(discoveredDeviceName);
}
}
};
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
context.registerReceiver(mReceiver,filter); // Don't forget to unregister during onDestroy
}
I just do not know how to call the onreceive method from another method. Could you help me to learn how to implement and discover the ready to connect bluetooth devices?
You can just send broadcast
Intent i = new Intent(BluetoothDevice.ACTION_FOUND);
sendBroadcast(i);
Or call it directly
mReceiver.onReceive(this, new Intent(BluetoothDevice.ACTION_FOUND));

Class extending BroadcastReceiver not working

I made a helper class that extends BroadcastReceiver to listen for BluetoothDevice found and discovery finish intents. I have two activities which use this class by passing a handler. The handler receives messages as per the intent. I instantiate the class and registerReceiver like this:
From mainActivity:
deviceHelper=new DevicesHelper(myHandler,DevicesHelper.REQUEST_DETECT_DEVICES_IN_RANGE);
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(deviceHelper, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(deviceHelper, filter);
if(myBluetoothAdapter.isDiscovering())myBluetoothAdapter.cancelDiscovery();
myBluetoothAdapter.startDiscovery();
From ListActivity:
deviceHelper=new DevicesHelper(deviceListHandler,DevicesHelper.REQUEST_DEVICE_LIST_ACTIVITY);
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(deviceHelper, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(deviceHelper, filter);
DeviceHelper class:
public class DevicesHelper extends BroadcastReceiver {
public final static int REQUEST_DEVICE_LIST_ACTIVITY=1;
public final static int REQUEST_DETECT_DEVICES_IN_RANGE=2;
Handler myHandler;
int requestCode;
public DevicesHelper(){
}
public DevicesHelper(Handler handler,int requestCode){
this.requestCode=requestCode;
myHandler=handler;
}
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
// When discovery finds a device
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
switch(requestCode){
case REQUEST_DEVICE_LIST_ACTIVITY:
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
//newDevicesCount++;
String[] deviceInfo={device.getName(),device.getAddress()};
myHandler.obtainMessage(DeviceListActivity.MESSAGE_NEW_DEVICE,deviceInfo);
};
break;
case REQUEST_DETECT_DEVICES_IN_RANGE:
String[] deviceInfo={device.getName(),device.getAddress()};
myHandler.obtainMessage(StripChartRecorder.MESSAGE_NEW_DEVICE,deviceInfo);
break;
}
// When discovery is finished, change the Activity title
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
myHandler.obtainMessage(StripChartRecorder.MESSAGE_DISCOVERY_FINISHED);
}
}
Handler:
private final Handler myHandler=new Handler() {
#Override
public void handleMessage(Message msg) {
switch(msg.what) {
case MESSAGE_NEW_DEVICE:
doOtherStuff();
case MESSAGE_DISCOVERY_FINISHED:
dostuff();
}
break;
}}
Am I missing something here? I appreciate any help.
You need to sendMessage(Message msg) where msg is the Message you get with obtainMessage.
The problem was how I was handling the message received from the handler. Turned out Set<> was initially set to null as per eclipse's instruction, so it was never adding the devices received from the BroadcastReceiver helper class. I appreciate anyone who tried to help.

Categories