Broadcast not triggered when process is created - android

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.

Related

Android: Will AlarmManager gets killed after shutdown

I am wondering will the alarm that I have set get destroyed after i shutting down the device or will it save the state of the schedule and broadcast straightaway when the user turning back on the device as long as the scheduled time is before the current time.
When device get rebooted alarm manager get destroyed.you need to re register the alarm manager after boot complete
add this permission in your manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and broadcast
<receiver
android:name="your package name.MyBroadcast "
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
create a broadcast receiver
public class MyBroadcast extends BroadcastReceiver {
private static final String LOG_TAG = "MyBroadcast ";
public MyBroadcast () {
}
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
String action = intent.getAction();
switch (action) {
case Intent.ACTION_BOOT_COMPLETED:
// Register your alarm manager here
break;
default:
break;
}
}
}
}
Android: Will AlarmManager gets killed after shutdown ?
Ans: YES
will it save the state of the schedule and broadcast straightaway when the user turning back on the device as long as the scheduled time is before the current time ?
Ans: NO
Resolution: Re-Register AlarmManager on BOOT_COMPLETED broadcast
It willl be destroyed after shutdown. Your should implement a RECEIVE_BOOT_COMPLETED broadcast receiver. In this way you will when device is shutdown and in your receiver set your AlarmManager again.

how to use broadcast receiver on receive

i have a project and when i run the application,one service should be active and when the device is turned on,my android service should be active.
The project runs in emulator successfully but in my phone when i turn on the device it doesn't works!
my broadcast receiver :
public class BroadcastReceiverOnTurnedOn extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, MyService.class);
context.startService(startServiceIntent);
}
}
i added :
<receiver android:name="com.dariran.BroadcastReceiverOnTurnedOn">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
to appliation tag on Manifest.xml and
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
You are registering a BroadcastReceiver not a Service. Services will generally run in the background all of the time (if memory and resources permit).
Your broadcast receiver activates only when the device is rebooted - and your emulator "boots" every time you start it up. Your phone does not "boot" when the app is installed.
You should either register for events like "app installed" or else actually implement a service, like here:
http://www.vogella.com/tutorials/AndroidServices/article.html
You need to make sure that once you install the app on device it should be started once by clicking app icon then only boot receiver will receive boot event on subsequent reboots calls.
i undrestand that if i install app in internal storage in works successfully even device rebooted but when i install the app on external storage and then reboot device it not work
i have a project that when run application one service be active and when device be turn on my android service be active. the project run in device's internal memory successfully but when i install it on external memory and reboot my device again don't work!
for first i call my service in first acitivity and it works, but when i reboot my device it doesn't work !
my activity :
public class FirstClass extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.first);
final Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
public void run()
{
startService(new Intent(getApplicationContext(), MyService.class));
startActivity(new Intent(FirstClass.this, MainActivity.class));
finish();
}
},5000);
}
/////////////////////////////////////////////////
}
my broadcast receiver :
public class BroadcastReceiverOnTurnedOn extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, MyService.class);
context.startService(startServiceIntent);
}
}
i added :
<service
android:name="com.dariran.MyService"
android:enabled="true"
android:exported="true" >
</service>
<receiver android:name="com.dariran.BroadcastReceiverOnTurnedOn"
android:enabled="true">
<intent-filter android:priority="1">
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE" />
</intent-filter>
</receiver>to appliation tag on Manifest.xml and
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
i added this code to my service class to put a filter to recognize the external storage but don't work again :(
#Override
public void onStart(Intent intent, int startId) {
try {
IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
BroadcastReceiver mReceiver = new BroadcastReceiverOnTurnedOn();
registerReceiver(mReceiver, filter);
} catch (Exception e) {
}
}

BOOT_COMPLETE and ACTION_SHUTDOWN never call the BroadcastReceiver

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.

ACTION_SCREEN_ON and ACTION_SCREEN_OFF not working?

I'm trying to turn WiFi off when the screen is OFF (locked), and turn it on again when screen is ON (unlocked).
I made a BroadcastReceiver; put in manifest this code:
<receiver android:name="MyIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.USER_PRESENT" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver>
and this is the class MyIntentReceiver:
package org.androidpeople.boot;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyIntentReceiver extends BroadcastReceiver {
// Called when boot completes
public static boolean startup;
#Override
public void onReceive(Context context, Intent intent) {
// Set what activity should launch after boot completes
System.out.println("Intent Action: " + intent.getAction());
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
System.out.println("locked : ACTION_SCREEN_OFF");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
System.out.println("not locked : ACTION_SCREEN_ON ");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
System.out.println("User Unlocking it ");
}
else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
// this to indicate that program is running
// automaticlly not manually by user
startup = true;
System.out.println("Automatic BOOT at StartUp");
Intent startupBootIntent = new Intent(context, LaunchActivity.class);
startupBootIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startupBootIntent);
}
}
}
And the result is - both ACTION_SCREEN_ON
and ACTION_SCREEN_OFF never fired!
USER_PRESENT and BOOT_COMPLETED worked fine but the other did not. I'm using an emulator, not a real device - can this cause the problem?
Any help?
I need to catch the screen on and off in order to enable/disable WiFi
to save battery.
Thanks in advance
To capture the SCREEN_OFF and SCREEN_ON actions (and maybe others) you have to configure the BroadcastReceiver by code, not through the manifest.
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenStateBroadcastReceiver();
registerReceiver(mReceiver, intentFilter);
It's tested and works right.
You cannot catch those intents through XML (I forget why). However, you could use a Service that registers a BroadcastReceiver member in its onStartCommand() and unregisters it in its onDestroy(). This would require the service to be running in the background, constantly or as long as you need it to, so be sure to explore alternative routes.
You could define the BroadcastReceiver in your Service class like so:
private final class ScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
//stuff
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
//other stuff
}
}
}
For a slightly complicated example, but one that shows how the BroadcastReceiver and Service interact see CheckForScreenBugAccelerometerService from my app, ElectricSleep.

Android BroadcastReceiver on startup - keep running when Activity is in Background

I'm monitoring incoming SMSs.
My app is working perfectly with a BroadcastReceiver. However it is working from an Activity and would like to keep the BroadcastReceiver running all the time (and not just when my Activity is running).
How can I achieve this? I've looked through the lifecycle of the BroadcastReceiver but all that is mentioned in the documentation is that the lifecycle is limited to the onReceive method, not the lifecycle of keeping the BroadcastReceiver checking for incoming SMS.
How can I make this persistent?
Thanks
You need to define a receiver in manifest with action name android.intent.action.BOOT_COMPLETED.
<!-- Start the Service if applicable on boot -->
<receiver android:name="com.prac.test.ServiceStarter">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
Make sure also to include the completed boot permission.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Use Service for this to make anything persist. And use receivers to receive Boot Up events to restart the service again if system boots..
Code for Starting Service on boot up. Make Service do your work of checking sms or whatever you want. You need to do your work in MyPersistingService define it your self.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class ServiceStarter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent("com.prac.test.MyPersistingService");
i.setClass(context, MyPersistingService.class);
context.startService(i);
}
}
Service or Boot Completed is not mandatory
In fact, you don't need to implement a Service or register to android.intent.action.BOOT_COMPLETED
Some examples shows how to register/unregister a BroadcastReceiver when activity is created and destroyed. However, this is useful for intents that you expect only when app is opened (for internal communication between Service/Activity for example).
However, in case of a SMS, you want to listen to the intent all the time (and not only when you app is opened).
There's another way
You can create a class which extends BroadcastReceiver and register to desired intents via AndroidManifest.xml. This way, the BroadcastReceiver will be indepedent from your Activity (and will not depend from Activity's Life Cycle)
This way, your BroadcastReceiver will be notified automatically by Android as soon as an SMS arrive even if your app is closed.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest>
...
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<application>
....
<receiver android:name=".MyCustomBroadcastReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
MyCustomBroadcastReceiver.java
public class MyCustomBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent != null) {
String action = intent.getAction();
if(action != null) {
if(action.equals("android.provider.Telephony.SMS_RECEIVED")) {
// DO YOUR STUFF
} else if (action.equals("ANOTHER ACTION")) {
// DO ANOTHER STUFF
}
}
}
}
}
Notes
You can add others intent-filters to AndroidManifest and handle all of them in same BroadcastReceiver.
Start a Service only if you will perform a long task. You just need to display a notification or update some database, just use the code above.
Add Broadcast Reciever in manifest:
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
Create Class BootReciever.java
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
// +++ Do Operation Here +++
}
}
}
Beside #Javanator answer I would like to include a case for Android version of (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) In my case this is working for Android SDK 29 (10)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context,FloatingWindow.class));
} else {
context.startService(new Intent(context, FloatingWindow.class));
}
use this code and also mention the broadcast in Manifest also:
public class BootService extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
Toast.makeText(context, "Boot Completed", Toast.LENGTH_SHORT).show();
//write code here
}
}
}
I just want to mention that in case of some Chinese phone brands (e.g. MI), you need to go to Settings and give autostart permission to your app.
Otherwise the battery optimisation feature will kill your service in background and broadcast receiver will not work.
So you can redirect your user to Settings and ask them to give that permission.

Categories

Resources