Android在接收来自待定意图的广播时存在问题

3

我正在使用闹钟管理器在特定时间触发广播。但是在多次测试后,我发现有时广播接收较晚。有时候是5秒,10秒,15秒甚至更久。特别是当设备被锁定时。我已经进行了各种实验。这里是我最不问题的代码。

即使使用唤醒锁,我也不知道我缺少什么。

触发意图

Intent intent = new Intent(this.getApplicationContext(), BroadCastReceiver.class);  
//..... some extras
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), code, intent, 0);
manager.setRepeating(AlarmManager.RTC_WAKEUP, time, 1000 * 120 , pi);

Receiving broadcast

public void onReceive(Context context, Intent intent)
{
       WakeLocker.acquire(context);
       .......
       Intent alarm = new Intent(context, xyz.class);
       alarm.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
       context.startActivity(alarm);
}

在xyz活动的destroy()中释放Wakelock。

自定义WakeLocker类 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.FULL_WAKE_LOCK |
            PowerManager.ACQUIRE_CAUSES_WAKEUP |
            PowerManager.ON_AFTER_RELEASE, "haris");
    wakeLock.acquire();
}

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

}


你正在使用Android Lollipop吗?看一下这个链接:http://developer.android.com/intl/es/training/scheduling/alarms.html - logoff
1个回答

1
根据官方文档,从API 19开始,所有重复的AlarmManager.setRepeating(...)都是不精确的。如果您的应用程序需要精确传递时间,则必须使用一次性精确警报,并根据上述描述每次重新安排。目标SdkVersion早于API 19的旧版应用程序将继续将其所有警报(包括重复警报)视为精确警报。这意味着当您接收到PendingIntent时,必须再次设置它。例如:
public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, Intent intent) {
    switch (intent.getAction()) {
        case AlarmHelper.ACTION_MY_ALARM: 
            doWhatYouNeed();
            long nextTime = getNextAlarmTime();
            AlarmHelper.resetAlarm(nextTime);
            break;
        ...
        }
    }
}

要获取下一个闹钟时间,您可以使用System.currentTimeMillis() + interval或将其传递给意图附加项,第二种方法更准确。而且,我相信您在BroadcastReceiver中不需要WakeLock。
public class AlarmHelper {
    public static void resetAlarm(long time) { 
        Intent intent = createIntent(); 
        PendingIntent pendingIntent = createPendingIntent(intent);
        setAlarmManager(time, pendingIntent); 
    }

    public static void setAlarmManager(long time, PendingIntent pendingIntent) {
        AlarmManager alarmManager = (AlarmManager) MyApp.getAppContext().getSystemService(Context.ALARM_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
        } else {
            alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
        }
    }
}

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