10

So I'm programming an Android app that uses Bluetooth discovery of devices. Here is the code I use to start discovery.

try {
    myBluetoothAdapter.startDiscovery();
    Log.d("Bluetooth Started successfully","yes");
} catch (Error e) {
    Log.d("FAILED","Ya failed mate");
    e.printStackTrace();
}

I then register a BroadcastReceiver to watch for when devices are found. Here is my code for that

IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
final ArrayList<String> stringArrayList = new ArrayList<>();
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getApplicationContext(),android.R.layout.simple_list_item_1,stringArrayList);
final ListView listView = findViewById(R.id.listView);
listView.setAdapter(arrayAdapter);
BroadcastReceiver myReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    Log.d("ACTION RECEIVED","Action was received");
    Log.d("Device Name", String.valueOf(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)));
    if (BluetoothDevice.ACTION_FOUND.equals(action)) {
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        stringArrayList.add(device.getName());
        arrayAdapter.notifyDataSetChanged();
        listView.invalidateViews();
    }
    }
};
registerReceiver(myReceiver,intentFilter);

The listView, arrayAdapter, and stringArrayList are just things I'm "logging" to.

The problem is that whenever I run that code I get this error and my code doesn't function. I'm assuming that the reason it doesn't function is because of this error.

W/BroadcastQueue: Background execution not allowed: receiving Intent { act=android.bluetooth.adapter.action.DISCOVERY_STARTED flg=0x10 } to com.verizon.messaging.vzmsgs/com.verizon.vzmsgs.receiver.DevicePairingListener

Can someone tell me what this error means as well as how to fix it?

I also find other questions on Stack Overflow with errors that look very similar; like, instead of Bluetooth, it will be in the context of BOOT_COMPLETED, ACTION_POWER_DISCONECTED, or BATTERY_LOW. How are those similar to this.

BlueLite
  • 187
  • 1
  • 3
  • 16
  • Please post your manifest. Do you have a `` declared in the manifest with an `` containing `android.bluetooth.adapter.action.DISCOVERY_STARTED`? – David Wasser Apr 10 '19 at 13:40

3 Answers3

14

In my case - Android 9 (API level 28) I had to define my BroadcastReceiver inside the code only to make it work.

Like this (added inside a service in my case - its not matter)

private MyReceiver myReceiver;

@Override
public void onCreate() {
    myReceiver = new MyReceiver();
    this.registerReceiver(myReceiver, new IntentFilter("android.intent.action.myreceiver"));
}


@Override
public void onDestroy() {
    super.onDestroy();
    unregisterReceiver(myReceiver);
}

private class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {

        try {
            if (intent.getAction().equals("android.intent.action.myreceiver")) {
                //logic goes here
            }
        } catch (Exception e) {
            //some log goes here
        }
    }
}

Send the broadcast like this

Intent intentMy = new Intent();
intentMy.setAction("android.intent.action.myreceiver");
intentMy.putExtra("whatever", true);
sendBroadcast(intentMy);
Daniel
  • 36,833
  • 10
  • 119
  • 200
10

Implicit broadcasts are not allowed anymore in Android Oreo and later.

An implicit broadcast is a broadcast that does not target that app specifically.

Instead of just using the intent-filter action name for constructing the Intent, search the package manager for the component providing the broadcast receiver:

            Intent intent = new Intent("the intent-filter action name in the different app").setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
            PackageManager packageManager = getPackageManager();
            List<ResolveInfo> infos = packageManager.queryBroadcastReceivers(intent, 0);
            for (ResolveInfo info : infos) {
                ComponentName cn = new ComponentName(info.activityInfo.packageName,
                        info.activityInfo.name);
                intent.setComponent(cn);
                sendBroadcast(intent);
            }
David
  • 1,050
  • 1
  • 16
  • 31
k_o_
  • 5,143
  • 1
  • 34
  • 43
-6

I think it's because of Implicit Broadcast Ban of Android O , to solve this you can make your targetSDKVersion be less than 26 . You can find more here https://commonsware.com/blog/2017/04/11/android-o-implicit-broadcast-ban.html

zht2005
  • 36
  • According to this there isn't a way around it though. Is that really true? – BlueLite Apr 09 '19 at 19:24
  • It's ok when you register the receiver in the code , I have download this code https://github.com/googlesamples/android-BluetoothChat , and I can get a callback in the BroadcastReceiver , maybe you can compare to the project to find where is the problem in your project . I noticed there are two permissions declared in the manifest . android.permission.BLUETOOTH_ADMIN and android.permission.BLUETOOTH , you can check this first. – zht2005 Apr 11 '19 at 07:49
  • 14
    Using a lower target is not a solution. – Arnold Balliu Jun 10 '19 at 20:36
  • It does not a solution – Trung Đoan Feb 05 '21 at 04:49
  • maybe it's not a solution, but it does explain the problem unlike the answer below. And solutions are there if you follow the link – StackExploded Aug 04 '21 at 14:33
  • This is not a solution, you have to be forced to upgrade your targetSDKVersion :D – Jorgesys May 22 '23 at 21:24