3

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 doesn't seem to work. I've added WAKE_LOCKpermission 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 AlarmManagerto 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();
springrolls
  • 1,331
  • 1
  • 14
  • 40
  • I don't think that it is possible to bypass the screen-lock with an app. – Haphazard Jun 22 '11 at 20:23
  • What do you suggest in that case? Is there a way to let users know that they need to provide input? – springrolls Jun 22 '11 at 20:30
  • You would have to keep the screen on indefinitely. That will, of course, chew threw the battery. – Haphazard Jun 22 '11 at 20:37
  • Works a treat. I didn't have screen lock turned on. I'd almost given up but then stumbled on your post. The problem I had was I was using ACQUIRE_CASE_WAKEUP rather than both as suggested by Aniket. I've voted for both of you. – Bear Jun 27 '11 at 00:26

3 Answers3

4

Normally wakelock doesnt actual turn on the screen. So you should get the wake lock with

ACQUIRE_CAUSES_WAKEUP

as an additional flag.

Trikaldarshiii
  • 11,174
  • 16
  • 67
  • 95
Aniket Awati
  • 1,381
  • 3
  • 13
  • 21
  • You mean replacing `FULL_WAKE_LOCK`with `ACQUIRE_CAUSES_WAKEUP`? It doesn't work. When I wake the device up, my app strangely quits. Did I miss something here? – springrolls Jun 22 '11 at 20:38
  • no not replacing. add that flag like FULL_WAKE_LOCK|ACQUIRE_CAUSES_WAKEUP – Aniket Awati Jun 22 '11 at 20:44
  • Ah, just read several threads related to this. It still doesn't work, though. But I'll read the other threads and give it a try. Thanks! PS: Will accept as an answer when I get it to work ;) – springrolls Jun 22 '11 at 21:06
  • It doesn't completely work at the moment, but at least it gives a blink on the screen. – springrolls Jun 24 '11 at 11:17
  • Your a genius. I struggled with this for hours. I was solely using ACQUIRE_CAUSES_WAKEUP rather than both. Cheers :-) – Bear Jun 27 '11 at 00:26
4

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>
gonzobrains
  • 7,856
  • 14
  • 81
  • 132
piotrpo
  • 12,398
  • 7
  • 42
  • 58
  • 2
    My alarm doesn't fire when the device goes into sleeping mode. Any specific alarm method you would suggest? – springrolls Jun 22 '11 at 20:43
  • I suggest you to use AlarmManager for generate sheduled intents and BroadcastReciever to aquire wake lock and start your application. This approach saves battery life much more than using handler. BTW - in your code I see try to wake up phone - did you set wake lock for keep phone in active state? Otherwise your application do not even run this code when phone is in sleep mode. – piotrpo Jun 22 '11 at 20:56
  • Yes, I've tried that one also, but it doesn't do anything. As I said, the alarm doesn't fire when the device sleeps. Please see the edited post. I attach the code. – springrolls Jun 22 '11 at 22:32
  • Worked a treat for me. I had the alarm manager working anyhow but couldn't wake the device using ACQUITE_CAUSE_WAKEUP. I'd almost given up then saw your example with the OR. Works a treat thanks :-) – Bear Jun 27 '11 at 00:23
0

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();
    }
};
Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
Ugokoli
  • 91
  • 1
  • 4