I am having the exact same problem as this post: Battery broadcast receiver doesn't work. But it seems no one has answered that question.
Here is my BroadcastReceiver:
public class BatteryLevelReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.v("plugg", "plug change fired");
Toast.makeText(context, " plug change fired", Toast.LENGTH_LONG).show();
}
And here is my AndroidManifest.xml:
<receiver android:name=".ReceversAndServices.BatteryLevelReceiver">
<intent-filter android:priority="900">
<action android:name="android.intent.action.BATTERY_LOW" />
</intent-filter>
</receiver>
<receiver android:name=".ReceversAndServices.BatteryLevelReceiver">
<intent-filter android:priority="900">
<action android:name="android.intent.action.BATTERY_CHANGED" />
</intent-filter>
</receiver>
I have also added this line to the manifest:
<uses-permission android:name="android.permission.BATTERY_STATS"/>
But still no success!
I would really appreciate if someone could advise me what I am doing wrong.
From the documentation for ACTION_BATTERY_CHANGED:
You can not receive this through components declared in manifests, only by explicitly registering for it with Context.registerReceiver(). See ACTION_BATTERY_LOW, ACTION_BATTERY_OKAY, ACTION_POWER_CONNECTED, and ACTION_POWER_DISCONNECTED for distinct battery-related broadcasts that are sent and can be received through manifest receivers.
There you have it: you must explicitly register for it from your Java code.
I just followed the Android Developer Guide's on Monitoring the Battery Level and Charging State and had immediate success. If BatteryLevelReceiver is it's own class then I would recommend:
<receiver android:name=".BatteryLevelReceiver">
<intent-filter android:priority="900">
<action android:name="android.intent.action.BATTERY_LOW" />
<action android:name="android.intent.action.BATTERY_CHANGED" />
</intent-filter>
</receiver>
Addition
I'm willing to guess that you wrote BatteryLevelReceiver as a nested class in ReceversAndServices. According to Receiver as inner class in Android, you cannot do that with non-static classes. You could make BatteryLevelReceiver a static class and register the receiver in onResume(), but then your app will need to be running to catch the events... Move your receiver to a separate class and register these Intents:
<receiver android:name=".BatteryLevelReceiver">
<intent-filter android:priority="900">
<action android:name="android.intent.action.BATTERY_LOW" />
<action android:name="android.intent.action.BATTERY_OKAY" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
(Not BATTERY_CHANGED as Darshan Computing pointed out.)
Make sure you have the battery receiver class not as a subclass of another one but as a seperate class in your project.
Also try using Context.registerReceiver() method explicitly in your code and do not forget to unregister it: http://developer.android.com/reference/android/content/Context.html#registerReceiver%28android.content.BroadcastReceiver,%20android.content.IntentFilter%29
Related
In an application, I am trying to implement a service which needs to run every time when device boot process completed.
Application unable to broadcast service only in MI devices.
Manifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
BroadcastReceiver
public class SavedLocationBroadcast extends WakefulBroadcastReceiver {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onReceive(Context context, Intent intent) {
App.showToast(context,"BROADCAST","SEND");
Intent service = new Intent(App.getContext(), MyLocationService.class);
startWakefulService(App.getContext(), service);
}}
Reciever in manifest
<receiver android:name="com.geolocation.broadcastreciever.SavedLocationBroadcast">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="com.geolocation.app.ACTION_PULSE_SERVER_ALARM" />
</intent-filter>
</receiver>
Please share your suggestion is anything wrong in implementation.
This is solution for your bug.
What you need to do is that , you need to mention this permission also in your Intent-Filter.
<receiver android:name="com.geolocation.broadcastreciever.SavedLocationBroadcast"
android:enabled="true"
android:exported="true" >
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.REBOOT"/>
</intent-filter>
</receiver>
Here you need to do one thing also.
Go to "Settings-Apps_open your app info-Manage permisson" in yourdevice
Here check all things here.
Because for some devices it will not work. Ex.Red mi
Try this !
iam using MediaButtonReciever in my Streaming service to listen handle head sets and different devices action
i'm declaring it in Manifest like this
<receiver android:name="android.support.v4.media.session.MediaButtonReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
The actions works just fine as long as the app in the background
once the app is terminated if i clicked on any MediaButton it crashes as the media button with the following crash
Fatal Exception: java.lang.RuntimeException: Unable to start receiver android.support.v4.media.session.MediaButtonReceiver: java.lang.IllegalStateException: Could not find any Service that handles android.intent.action.MEDIA_BUTTON or a media browser service implementation
the problem is the receiver keeps receiving even if the app is destroyed, now how can i unregister the receiver once the app close ?
i have tried audioManager.unregister(MediaButtonReciever) but its depreciated
the problem was that i was using the default class in my manifest like this
<receiver android:name="android.support.v4.media.session.MediaButtonReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
which was wrong the the receiver automatically unregister after onReceive() is finished
Once you return from onReceive(), the BroadcastReceiver is no longer active, source
so all idid was i extened MediaRecieverButton in my custom class MyMediaButtonReceiver
and edited my manifest like this
<receiver android:name=".MyMediaButtonReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
and it worked just fine
If you only want to handle buttons when your app is running, then you shouldn't declare this in the manifest. You should register and unregister the BroadcastReceiver dynamically in your code when you want it to respond to events.
To register the receiver, do:
BroadcastReceiver receiver = new MediaButtonReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
registerReceiver(receiver, filter);
When you are done (ie: in onDestroy() of your component), unregister the receiver like this:
unregisterReceiver(receiver);
in my case I got this error and I solve it by set enable flag of My service to true:
android:enabled="true"
<service
android:name=".MyService"
android:enabled="true"
android:multiprocess="true">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</service>
I have implemented a receiver like this (in the manifest file)
<receiver android:name="com.phonelight.realparrot.RecorderBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE">
</action>
</intent-filter>
</receiver>
If the state of the phone changes, the recorder broadcast receiver is invoked.
Everything is fine. However, If I reboot the device, the receiver is never invoked until I run my application.
I need to register (not invoking) this receiver after booting.
Many thank,
[Edit]
I solved the problem by adding the following receiver to the Manifest file
<receiver android:name="com.phonelight.realparrotpro.RecorderBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I did not register the RecorderBroadcastReceiver in the java code though.
I only added the above receiver. It means invoking anything from an app will register all the receivers written in the Manifest file.
You need to create a receiver for onBootComplete and then register your receiver there. This way your receiver will get registered even after reboot.
<receiver android:name="App_Receiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Can We only work with one broadcast receiver ?
I have some broadcast receiver and they works well , :
Note: Only one BroadcastReceiver class can be specified per application. Should you need to incorporate two or more BroadcastReceivers from different SDKs, you will need to create your own BroadcastReceiver class that will receive all broadcasts and call the appropriate BroadcastReceivers for each type of Broadcast.
Yes, you may use a single BroadcastReceiver to catch all action strings. Make sure you do add all the action string in your IntentFilter used by that receiver to make it work.
An <application> can contain multiple <receiver> and each <receiver> can contain multiple <intent-filter>. E.g.:
<application>
<receiver android:name="ReceiverA">
<intent-filter>
<action android:name="android.intent.action.ACTION1"/>
</intent-filter>
</receiver>
<receiver android:name="ReceiverB">
<intent-filter>
<action android:name="android.intent.action.ACTION2" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION3" />
<data android:scheme="file" />
</intent-filter>
</receiver>
</application>
But you can only have one "com.google.android.apps.analytics.AnalyticsReceiver" - that is IMO what the documentation means.
I understand that I can register a broadcast receiver either statically through the manifest or programmatically by registering and unregistering the receiver in an activity. In my case I want the OS to instantiate and call my broadcast receiver when my code is not in memory. So I included my receiver in my manifest. Unfortunately if my code is not in memory, my broadcast receiver never runs. I am very confused as to why this is. I have included snippets of my manifest below. Please let me know if there is something wrong/missing with this. Thank you.
<receiver android:name=".DesktopConnectionReceiver"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
<action android:name="android.intent.action.UMS_CONNECTED"/>
</intent-filter>
</receiver>