Search code examples
androidkotlinbroadcastreceiverandroid-broadcastandroid-broadcastreceiver

Context-Registered Receiver not being triggered by Custom Action


I have a problem: the Broadcast Receiver in one of my apps isn't having its onReceive callback triggered by a custom action broadcast sent by my service from a separate app.

The broadcast receiver is context-registered, meaning I don't want to declare it in a manifest file anywhere because I don't want broadcasts launching my app. The broadcast is being sent from a service completely separate from the app, so we're dealing with inter-process communication here and a local broadcast won't do.

My suspicion is that i'm not correctly matching the intent action string declared in my broadcast sender (the Service) with my broadcast receiver (the App).

Looking at my code below, what am I doing incorrectly?

ScannerService.kt

Intent().also { intent ->
    intent.action = "com.foo.bar.example.package.ScannerService.SCANNER_EVENT"
    intent.putExtra("barcode", barcode)
    intent.setPackage("com.nu.rms")
    sendBroadcast(intent)
    Timber.d("Sent broadcast")
}

AppActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    registerBroadcastReceivers()
}

private fun registerBroadcastReceivers() {
        val broadcastReceiver = ScannerBroadcastReceiver()
        val filter = IntentFilter().apply { addAction("SCANNER_EVENT") }
        registerReceiver(broadcastReceiver, filter)
        Timber.d("Registered broadcast receiver")
    }

class ScannerBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Timber.d("Received broadcast")
        StringBuilder().apply {
            append("Action: ${intent.action}\n")
            append("URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n")
            toString().also { log -> Timber.d(log) }
        }
    }
}

Solution

  • Try to use a manifest-declared receiver (eg. in case permissions may have to be added there):

    <receiver
        android:name=".ScannerBroadcastReceiver"
        android:permission="android.permission.INTERNET">
        <intent-filter>
            <action android:name="com.foo.bar.example.package.ScannerService.SCANNER_EVENT"/>
        </intent-filter>
    </receiver>
    

    When using a context-registered receiver, the action might be ScannerService.SCANNER_EVENT or verbosely com.foo.bar.example.package.ScannerService.SCANNER_EVENT.