I would like to run my service when the screen is unlocked and stop it when the screen is locked. I looked into these answers and implemented them. However, when I lock my screen the service stops as required, but when I unlock the screen it doesn't starts again.
The code for to run this service is as follows:
public class PhonePositionService extends Service {
@Override
public void onCreate() {
//ADDED CODE
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new BootCompletedIntentReceiver();
registerReceiver(mReceiver, filter);
{...}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int icon = R.drawable.ic_stat_bright;
startForeground(NOTIFICATION_ID, getCompatNotification(icon));
if (backgroundThread != null) {
backgroundThread.start();
}
return START_STICKY;
}
}
In some other file, my broadcast receiver code is as follows:
public class BootCompletedIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.ACTION_SCREEN_ON.equals(action)) {
// start the service
Intent pushIntent = new Intent(context, PhonePositionService.class);
context.startService(pushIntent);
} else if(Intent.ACTION_SCREEN_OFF.equals(action)) {
// stop the service
Intent pushIntent = new Intent(context, PhonePositionService.class);
context.stopService(pushIntent);
}
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent pushIntent = new Intent(context, PhonePositionService.class);
context.startService(pushIntent);
}
}
}
Then why is it so that when I unlock my phone the service does not start again?
How to remove Screen Lock on your Android phone. Tap Settings > Security > Screen Lock. If prompted, enter your current lock screen code > None > Delete.
After you've tried to unlock your phone multiple times, you'll see "Forgot pattern." Tap Forgot pattern. Enter the Google Account username and password you previously added to your phone. Reset your screen lock. Learn how to set a screen lock.
If an activity previously called startLockTask() , then the activity can call Activity. stopLockTask() to stop lock task mode.
isDeviceLocked to detect if the device is currently locked and requires a PIN, pattern or password to unlock.
First of all its not possible to detect if user has unlocked the phone until you have Admin Privilages. The issue you are facing is because you are stopping the PhonePositionService
using stopService()
when Screen is OFF:
public class BootCompletedIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.ACTION_SCREEN_ON.equals(action)) {
// start the service
Intent pushIntent = new Intent(context, PhonePositionService.class);
context.startService(pushIntent);
} else if(Intent.ACTION_SCREEN_OFF.equals(action)) {
// stop the service
Intent pushIntent = new Intent(context, PhonePositionService.class);
//This will stop the service
context.stopService(pushIntent);
}
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent pushIntent = new Intent(context, PhonePositionService.class);
context.startService(pushIntent);
}
}
}
It would lead to some memory leak since BroadcastReceiver is not unregistered.
It is discouraged to keep service running in foreground for forever since it could lead to (fast) battery drainage.
I would recommend you to find other alternatives. But if your core functionality is impacted and you still want to proceed you can do following work around:
Make BootCompletedIntentReceiver
as inner class for PhonePositionService
. And instead of starting and stopping the service you perform your action directly.
public class PhonePositionService extends Service {
@Override
public void onCreate() {
//ADDED CODE
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new BootCompletedIntentReceiver();
registerReceiver(mReceiver, filter);
...
}
...
private class BootCompletedIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.ACTION_SCREEN_ON.equals(action)) {
//DO action for SCREEN_ON
} else if(Intent.ACTION_SCREEN_OFF.equals(action)) {
//Do action for SCREEN_OFF
}
}
}
}
That's because you are registering your receiver inside your service, which is a component like an activity that has a lifecycle and when it's destroyed your broadcast listener goes with it too. Actually I'm guessing you are leaking your Service here too, because you didn't unregister it which is another problem.
Since API 26 aka Oreo you cannot register you broadcast listener inside AndroidManifest.xml
, If you want to target API 26+ your best bet is to register it in your Application class, but be aware when the system kills your app you will lose your broadcast listener too. However if you use a foreground service the system won't kill your service.
Edit: Here is an example:
import android.app.Application;
import android.content.Intent;
import android.content.IntentFilter;
/**
* @author : [email protected]
* Created on: 2018-04-12
*/
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(new BootCompletedIntentReceiver(), filter);
}
}
Don't forget to set this class inside your manifest file.
<application
android:name=".App"
android:allowBackup="true"
Note you need a foreground service to be run always to not miss the events.
PS: There's another solution which is a bit hacky, target a lower API version and register your listener inside the manifest file.
Looks like targeting a lower API is out of table. It seems google knew some developers would use it to get around this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With