Héctor Ortiz
Héctor Ortiz

Reputation: 267

AlarmManager when the phone is turned off - ANDROID

I'm doing an alarm System but i've a problem when the phone is turned off.. The alarm doesn't work..

I'm setting de alarm as follows:

    public void doIntents(Context context, long milis, Tratam trat){
    cal=Calendar.getInstance();
    alarmManager = (AlarmManager) context.getSystemService(Service.ALARM_SERVICE);

    cal.setTimeInMillis(milis);
    Intent intent = new Intent(context, OnAlarmReceiver.class);


    pendingIntent = PendingIntent.getBroadcast(context, trat.getId(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
    alarmManager.set(AlarmManager.RTC_WAKEUP,milis ,pendingIntent);

}

The Alarm works Ok when the phone is turned on..

What can I do?

Thank you!

Upvotes: 7

Views: 11115

Answers (3)

lucky
lucky

Reputation: 11

you can use something like the following:

private val ACTION_SET_POWEROFF_ALARM = "org.codeaurora.poweroffalarm.action.SET_ALARM"
private val ACTION_CANCEL_POWEROFF_ALARM = "org.codeaurora.poweroffalarm.action.CANCEL_ALARM"
private val POWER_OFF_ALARM_PACKAGE = "com.qualcomm.qti.poweroffalarm"
private val TIME = "time"

private fun setPowerOffAlarm(context: Context, timeInMillis: Long) {
    val intent = Intent(ACTION_SET_POWEROFF_ALARM)
    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
    intent.setPackage(POWER_OFF_ALARM_PACKAGE)
    val rightNow = Calendar.getInstance()

    rightNow.set(Calendar.SECOND, 0);
    rightNow.set(Calendar.MILLISECOND, 0);

    intent.putExtra(TIME, rightNow.timeInMillis + timeInMillis)

    context.sendBroadcast(intent)
    Log.i { "PWR STATE: pwr off Alarm is set" }
}

This is copied from the Android source code of the Default Clock App located at: DeskClock/src/com/android/deskclock/alarms/AlarmStateManager.java

Search for this function in the source code and see how they do it similarly. We basically send a broadcast to the com.qualcomm.qti.poweroffalarm package which will then create a power off alarm as you would do in the DeskClock app.

If we look at the decompiled source code of the com.qualcomm.qti.poweroffalarm we see that the manifest states something like the following:

    <receiver android:name="com.qualcomm.qti.poweroffalarm.PowerOffAlarmDialog$ShutDownReceiver" android:permission="org.codeaurora.permission.POWER_OFF_ALARM">
        <intent-filter>
            <action android:name="org.codeaurora.poweroffalarm.action.ALARM_POWER_OFF"/>
        </intent-filter>
    </receiver>

This means we also require this permission for the qcom package to accept the broadcasted intent. We therefore set it in our AndroidManifest.xml:

<uses-permission android:name="org.codeaurora.permission.POWER_OFF_ALARM" />

And then also request it:

    private val PERMISSION_POWER_OFF_ALARM = "org.codeaurora.permission.POWER_OFF_ALARM"

private val CODE_FOR_ALARM_PERMISSION = 1

        if (ContextCompat.checkSelfPermission(this, PERMISSION_POWER_OFF_ALARM)
        != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
            arrayOf(PERMISSION_POWER_OFF_ALARM), CODE_FOR_ALARM_PERMISSION);
    }

Finally we want to call the SetAlarm function. We specify the time in milliseconds from now until we want the alarm to ring. For example in two minutes:

 setPowerOffAlarm(context, 120000)

Upvotes: 1

Edy Aguirre
Edy Aguirre

Reputation: 2143

Alarms are cleared when the phone turned off and rebooted, but you can start your alarm using BroadcastReceiver that can receive the BOOT_COMPLETED

In Manifest.xml:

 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  <application ...>
 <receiver android:name="com.example.receiver.AlarmMonitorReceiver"
              android:enabled="true"
              android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
</application>

Java:

public class AlarmMonitorReceiver extends BroadcastReceiver{
  public void onReceive(Context context,Intent intent) { 
    if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
      AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 
      Intent intentAlarm = new Intent(context, ExampleReceiver.class); 
      PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentAlarm, 0);
      Calendar time = Calendar.getInstance();
      time.setTimeInMillis(System.currentTimeMillis());
      time.add(Calendar.SECOND, 10);
      alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),10000,pendingIntent);         
    }  

  }

}

Upvotes: 4

LuxuryMode
LuxuryMode

Reputation: 33741

Yea, the problem is your app isn't running when the phone restarts. You'll need to register a BroadcastReceiver that can receive the BOOT_COMPLETED message so it receives a message when the phone reboots. Then in the BroadcastReceiver you can either reschedule those alarms or whatever. But I don't think there's anything you can do about making your alarm trigger when the phone is off..(e.g. making the phone turn on)

<receiver android:name="MyBootReceiver"
        android:enabled="true"
        android:exported="true"
        android:label="BootReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>

        </intent-filter>
    </receiver>

Upvotes: 8

Related Questions