Is it possible to listen for DownloadManager.ACTION_DOWNLOAD_COMPLETE in Manifest.xml?
All the examples I found use registerReceiver(downloadCompleteReceiver,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); from a class but I would like to receive it in Manifest.xml so I can listen when the app is closed.
I can't find this action when I try to set the intent-filter for my receiver in Manifest.xml
As the official documentation states:
Beginning with Android 8.0 (API level 26), the system imposes additional restrictions on manifest-declared receivers.
If your app targets Android 8.0 or higher, you cannot use the manifest to declare a receiver for most implicit broadcasts (broadcasts that don't target your app specifically). You can still use a context-registered receiver when the user is actively using your app.
From Is android.intent.action.DOWNLOAD_COMPLETE an explicit broadcast? we learn that android.intent.action.DOWNLOAD_COMPLETE seems to be an explicit broadcast, therefore there should be no issue defining a <receiver> for it in the manifest, even if it's not autocompleted. So just add it with an action of android.intent.action.DOWNLOAD_COMPLETE.
<receiver
android:name=".your.DownloadCompleteReceiver"
android:permission="android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter>
</receiver>
Related
I have a receiver registered in my app's manifest file with action BOOT_COMPLETED.
There is a third-party library in my app and when it receives BOOT_COMPLETED action, it starts a service. Since there is background execution limits in Android Oreo, it crashes.
Now, I want to disable this receiver for only Android O devices. Is there a way to do this? Maybe just like #TargetApi but in Android Manifest?
I forgot to write that I cannot change library class, it's an external jar file.
Since Library's code is not in your control, any approach won't work. You should ask the library provider to comply with latest OS.
You can try following work around:
Register BOOT_COMPLETED in your app with high priority as follows:
<action android:name="android.intent.action.BOOT_COMPLETED" android:priority="999"/>
Start a Foreground Service immediately
This might allow your library to start background service.
Alternatively, If you have access to the BootReceiver class of the library, you can disable it as follows:
PackageManager pm = getPackageManager();
ComponentName compName =
new ComponentName(getApplicationContext(),
<library_broadcastreceiver>.class);
pm.setComponentEnabledSetting(
compName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
It's too late for answer, but maybe it will help someone.
I found different solution, like in accepted answer you can register receiver in your manifest, but instead of priority you can specify tools:node="remove" and this attribute will be removed from the resulting manifest. Also I think it's possible to create separate manifest for Android O.
<receiver android:name="com.package.app.SomeReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" tools:node="remove"/>
</intent-filter>
</receiver>
Register BroadcastReceiver for SMS_RECEIVE in Manifest, on Android 4.2 my broadcast receiver is called even when app is closed (from recent also).
But on Android 7.0, its called when app is running or is in recent, if app is closed it is not being called. I tried to use service and registered Broadcast inside Service still same scenario.
My Receiver is:
<receiver
android:name=".BroadcastReceiver.SMSBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="999">
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
Is something missing, or any other way, or now its how it will work?
https://developer.android.com/guide/components/broadcasts provides the following information:
Beginning with Android 8.0 (API level 26), the system imposes additional restrictions on manifest-declared receivers. If your app targets API level 26 or higher, you cannot use the manifest to declare a receiver for most implicit broadcasts (broadcasts that do not target your app specifically). You can still use a context-registered reciever when the user is actively using your app.
There is also a video about declaring static services/receivers in the manifest.
You probably need to update the code to use job scheduler or work manager. Google i/o was full of work manager videos.
I think you are missing runtime permissions. It was added after Android 6.0
check this .
<receiver
android:name="MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I don't understand if it's needed to be notified.
If it were true any app could call my receiver with those actions? So If I make it false the system can send the actions to my receiver?
I don't understand if it's needed to be notified. If it were true any
app could call my receiver with those actions? So If I make it false
the system can send the actions to my receiver?
Actually, others apps cannot "call your receiver". Other apps can just send broadcast Intents. The System will then call all registered receivers.
In general you shouldn't worry about this. Most of these broadcast Intents are protected so that only system apps can broadcast them anyway. An attempt by another app to broadcast BOOT_COMPLETED, for example, would just be ignored. What would happen if your BroadcastReceiver gets triggered by a rogue app because it broadcast CONNECTIVITY_CHANGE? Probably nothing, because your app should check the real connectivity state in onReceive() anyway, and if there isn't any change you can just ignore it.
Also, you don't need to specify android:enabled="true" because this is the default state. You also don't need to specify android:exported="true" because you have an <intent-filter> attached to your <receiver> which automatically sets android:exported to true.
If you set android:exported ="false", implies that the receiver is intended only for application-internal use.
Note: This attribute is not the only way to limit a broadcast receiver's external exposure. You can also use a permission to limit
the external entities that can send it messages
Adding to #SaravInfern's answer. Here is the relevant permission doc for limiting external entities that can send the receiver messages:
https://developer.android.com/training/permissions/restrict-interactions#broadcast-receivers
While it is possible to declare a 'Local' BroadcastReceiver via code so it receives intents published via a LocalBroadcastManager.Ex
LocalBroadcastManager.getInstance(this).registerReceiver(new FooReceiver(), new IntentFilter("foo_intent_filter"));
I wonder if it is possible to declare such receiver via the manifest.xml (cleaner) .
When I use the 'manifest way', the receiver is not 'receiving' the intents.
<receiver
android:name="FooReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="foo_intent_filter" />
</intent-filter>
</receiver>
Am I missing something? or the code-way is the only viable solution.
Thanks
I wonder if it is possible to declare such receiver via the manifest.xml (cleaner) .
First, that is not possible.
Second, registering in the manifest has little to do with it being "cleaner". It is to allow Android to instantiate the receiver on its own, so that you can respond to broadcasts when your process is not running. And, in the specific example that you cite, it is to allow any app on the system to send you a broadcast. Neither of those are relevant for LocalBroadcastManager.
There seems to be different opinions on whether it is possible to catch the ACTION_USER_PRESENT screen unlock through the manifest.
This thread implies no it can't be done:
Android Broadcast Receiver Not Working
This thread implies yes it can be done:
Broadcast Receiver for ACTION_USER_PRESENT,ACTION_SCREEN_ON,ACTION_BOOT_COMPLETED
I'm not able to get the event working with either a 2.3.3 or 3.2 emulator.
Does anyone else have recent experience with this? And perhaps a code sample to share?
Use a receiver:
public class Receive extends BroadcastReceiver {
if (intent.getAction() != null) {
if
( intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
Intent s = new Intent(context, MainActivity.class);
s.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(s);
}}
And in your manifest:
<receiver
android:name=".Receive"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT"/>
</intent-filter>
</receiver>
The official document says:
Beginning with Android 8.0 (API level 26), the system imposes
additional restrictions on manifest-declared receivers.
If your app targets Android 8.0 or higher, you cannot use the manifest
to declare a receiver for most implicit broadcasts (broadcasts that
don't target your app specifically). You can still use a
context-registered receiver when the user is actively using your app.
so only some exception can receive implicit, manifest-defined events.
Short answer:
so it's not possible anymore to declare it in the manifest. but it's available by context-registering.