Android: Event ACTION_POWER_CONNECTED is not sent to my BroadcastReceiver - android

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?

Related

How reliable are Broadcast Receivers across different brand phones?

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");

LocationManager.PROVIDERS_CHANGED_ACTION will not work on API 26 and higher

I am using following code to get location on/off event.
<receiver
android:name=".receivers.GpsReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
I am developing geofence based app. Based on Re-register geofences only when required we have to re register the geofences after the app has received a GEOFENCE_NOT_AVAILABLE alert. This typically happens after NLP (Android's Network Location Provider) is disabled.
By using this broadcast receiver I re-registered the geofences when Android's Network Location Provider is enabled.
But from API level 26 this broadcast receiver will never work. See
Background Execution Limits.
So how can I achieve the same task in API 26 and higher?
Note : I need to re-register the geofences even when app is in the background.
You could switch to registering you receivers dynamically by Context.registerReceiver(), but IMHO there is no reliable way to get them registered "forever", because the system is going to terminate your process anyway on certain conditions.
Sure, you could re-register them by using e.g. white listed broadcast receivers, AlarmManager, JobScheduler etc. But this is not the best way in terms of battery and other resource consumption. Actually this is the reason, why Google disabled the implicit broadcasts.
The point is: By disabling implicit broadcasts in Oreo Google forces you to use some kind of recurring job to to do things like this. As the result, you don't need to listen for the NLP state updates, you just set your geofences with GeofencingClient.addGeofences (if NLP is enabled) in your recurring job over and over again.
as mentioned in the article you've linked, there's no way on Android API 26 to listen to implicit broadcasts like
<action android:name="android.location.PROVIDERS_CHANGED" />
if the app is killed or isn't currently running in background.
The only thing what you can do is to register the broadcast receiver on runtime, as stated in the migration guide.
What I did is calling registerReceiver in the application class in onCreate and unregister it in onTerminate.
class MyApplication : Application() {
private val gpsReceiver = MyBroadcastReceiver()
override fun onCreate() {
super.onCreate()
registerReceiver(gpsReceiver, IntentFilter("android.location.PROVIDERS_CHANGED"))
}
override fun onTerminate() {
super.onTerminate()
unregisterReceiver(gpsReceiver)
}
}
Hopefully, this could help you!
maybe you should try use background service and wakelock for long-running in the background when app closed/killed or screen off.
it's works for me :)

BroadcastReceiver doesnt receive when app is closed

I know this question is similar to many questions of BroadcastReceiver but as I read, non of them have solutions.
the tutorial of BroadcastReceiver tells it will work even app was not running in the background, my question is why I can not use it when app is not running
I tried to call broadcast from main activity, use service and ....
but non of them solved my problem.
here is my CODE:
MyReceiver java Class:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"BroadCast Trigger",Toast.LENGTH_SHORT).show();
}
}
Also MyManifest Code:
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.media.VOLUME_CHANGED_ACTION" />
</intent-filter>
</receiver>
As I found there is no way to active BroadcastReceiver in Huawei Devices programmatically, but here is a solution to find device type and do needed action in this regard such as show an alert to user to activate it manually.
if ("huawei".equalsIgnoreCase(android.os.Build.MANUFACTURER)) {
// Do Needed Action
}
I faced with same problem on Huawey Honor with Android 7. On Sony and ZTE devices BroadcastReceiver works as expected. But on Honor it work some time and suddenly stop.
I discover, that problem not related with re-boot. I reboot device and broadcast receiver work after it. But sometimes, it stop without rebooting.
First i add my app to protected list according this solution:
"Protected Apps" setting on Huawei phones, and how to handle it
But it didn't help :(
Then, i add a fake accessibility service to my app, according to this recommendation:
Broadcast Receiver Not Working After Device Reboot in Android
And problem was solved!

How can I discover that my device has rebooted, given that HONEYCOMB BOOT COMPLETED is no longer supported?

I am developing app in Android 4.0.3. I've read that the HONEYCOMB BOOT COMPLETED event is no longer supported, according to Google's documentation.
Given this, how can I discover that my device has rebooted?
CODE -
Java Class :-
public class MyStartupIntentReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Logger.i("Device", "REBOOT");
Logger.i("Device", "REBOOT");
Logger.i("Device", "REBOOT");
Logger.i("Device", "REBOOT");
Logger.i("Device", "REBOOT");
}
}
Manifest File :-
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name="MyStartupIntentReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
sorry , but perhaps you are wrong about the documentation , any way make sure that you are including <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> permission in your manifest . I use this broadcast in many apps and they works great.
Make sure you know aslo about this info BOOT_COMPLETE is sent to applications before external storage is mounted. So if application is installed to external storage it won't receive BOOT_COMPLETE broadcast message.
I am developing app in Android 4.0.3. I've read that the HONEYCOMB BOOT COMPLETED event is no longer supported, according to Google's documentation.
You misinterpreted the documentation. BOOT_COMPLETED is supported. However, it does require some component of your application to be run manually, before any registered BroadcastReceiver will work. Typically, this is done by starting an activity. Hence, if you just install an app and restart the device, you will not get control at boot time.
You can read more about this in the "Launch controls on stopped applications" of the Android 3.1 release notes, as well as in this blog post.

ACTION_USER_PRESENT in manifest with BroadcastReceiver

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.

Categories

Resources