I've created an IntentService
for downloading a file using Android's DownloadManager. Following is my Class:
public class DownloadService extends IntentService {
public DownloadService() {
super("name");
}
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
function();
}
};
@Override
protected void onHandleIntent(Intent intent) {
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
Utility.download(someURL);
}
}
I've this entry in manifest:
<service
android:name=".services.DownloadService"
android:enabled="true" >
</service>
The code inside BroadcastReceiver(function())
is never executing even if the file is downloaded. I also tried doing the same thing in Service
instead of IntentService
, it worked.
How can I make BroadcastReceiver work inside IntentService?
Avoid calling registerReceiver
method using IntentService's context.
Once your IntentService#onHandleIntent method returns, the Service#stopSelf(int) method will be called. All the not-yet-unregistered receivers will be considered as leaked. The framework even warns you about that:
E/ActivityThread﹕ Service com.your.packagename.YourIntentService has leaked IntentReceiver com.your.packagename.YourReceiver@41f4cd08 that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.IntentReceiverLeaked: Service com.your.packagename.YourIntentService has leaked IntentReceiver com.your.packagename.YourReceiver@41f4cd08 that was originally registered here. Are you missing a call to unregisterReceiver()?
at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:796)
at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:597)
at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1438)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1418)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1412)
at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:467)
at com.your.packagename.YourIntentService.onHandleIntent(YourIntentService.java:79)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.os.HandlerThread.run(HandlerThread.java:61)
And of course, none of your leaked broadcast receivers will receive notifications afterwards.
If you still want to register the broadcast receiver within IntentService#onHandleIntent method, use (for example) Application's context for that.
getApplication().registerReceiver(receiverInstance,
new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
Note however, that you'll have to add logic that unregisters each such receiver instance once you finish with it.