Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 608
Héctor Ortiz Avatar asked Sep 02 '12 05:09

Héctor Ortiz


3 Answers

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>
like image 102
LuxuryMode Avatar answered Nov 02 '22 18:11

LuxuryMode


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);         
    }  

  }

}

like image 4
Edy Aguirre Avatar answered Nov 02 '22 16:11

Edy Aguirre


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)
like image 1
lucky Avatar answered Nov 02 '22 16:11

lucky