首页 > 解决方案 > setAlarmClock BroadcastReceiver 有时无法达到 onResume

问题描述

我使用 setAlarmClock 创建了一个闹钟应用程序。对于某些人来说,警报无法正常启动。我知道您必须在设备上禁用所有类型的节能模式,否则警报不会触发。但是我有一些罕见的情况,警报按时开始,但在完成我的活动的 onCreate 和 onPostCreate 的所有步骤之前,它有时间间隔。

这可能与我的唤醒锁激活很晚有关。当使用警报事件调用 Broadcastreceiver 时,它会启动我的主要活动。该活动启动一个必须至少运行一次的线程。它检查警报是否应该触发。如果是,那么它会创建一个唤醒锁以保持设备唤醒。

我可以尝试更早地创建唤醒锁,但我看到日志文件甚至没有调用 onResume,只有 onStart。onStart 和 onResume 之间有 5 分钟的间隔。所以没有机会足够早地做到这一点。

我的闹钟和唤醒锁概念有问题吗?在 BroadcastReceiver 中启动唤醒锁并在 Activity 中停止它是否可能/明智?

public class AlarmManagement extends BroadcastReceiver implements Serializable
{
    @Override
    public void onReceive (Context context, Intent intent)
    {
        Intent i = new Intent(context, FullscreenActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        context.startActivity(i);
    }

    public void scheduleSystemAlarmApi21(Context context,long alarmTime, PendingIntent pi) {
        AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent i2=new Intent(context, FullscreenActivity.class);
        PendingIntent pi2=PendingIntent.getActivity(context, 0, i2, 0);
        am.setAlarmClock(new AlarmManager.AlarmClockInfo(alarmTime,pi2),pi);
    }

    public void scheduleSystemAlarm(Context context,int id, long alarmTime) {
        Intent i = new Intent(context, AlarmManagement.class);
        PendingIntent pi = PendingIntent.getBroadcast(context, id, i, 0);

        scheduleSystemAlarmApi21(context,alarmTime,pi);
    }
}

public class FullscreenActivity extends AppCompatActivity {
    Thread thread;

    @Override
    protected void onResume() {
        super.onResume();
        if (threadStopped)
            alarmServiceThread();
    }

    void alarmServiceThread() {
        thread = new Thread() {
            @Override
            public void run() {
            ...
                if (needToStartWakeup(currentTime))
                     startWakeup();
            ...
            }
        }
        thread.start(); 
    }

    PowerManager powerManager;
    PowerManager.WakeLock wake;

    public void startWakeup() {
        powerManager = ((PowerManager) getSystemService(Context.POWER_SERVICE));
        int levelAndFlags=PowerManager.ACQUIRE_CAUSES_WAKEUP;
        levelAndFlags |= PowerManager.SCREEN_BRIGHT_WAKE_LOCK;
        wake = powerManager.newWakeLock( levelAndFlags , WAKE_LOCK_TAG);
        wake.acquire();
    }   
}

标签: androidwakelocksetalarmclock

解决方案


您正在尝试从onReceive方法中的接收器启动一个活动,如果您的应用程序在后台,这是有问题的。

请阅读有关该主题的以下文档:
https ://developer.android.com/guide/components/activities/background-starts

您应该向用户显示通知并打开有关用户操作的活动。


推荐阅读