I am trying to figure out how to wake and unlock the phone with a service. I have been referring to this post but, I can't figure out why it isn't working. This is the code that I have so far:
public class WakephoneActivity extends Activity {
BroadcastReceiver mReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Log.v(TAG, "Screen OFF onReceive()");
screenOFFHandler.sendEmptyMessageDelayed(0, 2000);
}
};
}
private Handler screenOFFHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// do something
// wake up phone
// Log.i(TAG, "ake up the phone and disable keyguard");
PowerManager powerManager = (PowerManager) WakephoneActivity.this
.getSystemService(Context.POWER_SERVICE);
long l = SystemClock.uptimeMillis();
powerManager.userActivity(l, false);// false will bring the screen
// back as bright as it was, true - will dim it
}
};
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
registerReceiver(mReceiver, filter);
// Log.i(TAG, "broadcast receiver registered!");
}
}
I have added the code in the manifest as well. Any ideas?
Use this code below in your service.
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock((PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "YourServie");
mWakeLock.acquire();
[...]
mWakeLock.release();
If you want to unlock the screen as well, register a receiver in your service that monitors if the screen is turned on/off and if it is turned off and you want to unlock the phone, start an activity with this code in onCreate:
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
this.finish();
return;
I know, this is a rather dirty, but as far as I know, there is no other way of unlocking the lockscreen (and this will only work if there are no passwords etc set, so it must be the normal "slide to unlock" screen).
And don't forget to add android.permission.WAKE_LOCK ;-)
/edit: I just saw you are already using an Activity. If you have one and don't need the service at all, just put this code into the activity.
For the service to be allways active you need to have this permission on manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Another thing you need to do is to adquire a WakeLock. Without it the service will end passed some time. You can do it like this:
getApplicationContext();
PowerManager pm = (PowerManager)getApplicationContext().getSystemService(Context.POWER_SERVICE);
WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
wl.acquire();
You might need to change PowerManager.PARTIAL_WAKE_LOCK to the one that you need. You can see info about that here.
There is WakefulBroadcastReceiver which does this for you. Example use:
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// This is the Intent to deliver to our service.
Intent service = new Intent(context, SimpleWakefulService.class);
// Start the service, keeping the device awake while it is launching.
Log.i("SimpleWakefulReceiver", "Starting service # " + SystemClock.elapsedRealtime());
startWakefulService(context, service);
}
}
After completing the action in the service, call SimpleWakefulReceiver.completeWakefulIntent(intent) to release the wake lock.
(as #Force already gave you the details about the wakeLock, they need not be repeated here ;-)
Mind that the class is deprecated from api level 26.1.0, reference here
Related
When Android Wear goes to sleep mode (screen dimmed), some parts of my code are not executed. I use Timer in background service to trigger some actions, such as sending data from wear to mobile, but the data is not sent. It is sent when I tap the screen to wake it up.
I also try to use Timer trigger a notification with vibration when the screen is off, but it doesn't appear until I tap the screen.
In debug mode (either Bluetooth or USB), data sending and notification work fine.
I suspect this is because when Android Wear is in sleep mode, its CPU works at minimum level because the Timer is still running, but not for GoogleApiClient, IntentService, or Notification.
I have tried many ways to wake CPU up such as AlarmManager, PowerManager, Wakelock, but it did not work for Android Wear.
Anyone has encountered this problem? What is the solution?
I'm using PowerManger to wakeup my wearable device each time i receive message from handled device.
Do not forget to release PowerManager.WakeLock
public abstract class WatchFaceActivity extends Activity {
private PowerManager.WakeLock mWakeLock;
private Handler mWakeLockHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_clock_watch_face);
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "MyWakelockTag");
mWakeLockHandler = new Handler();
IntentFilter messageFilter = new IntentFilter("message-forwarded-from-data-layer");
MessageReceiver messageReceiver = new MessageReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(messageReceiver, messageFilter);
}
public class MessageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (!mWakeLock.isHeld()) {
mWakeLock.acquire();
}
mWakeLockHandler.removeCallbacksAndMessages(null);
mWakeLockHandler.postDelayed(mReleaseRunnable, 5000);
}
}
private Runnable mReleaseRunnable = new Runnable() {
#Override
public void run() {
mWakeLock.release();
}
};
#Override
protected void onDestroy() {
super.onDestroy();
mWakeLockHandler.removeCallbacksAndMessages(null);
mWakeLock.release();
}
}
And allow WAKE_UP permission in your Manifest.
<uses-permission android:name="android.permission.WAKE_LOCK" />
You should use AlarmManager along with WakefulBroadcastReceiver and startWakefulService(). See this working solution.
You may find answers for your further questions in chat history on that post here.This is the only solution worked for our app.
#SeaDog is successful in making http calls when device in deep sleep mode with this solution. Try it.
I need to force the android device to stay alive while the application is running. There any way to do this ?
I read here : Is there a way to force an android device to stay awake? about this, I tried to do this but probably I don't know to use correctly a Service.
This is the code I use :
public class WakeLockService extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "My Tag");
wl.acquire();
}
#Override
public void onDestroy() {
wl.release();
}
and in the first Activity of my Application, I put this :
Intent s = new Intent(this, WakeLockService.class);
startService(s);
Is it correct what I'm doing? Anyone can help me to do this ?
Thanks in advance.
If you want the device to stay awake while it displays an activity of your app, you have to set the flag FLAG_KEEP_SCREEN_ON when creating the activity:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); // Unlock the device if locked
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); // Turn screen on if off
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // Keep screen on
.....
}
Add the permission WAKE_LOCK in the manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
EDIT After seeing your last comment: yes, you need a service: note that the device will go to sleep anyway, but your service can continue to run if you make it clear to the user (you have to display a notification) and declare it STICKY:
public class yourservice extends Service
{
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//The intent to launch when the user clicks the expanded notification
/////////////////////////////////////////////////////////////////////
Intent forPendingIntent = new Intent(this, si.test.app.activities.activity.class);
forPendingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, forPendingIntent, 0);
Notification notification = new Notification(R.drawable.icon, "testapp", System.currentTimeMillis());
notification.setLatestEventInfo(this, "testApp", "testApp is running", pendIntent);
notification.flags |= Notification.FLAG_NO_CLEAR;
startForeground (R.string.app_name, notification);
return START_STICKY;
}
...
}
In my application I have, for example, a syncronization server->mobile and this syncronization can run more then 5 minutes. I want to force the device to not enter into stand-by, to see when the syncronization process is finished
The synchronization operation should be managed by some Android component, such as a service. That component can manage a WakeLock. Do not create some separate component purely for the WakeLock, as that other component has nothing whatsoever to do with your synchronization work.
For example, if your synchronization is being conducted via an IntentService, you could use my WakefulIntentService to keep the device awake while the work in onHandleIntent() is being conducted.
I am trying to turn on and off the display after a certain action happens (Lets just worry about turning the screen off for now). From what I understand from wake lock, this is what I have:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
When I read other posts on stackoverflow and else where, they seem to tell me that PARTIAL_WAKE_LOCK will turn the screen off. But if I read the SDK it says that it will only allow the screen to be turned off. I think this isn't right.
There are two choices for turning the screen off:
PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);
// Choice 1
manager.goToSleep(int amountOfTime);
// Choice 2
PowerManager.WakeLock wl = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Your Tag");
wl.acquire();
wl.release();
You will probably need this permission too:
<uses-permission android:name="android.permission.WAKE_LOCK" />
UPDATE:
Try this method; android turns off the screen once the light level is low enough.
WindowManager.LayoutParams params = getWindow().getAttributes();
params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);
The following is copied from SDK document.
If you want to keep screen on, I think SCREEN_BRIGHT_WAKE_LOCK is enough.
Flag Value CPU Screen Keyboard
PARTIAL_WAKE_LOCK On* Off Off
SCREEN_DIM_WAKE_LOCK On Dim Off
SCREEN_BRIGHT_WAKE_LOCK On Bright Off
FULL_WAKE_LOCK On Bright Bright
For me those methods didn't work. So I used other scenario (not trivial) to make my screen off.
Android has 2 flags that responsible to be awake:
Display --> Screen TimeOut
Application --> Development --> Stay awake while charging check box.
I used followed flow:
1st of all save your previous configuration, for example screen timeout was 1 min and Stay awake while charging checked.
After, I uncheck Stay awake while charging and set screen timeout to minimal time.
I register to broadcast receiver service to get event from android that screen turned off.
When I got event on screen off, I set previous configuration to default: screen timeout was 1 min and Stay awake while charging checked.
Unregister receiver
After 15 sec. device sleeps
Here is snippets of code:
BroadcastReceiver
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
/**
* Catch Screen On/Off
* */
public class BroadcastReceiverScreenListener extends BroadcastReceiver{
private BroadCastListenerCallBackItf mBroadCastListenerCallBack = null;
public BroadcastReceiverScreenListener(
BroadCastListenerCallBackItf broadCastListenerCallBack) {
this.mBroadCastListenerCallBack = broadCastListenerCallBack;
}
#Override
public void onReceive(Context arg0, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
mBroadCastListenerCallBack.broadCastListenerCallBack__ScreenOff_onResponse();
}
}
}
Interface used as callback
public interface BroadCastListenerCallBackItf {
public void broadCastListenerCallBack__ScreenOff_onResponse();
}
2 methods from main class:
....
AndroidSynchronize mSync = new AndroidSynchronize();
....
public void turnScreenOff(int wait){
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadCastListenerCallBackItf broadCastListenerCallBack = this;
BroadcastReceiver mReceiver = new BroadcastReceiverScreenListener(broadCastListenerCallBack);
m_context.registerReceiver(mReceiver, filter);
//set Development --> disable STAY_ON_WHILE_PLUGGED_IN
Settings.System.putInt(
m_context.getContentResolver(),
Settings.System.STAY_ON_WHILE_PLUGGED_IN,
0 );
// take current screen off time
int defTimeOut = Settings.System.getInt(m_context.getContentResolver(),
Settings.System.SCREEN_OFF_TIMEOUT, 3000);
// set 15 sec
Settings.System.putInt(m_context.getContentResolver(),
Settings.System.SCREEN_OFF_TIMEOUT, 15000);
// wait 200 sec till get response from BroadcastReceiver on Screen Off
mSync.doWait(wait*1000);
// set previous settings
Settings.System.putInt(m_context.getContentResolver(),
Settings.System.SCREEN_OFF_TIMEOUT, defTimeOut);
// switch back previous state
Settings.System.putInt(
m_context.getContentResolver(),
Settings.System.STAY_ON_WHILE_PLUGGED_IN,
BatteryManager.BATTERY_PLUGGED_USB);
m_context.unregisterReceiver(mReceiver);
}
public void broadCastListenerCallBack__ScreenOff_onResponse() {
mSync.doNotify();
}
....
AndroidSynchronize class
public class AndroidSynchronize {
public void doWait(long l){
synchronized(this){
try {
this.wait(l);
} catch(InterruptedException e) {
}
}
}
public void doNotify() {
synchronized(this) {
this.notify();
}
}
public void doWait() {
synchronized(this){
try {
this.wait();
} catch(InterruptedException e) {
}
}
}
}
[EDIT]
You need to register permission:
android.permission.WRITE_SETTINGS
Per this link, You can also turn the screen off like this:
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, 1000);
1000 is in milliseconds which means 1 second, you can replace it with any value as desired.
Needed permission:
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
try -
wakeLock.acquire(1000); // specify the time , it dims out and eventually turns off.
im receiving an intent in broadcast receiver and then i start service to do more work. now what if the device is sleep and this happen, do i have to get Wakelock (AlarmManger?), and why do i need it?
does my service will stop running if the device goes to sleep without getting a wakelock.
now what if the device is sleep and this happen, do i have to get Wakelock (AlarmManger?), and why do i need it?
If the device is asleep to begin with, you will not be "receiving an intent in broadcast receiver", because the device is asleep.
do i have to get Wakelock (AlarmManger?), and why do i need it?
You don't "need it", unless you want to ensure the device stays running while you complete some work.
does my service will stop running if the device goes to sleep without getting a wakelock.
Yes.
Looks like the Android's native WakefulBroadcastReceiver would be a perfect solution for you. Need to extend this rather than the regular BroadcastReceiver and start the service in the onReceive() in the "wakeful" manner:
startWakefulService(context, service);
and signal your work is done in the service's onHandleIntent(), calling
MyWakefulReceiver.completeWakefulIntent(intent);
public class WakeLockManager extends BroadcastReceiver {
private static WakeLock mWakeLock;
private String LCLT;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Consts.WAKELOCK_INTENT)) {
Log.v("wakelock", "GOT THE wakelock INTENT");
boolean on = intent.getExtras().getBoolean("on");
if (mWakeLock == null) {
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"Breeze WakeLock");
}
if (on) {
if (!mWakeLock.isHeld()) {
mWakeLock.acquire();
Log.v("wakelock", "acquiring wakelock");
}
} else {
if (mWakeLock.isHeld()) {
Log.v("wakelock", "releasing wakelock");
mWakeLock.release();
}
mWakeLock = null;
}
}
}
}
look at the above code ..put it in a separate class file and and in your manifest define it for some custom intent .... now that this class will respond to a custom intent ...just broadcast that intent and you can turn the wakelock on or off in your entire app since the wakelock is static..like this :
public void setWakeup(boolean status) {
Intent wakelock_Intent = new Intent(CUSTOM_INTENT);
wakelock_Intent.putExtra("on", status);
this.sendBroadcast(wakelock_Intent);
}
the above would be defined in your alarmmanager code so it schedules a call
I m looking for the best practice to implement a service for logging gps- or other sensor-values periodically (every 10-60 sec). The service should deal with the standby mode, when the phone goes asleep.
Any help (pseudo-code or tutorials) is very much appreciated!
It looks like it is impossible to let the orientation sensors work constantly for hours even though the device may fall asleep (refer to http://code.google.com/p/android/issues/detail?id=3708#makechanges
As soon as the display goes off, the sensors will do alike... :(
I now implemented a wakelock (needs permission)
<uses-permission android:name="android.permission.WAKE_LOCK" />
in conjunction with a timer and a broadcastreciever that will turn the display back on again. This is of course crazy for battery life but I found no other way so far.
This is my onCreate method in the service:
#Override
public void onCreate() {
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
CONTEXT = this;
PowerManager pm = (PowerManager) CONTEXT.getSystemService(Context.POWER_SERVICE);
this.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "my tag");
mWakeLock.acquire();
Log.d(TAG, "Wakelock acquired");
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
this the onStart method of the service:
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onStart");
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Log.d(TAG, "Screen is on");
} else {
Log.d(TAG, "Screen is off");
Timer timer = new Timer("DigitalClock");
timer.schedule(new TimerTask() {
#Override
public void run() {
Log.d(TAG,"Waiting 1 sec for switching the screen back on again...");
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
"my tag");
mWakeLock.acquire();
}
}, 1000);
mWakeLock.acquire();
}
}
and this is the BroadcastReceiver class:
public class ScreenReceiver extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
Intent i = new Intent(context, MyService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
This workaround will also do with a device UN-plugged from the debugger via USB (I first had an issue with this).
Please let me know if you have a better solution, or if there is fix in 2.3. Thanx!
Here's a link to a tutorial on how to use Android Services. LINK
Here's a link to a tutorial on how to read data from sensors. LINK