AndroidManifest BroadcastReceiver for external SDK

Issue

I am trying to integrate Estimote bluetooth low energy beacons into an existing (big) Android 12 application. The problem is that the Manifest merger fails:

Manifest merger failed : android:exported needs to be explicitly specified for element <receiver#com.estimote.proximity_sdk.api.TriggerBroadcastReceiver>. Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined. 

From the SDK I understood that they implemented the Android BroadcastReceiver. So I tried to include the following into my AndroidManifest:

<receiver
     android:name="android.content.BroadcastReceiver"
     android:enabled="true"
     android:exported="false" >
</receiver>

This did not work and gives me still the same error. I failed to explicitly defined the class from the SDK. I tried:

<receiver
     android:name="com.estimote.proximity_sdk.api.TriggerBroadcastReceiver"
     android:enabled="true"
     android:exported="false" >
</receiver>

But I get: Unresolved class 'TriggerBroadcastReceiver'

I don’t really understand why it is not sufficient to define the Android BroadcastReceiver and how I can define a receiver for the class TriggerBroadcastReceiver from the SDK.

Any ideas, hints, explanations are very much appreciated!

Solution

Version 1.0.7 of the Estimote SDK does not seem to support Android API level 31. Looks like it’s stuck at 26! Luckily there are some ways to massage the manifest into what is hopefully needed.

First, add to your manifest’s application element:

    <receiver android:name="com.estimote.proximity_sdk.api.TriggerBroadcastReceiver" 
        android:exported="false">
        <intent-filter>
            <action android:name="com.estimote.proximity_trigger" />
        </intent-filter>
    </receiver>

If you can Context Menu > "Go to Declaration" for the above TriggerBroadcastReceiver then it ought to be wired up correctly. I was unable to replicate your finding of Unresolved class 'TriggerBroadcastReceiver'. So hopefully that resolves your immediate problem. But after that, there is a bit more you’ll likely need to allow BLE scanning to proceed.

Assuming your min SDK version is 30 or less, to override Estimote’s unqualified use of the following permissions, you can add:

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

More importantly, I believe you will need to add BLUETOOTH_SCAN and ACCESS_FINE_LOCATION permission locations to your manifest, which are needed when scanning on API 31 or greater:

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

In the app code, you will then need to request BLUETOOTH_SCAN and ACCESS_FINE_LOCATION permissions. (Fine location because Beacons do confer physical location!) If I understand correctly, the Estimote SDK allows scanning to persist in the background via a foreground service, so you won’t need to mess with ACCESS_BACKGROUND_LOCATION.

Alternatively, you could target API 30 in your app, which does not enforce the exported receiver attribute rule, and doesn’t make use of BLUETOOTH_SCAN or ACCESS_FINE_LOCATION for BLE scanning.

Caveat: I am unable to test because I’m not an Estimote user. But at least my app builds and runs.


Bluetooth permissions: Target Android 12 or higher

Answered By – ksparrow

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published