安卓如何设置精确重复闹钟?

5

我正在构建一个闹钟应用程序,其中将有一个精确重复的闹钟。

由于在 Android 中,对于重复提供的只是带有可能延迟75%所选间隔的不精确闹钟,因此我尝试制作精确闹钟,触发后再次设置自身。 只要保持屏幕开启,这种类型的闹钟就可以完美工作。 但是,一旦屏幕进入睡眠状态,闹钟第一次可以正常工作,但以编程方式设置的第二个闹钟会有延迟,就好像我使用了不精确方法。

作为替代方案,我考虑制作一个InexactRepeating闹钟,每分钟触发一次以检查是否“到时间”。 这样,我的闹钟将具有2分钟的不精确间隔,这是可以接受的。 但我不确定它会对手机电池造成多大负担。

大家有什么想法吗?

这是我对精确闹钟的尝试:

AlarmManager.java

 public static void setAlarm(Context context){
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);

        //SET BROADCAST RECEIVER WHICH WILL BE THE ONE TO LISTEN FOR THE ALARM SIGNAL
        Intent intent = new Intent(context, AlarmTriggerBroadcastReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 22222, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        //SETING THE ALARM
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 300000, pendingIntent);
        } else {
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 300000, pendingIntent);
        } 

    }

AlarmTriggerBroadcastReceiver.java

public class AlarmTriggerBroadcastReceiver extends BroadcastReceiver {

    private final static String TAG_ALARM_TRIGGER_BROADCAST = "ALARM_TRIGGER_BROADCAST";

    @Override
    public void onReceive(Context context, Intent intent) {
        //WAKE UP DEVICE
        WakeLocker.acquire(context);

            //LAUNCH PAGE
            Intent intent1 = new Intent();
            intent1.setClassName(context.getPackageName(), SomeActivity.class.getName());
            intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent1);


            Toast.makeText(context, "TOAST ALARM", Toast.LENGTH_LONG).show();
        };

        //SET NEW ALARM
        AlarmManagerActivity.setAlarm(context);
        WakeLocker.release();   

    }

}

WakeLocker.java

//WAKES UP DEVICE IF PHONE'S SCREEN LOCKED
public abstract class WakeLocker {
    private static PowerManager.WakeLock wakeLock;

    public static void acquire(Context ctx) {
        //if (wakeLock != null) wakeLock.release();

        PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK |
                PowerManager.ACQUIRE_CAUSES_WAKEUP |
                PowerManager.ON_AFTER_RELEASE, "myapp:WAKE_LOCK_TAG");
        wakeLock.acquire();
    }

    public static void release() {
        if (wakeLock != null) wakeLock.release(); wakeLock = null;
    }
}

清单

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

  <receiver
            android:name=".Alarm.AlarmTriggerBroadcastReceiver"
            android:process=":remote">

            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"></action>
            </intent-filter>
            <intent-filter android:priority="1">
                <action android:name="my.app.here.ALARM_RECIEVED" />
            </intent-filter>
        </receiver>

各位程序员,你们好?


setExactWhileInIdle,无论如何都要使用推送通知。 - hemen
@notTdar,这就是我正在使用的。但它不起作用。 - Oleksandr Firsov
1个回答

5

你尝试过使用WorkManager而不是使用广播接收器吗?详情请参见这里。演示应用程序在此


不错。看起来很有前途! 我会尽快测试这个,谢谢! - Oleksandr Firsov
好的。我已经进行了15分钟WorkerAlarm和1分钟弹性窗口的一些测试,效果非常好。今晚将进行30分钟的测试,然后再汇报结果。 - Oleksandr Firsov
好的,请点赞以便其他人在工作中也能受益。 - Dennis Murage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接