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.
Related
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>
I have manifest declared Broadcasts for android.intent.action.PHONE_STATE and android.intent.action.NEW_OUTGOING_CALL. I tested my app after I removed it from Recent apps screen. I tested it on two phones:
MOTO G4 Play(Nougat)- After I removed my app from Recent apps screen on this phone I was receiving broadcasts.
ASUS(Lollipop)- After I removed my app from Recent apps screen on this phone I was not receiving broadcasts.
One way after reading such questions on SO I got is that I can do it by starting a sticky service so what it will do is not terminate my process and I will continue to get broadcasts.
What should I do to ensure that I receive broadcasts on every phone without using a service ?
Edit-1:I register my broadcasts as follows in Manifest
`
<receiver android:name=".PhonecallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"
android:enabled="true"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"
android:enabled="true"/>
</intent-filter>
</receiver>
`
#Override
public void onReceive(Context context, Intent intent) {
Log.e("onReceive ","Called"); //This is how I check whether broadcast was called or not
//... other code
}
Think of notification broad cast that can be used to generate notification for your app, so broadcast is pretty reliable.
You are using manifest declared broad cast so theoretically, you should be able to receive broadcast regardless of whether your app is in foreground or background ( similar behavior was expected in all phone since your app targets same API). But there has been cases where mobile devices has ignored/bug some of the contract as a result some expected behavior breaks. It is very likely that similar thing happened in your ASUS based test.
From the broadcast manager documentation ,
If you declare a broadcast receiver in your manifest, the system
launches your app (if the app is not already running) when the
broadcast is sent.
However there is exception .Android has some updates on this behavior recently to restrict some of this features.
Note: If your app targets API level 26 or higher, you cannot use the manifest to declare a receiver for implicit broadcasts (broadcasts that do not target your app specifically), except for a few implicit broadcasts that are exempted from that restriction. In most cases, you can use scheduled jobs instead.
So what I believe is you should be receiving all broadcasts as long as you target API level less than 26 regardless of your app being active or not. Moving forward to API 26 or greater, you will receive broadcast regardless only if it is explicit OR exempted broadcast as per above quote.
What you encountered is probably that device specific issue which was not supposed to happen. Try testing in few more devices to rule this out.
You may want to read this for more clarification.
p.s. try not using error logging for info/debug like Log.e("onReceive ","Called");
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 .
I want to do something after the the phone is put into charger. So I
created ChargingOnReciever:
public class ChargingOnReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
context.startActivity(someActivity);
Log.d(TAG, "Phone was connected to power");
}
}
and I want my receiver to listen to android.intent.action.ACTION_POWER_CONNECTED, so I put this into manifest:
<reciever android:name=".ChargingOnReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
</intent-filter>
</reciever>
But ChargingOnReceiver is apparently not started when I put my G1 to charger
(connect to my notebook via USB cable). Any help is much appreciated.
It's receiver, not reciever! It took me 5 hours to find this stupid bug. I think that the Android Eclipse plugin should do some syntax checking in the manifest xml.
For anyone trying to register receiver for "android.intent.action.ACTION_POWER_CONNECTED" and "android.intent.action.ACTION_POWER_DISCONNECTED" , I would like to add :
As part of the Android 8.0 (API level 26) Background Execution Limits,
apps that target the API level 26 or higher can no longer register
broadcast receivers for implicit broadcasts in their manifest.
However, several broadcasts are currently exempted from these
limitations. Apps can continue to register listeners for the exempted
broadcasts, no matter what API level the apps target.
The above two broadcasts are no longer in the list of these exempted broadcasts. Please refer the documentation below :
https://developer.android.com/guide/components/broadcast-exceptions
Do not start an activity from a BroadcastReceiver.
Have you examined LogCat at the time you plug in the USB cable to see if there are any logged messages that might explain your problem?