Wake the device up when app prompts user
I'm using handler to repeatedly prompt user for an input every e.g. 5 minutes. When the device goes into sleeping mode and screen is locked, how can I wake the device up when my app prompts user for input? I've tried this but it do开发者_JS百科esn't seem to work. I've added WAKE_LOCK
permission in the manifest.
class BtHandler extends Handler {
private PowerManager pm;
private WakeLock wl;
@Override
public void handleMessage(Message msg) {
pm = (PowerManager)FixedNode.this.getSystemService(Context.POWER_SERVICE);
if (!pm.isScreenOn()) {
wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "TAG");
wl.acquire();
}
FixedNode.this.setAlwaysDiscoverable();
wl.release();
}
}
Any ideas?
Edit: Using AlarmManager
to broadcast custom intent.
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(300);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
WakeLock wl = null;
if (!pm.isScreenOn()) {
KeyguardLock kl = km.newKeyguardLock("TAG");
kl.disableKeyguard();
wl = pm.newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
wl.acquire();
}
Toast.makeText(context, "Alarm worked", Toast.LENGTH_LONG).show();
wl.release();
}
};
mFilter = new IntentFilter(ACTION_NAME);
Intent mIntent = new Intent(ACTION_NAME);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, mIntent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (120 * 1000), pendingIntent);
Toast.makeText(this, "Alarm set", Toast.LENGTH_LONG).show();
Normally wakelock
doesnt actual turn on the screen. So you should get the wake lock with
ACQUIRE_CAUSES_WAKEUP
as an additional flag.
Take a look for AlarmManager class http://developer.android.com/reference/android/app/AlarmManager.html It's something like "cron"
Ok, here is a piece of working code - first comes the activity class:
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
public class MainActivity extends Activity {
private WakeLock wl;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//acquire wake lock
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP|PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "TAG");
wl.acquire();
// schedule alarm
Intent i = new Intent();
i.setAction(WakeReciever.WAKE_INTENT);
PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, i, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 120000,
pIntent);
}
@Override
protected void onPause() {
wl.release();
super.onPause();
}
}
Next comes BroadcastReceiver:
package com.test;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.Context;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
public class WakeReciever extends BroadcastReceiver {
public static final String WAKE_INTENT = "com.test.WAKE";
/**
* @see android.content.BroadcastReceiver#onReceive(Context,Intent)
*/
@Override
public void onReceive(Context context, Intent intent) {
//acquire wake lock
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
wl.acquire();
//start activity
Intent i = new Intent();
i.setClassName("com.test", "com.test.MainActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
wl.release();
}
}
And finally don't forget about the manifest file:
<?xml version="1.0" encoding="UTF-8"?>
<manifest android:versionCode="1" android:versionName="1.0"
package="com.test" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="8"/>
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:label="@string/app_name" android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver android:name=".WakeReciever" android:enabled="true">
<intent-filter>
<action android:name="com.test.WAKE"></action>
</intent-filter>
</receiver>
</application>
</manifest>
From what I see, you are releasing the wake lock immediately after acquiring it. That's why it gives the impression of not working. Remove it and put it somewhere else outside the method that acquires it.
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(300);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
WakeLock wl = null;
if (!pm.isScreenOn()) {
KeyguardLock kl = km.newKeyguardLock("TAG");
kl.disableKeyguard();
wl = pm.newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
wl.acquire();
}
Toast.makeText(context, "Alarm worked", Toast.LENGTH_LONG).show();
}
};
精彩评论