I am trying to create a function to wake up my phone and unlock. For this I was using the getWindow() function, which do not work in BroadcastReceivers. How do I fix this? Any help would be appreciated!
public class ShakeToWake extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock mWakeLock = pm.newWakeLock((PowerManager.ACQUIRE_CAUSES_WAKEUP), "TapApp");
mWakeLock.acquire();
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mWakeLock.release();
}
}
Broadcast receivers don't need wakelocks- there's an implicit one in the Android framework, otherwise the OS couldn't call the BroadcastReceiver in the first place in order to run it and take a wakelock. Activities and Services are what need wakelocks. And Activities have windows, so it all works out.
Related
I am a newbie in Android.
I wanna create a programing related to Wakelock.
When wakelock is acquired(it's as same as Alarm), an popup Activity is created and it enters HomeScreen directly.
How can I do it?
In manifest
<uses-permission android:name="android.permission.WAKE_LOCK" />
If your app includes a broadcast receiver that uses a service to do some work, you can manage your wake lock through a WakefulBroadcastReceiver, as described in Using a WakefulBroadcastReceiver. This is the preferred approach. If your app doesn't follow that pattern, here is how you set a wake lock directly:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyWakelockTag");
wakeLock.acquire();
Using WakefulBroadcastReceiver
In manifest:
<receiver android:name=".MyWakefulReceiver"></receiver>
The following code starts MyIntentService with the method startWakefulService()
public class MyWakefulReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Start the service, keeping the device awake while the service is
// launching. This is the Intent to deliver to the service.
Intent service = new Intent(context, MyIntentService.class);
startWakefulService(context, service);
}
}
Referance :
https://developer.android.com/training/scheduling/wakelock.html
What's the right way to acquire a wakelock in a BroadcastReceiver, and hold it until an activity is started - this is what I have:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager)
context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"tag");
wl.acquire();
Intent intent = new Intent(context, MyActivity.class);
context.startActivity(intent);
}
}
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PowerManager pm = (PowerManager)
context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"tag");
wl.release();
// I want to keep the screen on now.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
}
// The broadcastreceiver is fired via AlarmManager:
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, someTime, pendingIntent);
Additionally, what happens if the broadcast receiver gets fired simultaneously - I assume the wakelock manager is synchronized and this won't be a problem?
Thank you
Once a lock is acquired you have to keep this instance of lock and release exactly that instance once work is done. You can check source code of WakefulBroadcastReceiver.java to get better idea of how this can be implemented and used.
Additionally, it's not a very good idea to start activity from a broadcast receiver. Imagine you play a game and in the middle of a level your phone starts an activity. I don't think you will like it. You should rather post a notification that user can open activity later, when user wants it.
I've using alarm manager to call an activity and I'm using the wake locker class onRecive() to wake the phone and then calling WakeLocker.release() after the Activity is over but the screen still stays on...
Receive.class:
public class MyScheduledReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
WakeLocker.acquire(context);
Activity.class
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
WakeLocker.release();
finish();
}
I've put it in the onPause(), onStop() everywhere... the thing won't release and the screen won't turn off automatically after my app closes...
Make sure you request permission
<uses-permission android:name="android.permission.WAKE_LOCK" />
You are starting the wakelock in a broadcastreceiver and stopping it in an activity.
You are referencing 2 different instances of a wakelock. You should start the activity from the onreceive and in onresume acquire the wake lock, then still release in the onpause if that is where you want it to happen.
You should never start anything that is supposed to be around for awhile within a broadcastreceiver, because the receiver is destroyed as soon as possible.
Try this
PowerManager pm;
PowerManager.WakeLock wakeLock;
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
"x2_wakelook");
wakeLock.acquire();
wakeLock.release();
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
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