I want to catch ACTION_SHUTDOWN and BOOT_COMPLETE using BroadcastReceiver.
But it turns out both signals never trigger the BroadcastReceiver (I didn't see any log on logcat).
Here is my source code.
I give the permission on Manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and I try to register the BroadcastReceiver in both ways
protected void onCreate(Bundle savedInstanceState)
{
registerReceiver(BootReceiver, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
registerReceiver(ShutDownReceiver, new IntentFilter(Intent.ACTION_SHUTDOWN));
}
<receiver android:name=".BootReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
and the source code for BootReceiver and ShutDownReceiver are as
private BroadcastReceiver BootReceiver = new BroadcastReceiver()
{
private String ACTION_BOOT = "android.intent.action.BOOT_COMPLETED";
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(ACTION_BOOT)){
//my stuff
Log.d("Power", "Boot Complete");
}
}
};
private BroadcastReceiver ShutDownReceiver = new BroadcastReceiver()
{
private String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_SHUTDOWN)) {
//my stuff
Log.d("Power", "Shutdown Complete");
}
}
};
also, I unregister both BoradcastReceiver in onDestroy
public void onDestroy()
{
unregisterReceiver(BootReceiver);
unregisterReceiver(ShutDownReceiver);
super.onDestroy();
}
Does anyone know what's wrong with my code?
Or anything I miss? Thank you.
I found out why it didn't work.
Since I use a HTC device, the broadcast messages are different from others.
Shut down event broadcasts "com.htc.intent.action.QUICKBOOT_POWEROFF"
Restart(reboot) event broadcasts "android.intent.action.ACTION_SHUTDOWN"
Power on event broadcasts "com.htc.intent.action.QUICKBOOT_POWERON"
In other device, when shutting down the device, it might broadcast "android.intent.action.QUICKBOOT_POWEROFF".
Chances are that your application is not yet added to the "BOOT_COMPLETED" possible receivers list, starting from Android 3.1, in order to get the "BOOT_COMPLETED" action, your application must have been started explicitly by the user, either showing an Activity or another Component, until then your application will not receive the broadcast you are expecting, is important to know that if you "Force Close" the application, it will be missing the broadcasts again, So, try to open an activity and then reboot your device, you will get it...
Hope this Helps!
Regards!
Try this.
<receiver
android:name="packagename.GPSReceiver"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter android:priority="500" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
BOOT_COMPLETED must be registered in the manifest. You cannot register for it via registerReceiver(), because by the time you call registerReceiver(), the boot will have long since occurred.
AFAIK the shutdown broadcast works with registerReceiver(), though in your case it will only be around when your process is running.
Related
I searched the web for alot of time and I don't understand why my custom broadcast
isn't working.
<receiver
android:name=".myservice.MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
<action android:name="android.intent.action.BATTERY_CHANGED"/>
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
</intent-filter>
</receiver>
I don't it not recieve when I reconnet and disconnect the charger.
I did this for making thing simpale
public class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context,"Battery", Toast.LENGTH_SHORT).show();
Log.i("Recive", "Yes");
}
}
From docs:
ACTION_BATTERY_CHANGED
Broadcast Action: This is a sticky broadcast containing the charging state, level, and other information about the battery. See BatteryManager for documentation on the contents of the Intent.
You cannot 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
So, you cannot use this BroadcastReceiver decalred in Manifest, only registering explicitly from your context.
Also, your power connection BroadcastReceiver seems correct. Try to separate it into another BroadcastReceiver, maybe action ACTION_BATTERY_CHANGED is interfering with other actions.
This is my declared BroadcastReceiver which I use and it's working in my app.
<receiver android:name=".PowerConnectionBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
</intent-filter>
</receiver>
PowerConnectionBroadcastReceiver
public class PowerConnectionBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "PowerRcvr";
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_POWER_CONNECTED)) {
Log.d(TAG, "Device is charging");
} else if (action.equals(Intent.ACTION_POWER_DISCONNECTED)) {
Log.d(TAG, "Device is NOT charging");
} else {
Log.d(TAG, "Unable to check if device is charging or not");
}
}
}
NOTE: This code is working on Android 8 with targetSdkVersion 25 or lower.
In targetSdkVersion 26 or higher most of BroadcastReceivers doesn't work through Manifest due to background limitations. Here are documentation (thanks to Pawel) about that. So your IntentFilters wont work. To keep it working you can download your targetSdkVersion to 25 or lower.
I have a broadcast which monitors for unlock event for the phone. But when the app's process is killed and no longer in memory, Unlocking the phone does not trigger the Receiver, instead I can see in the Android studio, that new process is created for that app.
If lock and unlock it again, then as the process is already running, I can see the BroadcastReceiver is triggered.
<receiver
android:name=".UserPresentBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
Broadcast Receiver:
public class UserPresentBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = UserPresentBroadcastReceiver.class.getSimpleName();
#Override
public void onReceive(Context arg0, Intent intent) {
Log.d(TAG, "onReceive: Unlock Boradcast received");
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
Toast.makeText(arg0, "You just unlocked the device", Toast.LENGTH_LONG).show();
}
}
}
I am unable to understand this behavior. Is this the default behavior?
You have to register and unregister this broadcast receiver in Activity(or Service for listening in background all the time).
Manifest entry won't work.
I want to do something when a headset is plugged in when my app is running in the background. (if possible I want to do it with a broadcast receiver)
I tried the code below:
--ReceiveBroadcast--
package com.example.openmusiconheadsetconnect;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class ReceiveBroadcast extends BroadcastReceiver {
public ReceiveBroadcast() {
}
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Received!",Toast.LENGTH_LONG).show();
}
}
--Manifest--
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.openmusiconheadsetconnect" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name=".ReceiveBroadcast"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.HEADSET_PLUG" />
</intent-filter>
</receiver>
</application>
</manifest>
Thank you!
Your code is correct, but as far as I know, you cannot put the HEADSET_PLUG filter on the manifest.
Instead, create a receiver in its own class, and make it listen for USER_PRESENT (screen unlocked) or BOOT_COMPLETED in the manifest:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<receiver android:name="classes.myReceiver" >
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
When triggered by such events, your receiver should start the service:
public class myReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
Intent service = new Intent(ctx, VoiceLaunchService.class);
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)||intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
ctx.startService(service);
}
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
ctx.stopService(service);
}
}
The service will now register the receiver that will be listening to the HEADSET_PLUG intent, in its onCreate method:
#Override
public void onCreate() {
super.onCreate();
speechReconRx=new SpeechReconControlReceiver(this);//"this" will allow you to call service's methods from the receiver
registerReceiver(speechReconRx, new IntentFilter(Intent.HEADSET_PLUG));
}
It's is a hassle, but you'll need it if you don't want to use an activity.
It is google's fault for not letting us put PLUG receivers in the manifest! Finally make the Broadcast that will take action when the headset is plugged in.
public class SpeechReconControlReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
Log.e("joshcsr","HEADSET PLUGGED!");
if(intent.getStringExtra("command")!=null){
c=intent.getStringExtra("command");
}
//run some methods from the service
if (c.equals("resume")) {
sService.resume();
}
if (c.equals("pause")) {
sService.pause();
}
if (c.equals("stop")) {
sService.stop();
}
}
}
To wrap, up you will need:
*A receiver for the BOOT/Screen unlock events.
*A Service to hold everything that will run on the background and to register your headset listening broadcast.
*And a receiver for the headset Plug, that will take action and call methods hosted in the service.
I've did this yesterday, and it works from Jelly bean to Lollipop ...and perhaps even older versions. Cheers.
First you'll need permission to start app in background after boot is completed.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and also specify this in your broadcast receiver,
<receiver android:name=".YourBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
Then create a service that run your application in background, and inside the service use AudioManager.isWiredHeadsetOn() to check if the headset is plugged in. And if so, do the task you want.
while(AudioManager.isWiredHeadsetOn()){
//your task goes here
}
Also add the permission in manifest
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
I am calling the following BroadcastReceiver using AlarmManager every X mins. Its working fine.
public class MyAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (CommonFuncs.isConnectedBySettings(context)) {
if(CommonFuncs.isUpdateTimeValid(context)){
Intent intentCurSvc = new Intent(context, CurrencySvc.class);
context.startService(intentCurSvc);
}
}
}
Manifest
<receiver
android:name=".service.AlarmSvcRecevier"
android:process=":remote" >
</receiver>
I want to use the same BroadcastReceiver for connectivity change as well, by just adding the following manifest.
<receiver
android:name=".service.AlarmSvcRecevier"
android:process=":remote" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
But my receiver is not getting called when WIFI is connected. I am not sure what is the problem. Do I need a separate receiver for AlarmManager and CONNECTIVITY_CHANGE to perform same operation? Is my approach correct?
I have a broadcast receiver defined in the manifest with the android.bluetooth.device.action.ACL_CONNECTED in the intent filter.
It's triggered fine when the app is in the stack, but after I stop it from android settings it won't trigger anymore. any suggestions?
Update for Menny:
<receiver android:name=".auto.AppLauncher">
<intent-filter>
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
</intent-filter>
</receiver>
Did you program a BroadcastReceiver in your Code?
public class receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
//something you want to do here
}
}
}