1

我目前正在使用广播接收器启动服务,该接收器在设备启动后 60 秒触发。此广播接收器触发警报,以便我的服务每 60 秒运行一次。代码如下:

public class ScheduleReceiver extends BroadcastReceiver {
    // Restart service every 60 seconds
    private static final long REPEAT_TIME = 1000 * 60;

    @Override
    public void onReceive(Context context, Intent intent) {
        AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(context, StartServiceReceiver.class);
        PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,PendingIntent.FLAG_CANCEL_CURRENT);

        Calendar cal = Calendar.getInstance();
        // Start 60 seconds after boot completed
        cal.add(Calendar.SECOND, 60);
        // Fetch every 60 seconds
        // InexactRepeating allows Android to optimize the energy consumption
        service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), REPEAT_TIME, pending);
    }
}

以上启动服务如下:

public class StartServiceReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service = new Intent(context, PhotoService.class);
        context.startService(service);
    }
} 

我想以某种方式对其进行修改,以便我的服务在手机屏幕打开时每 60 秒运行一次,而在关闭时每 20 分钟运行一次。

做这个的最好方式是什么 ?当屏幕关闭/打开时,我可以动态修改警报吗?

谢谢你的帮助,

问候,

菲多

4

1 回答 1

1

好的,我已经找到了如何做到这一点,所以我想我会把它放在这里,以防其他人好奇。(总是欢迎更优雅的解决方案):

首先是在我的服务中,我在 OnCreate 中添加了以下内容:

 @Override
 public void onCreate() {
     super.onCreate();
     // REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC
     IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
     filter.addAction(Intent.ACTION_SCREEN_OFF);
     BroadcastReceiver mReceiver = new ScheduleReceiver();
     registerReceiver(mReceiver, filter);
 }

这样做是为了让我的广播接收器可以处理这些事件。显然你不能通过 xml 中的意图过滤器注册这些。

这意味着在创建服务时,它确保可以处理这些额外的系统操作。

然后我将我的广播接收器修改为:

public class ScheduleReceiver extends BroadcastReceiver {
    private static final int ALARM_ID = 909;

    @Override
    public void onReceive(Context context, Intent intent) {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);   
        AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(context, StartServiceReceiver.class);
        PendingIntent pending = PendingIntent.getBroadcast(context, ALARM_ID, i,PendingIntent.FLAG_CANCEL_CURRENT);
        service.cancel(pending);

        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.SECOND, 60); //Delay startup by one minute - This is useful to prevent over utilization of resources at boot

        // Start alarm. Set a long repeat time if the screen is off and a short repeat time if the screen is on
        if (intent.getAction().equals(Intent.ACTION_SCREEN_ON) || intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
            service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 60000, pending);
        }
        else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
            service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 600000, pending);
        }
    }
}

从上面我取消了任何具有相同待处理意图的当前警报,然后在屏幕关闭/打开时设置一个新警报。

这似乎对我有用。一如既往地欢迎任何改进。

于 2013-06-18T14:39:26.837 回答