Search code examples
javaandroidalarmmanagerwakelock

Android AlarmManager RTC_WAKEUP not waking CPU


I'm working on alarm app, that notofies the user several times at different moments. Everything is working perfect, except that when I disconnect phone from PC and turn off the screen (by pressing power button for example), the alarms do not go off. But when I manually wake up phone by pressing button, then the alarm suddenly go off.

This happens on Android 4.4, API 19 (KITKAT). On Android 2.3 phone correctly wakes up every time.

Please help me. How to make it work on all Android versions?

MainActivity.java:

    Button b = (Button) findViewById(R.id.button);
    b.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            setAlarm(0);
            setAlarm(1);
            setAlarm(4);
            setAlarm(7);
        }});

public void setAlarm(int index) {
    long tim = new GregorianCalendar().getTimeInMillis() + 5 * 1000 * (index+1);
    Intent intent = new Intent(this, MyReceiver.class);
    intent.setData(Uri.parse(Integer.toString( index )));
    PendingIntent pi = PendingIntent.getBroadcast(this, index, intent, PendingIntent.FLAG_ONE_SHOT);
    AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        am.setExact(AlarmManager.RTC_WAKEUP, tim, pi);
    } else {
        am.set(AlarmManager.RTC_WAKEUP, tim, pi);
    }
}

MyReceiver.java:

public void onReceive(Context context, Intent intent) {
    Intent mIntent = new Intent(context, NotifActivity.class);
    mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(mIntent);
}

NotifActivity.java:

boolean done;
public PowerManager.WakeLock mWakeLock;

@Override
protected void onCreate(Bundle savedInstanceState) {
    done = false;
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP |
            PowerManager.ON_AFTER_RELEASE, "TEST_LOCK");
    mWakeLock.acquire();

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_notif);

    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);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);

    final Vibrator vibe = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    vibe.vibrate(100);

    done = true;
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (done) {
        try {
            if (mWakeLock != null)
                mWakeLock.release();
        } catch (Exception e) {
            //e.printStackTrace();
        }
    }
}

AndroidManifest.xml:

 <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity 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=".MyReceiver"
            android:enabled="true"
            android:exported="false"
            android:process=":remote"/>

        <activity android:name=".NotifActivity"></activity>
    </application>

Solution

  • OK, problem solved. What a stupid mistake... I was using SONY XPERIA phone for debbugging. It had some strange power saving mode "STAMINA" turned on, which prevents phone from waking up by any app that don't come from SONY.

    So the code is correct. The only thing that you may add is another wakelock in the onReceive method.