Reputation: 97
I need to create an application to run a method at a specific time. However, AlarmManager never works, and I do not understand why. I set up the alarm to run at 11.54, but it always runs when the application starts and never runs at the expected time. If you know what is the problem, please comment. Thank you very much.
This is my Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.spr.timemanager">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.TimeManager"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.ALARM"/>
</intent-filter>
</receiver>
</application>
</manifest>
And this is my MainActivity.java
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 11);
calendar.set(Calendar.MINUTE, 54);
Intent intent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0 , intent, 0);
time = (calendar.getTimeInMillis() - (calendar.getTimeInMillis() % 60000));
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Log.e("time", String.valueOf(time));
time = System.currentTimeMillis();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,time,pendingIntent);}
else {
alarmManager.setExact(AlarmManager.RTC_WAKEUP,time,pendingIntent);}
}else {
alarmManager.set(AlarmManager.RTC_WAKEUP,time,pendingIntent);
}
My AlarmReceiver
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Vibrator vibrator = (Vibrator) context.getSystemService(context.VIBRATOR_SERVICE);
vibrator.vibrate(4000);
Log.e("System time", String.valueOf(System.currentTimeMillis()));
}
}
This is my logcat
2022-05-25 11:52:27.820 16914-16914/com.spr.timemanager E/time: 1653468840000
2022-05-25 11:52:28.103 16914-16914/com.spr.timemanager E/System time: 1653468748103
P/S: if I change these alarmManager.set() code into setreapeating(), it always fires when the application starts and 5 seconds afterward, no matter how I set it.
Upvotes: 0
Views: 45
Reputation: 19273
you are calculating your time
(when alarm should fire)
time = (calendar.getTimeInMillis() - (calendar.getTimeInMillis() % 60000));
but at very last after logging you are overriding this variable with
time = System.currentTimeMillis();
just before if
cascade. remove this line, looks unnecessary
btw. HOUR_OF_DAY
is in <0 to 23>
, so if you want 11:54 exacly then you should set 10
. you can also set seconds and millis with Calendar.SECOND
and Calendar.MILLISECOND
to 0
instead of dividing with %
and then your time = calendar.getTimeInMillis()
ps. you should add some alarm-in-past-setting protection (add a day?)
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 10); // remember set -1 in here!!
calendar.set(Calendar.MINUTE, 54);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// ensuring next day
while (calendar.getTimeInMillis() < System.currentTimeMillis()) {
calendar.add(Calendar.DATE, 1);
}
time = calendar.getTimeInMillis();
Log.e("time", String.valueOf(time));
Intent intent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0 , intent, 0);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
... set alarm for time
Upvotes: 1