收到BOOT_COMPLETED广播后如何在BroadcastReceiver中使用AlarmManager?

6

我有一个名为"GroupsTaskAlarmChecker"的服务,在Groups.class活动的onCreate方法中通过AlarmManager每20秒钟被调用:

int seconds = 20;

           Intent myIntent = new Intent(Groups.this, GroupsTaskAlarmChecker.class);
           pendingIntent = PendingIntent.getService(Groups.this, 0, myIntent, 0);

           AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

           Calendar calendar = Calendar.getInstance();
           calendar.setTimeInMillis(System.currentTimeMillis());
           calendar.add(Calendar.SECOND, 10);
           alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), seconds * 1000, pendingIntent);

这很完美。但是我需要在设备启动时执行它。 然后我知道我必须像这样制作AndroidManifest:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 <receiver android:name=".ReceiverBoot">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED">
            <category android:name="android.intent.category.HOME">
        </category></action></intent-filter>
    </receiver>

然后像这样使用 mi broadcastReceiver:
 public class ReceiverBoot extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    int seconds = 20;

        Intent myIntent = new Intent(context, GroupsTaskAlarmChecker.class);
        pendingIntent = PendingIntent.getService(context, 0, myIntent, 0);

        AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.add(Calendar.SECOND, 10);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), seconds * 1000, pendingIntent);

    }
}

但是在这个onReceive方法中,我不知道该如何做与之前相同的事情(使用intent和alarmManager每20秒启动服务)。这行代码存在错误:
 AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

我能否在BroadcastReceiver内使用AlarmManager?

感谢各位,我是一名Android初学者,需要您的帮助。抱歉我的英语不太好 ;)


我在这个问题中忘记写这一行,但在代码中没有 @Jacob。并且接收广播的init工作正常(在测试init活动之前,它是可以的),我只想知道是否可以将我编写的第一段代码写入onReceive方法中。这可行吗? - carlosdiazp
4个回答

4

总结以上的答案和评论:onReceive处理程序接收一个上下文,可以用来访问getSystemService 和ALARM_SERVICE。示例代码:

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        // Start periodic service.
        Calendar cal = Calendar.getInstance();
        Intent srvIntent = new Intent(context, MyService.class);
        PendingIntent pIntent = PendingIntent.getService(context, 0, srvIntent, 0);
        // Use context argument to access service
        AlarmManager alarm = 
                        (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

        // Repeat every 5 seconds
        alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
                                5000, pIntent);
        }
    }
}

使用此代码创建一个新类,并将MyReceiverMyService更改为您实现中的名称。

2

在ReceiverBoot类或BroadcastReceiver类中,均未定义ALARM_SERVICE。

您应该使用Context.ALARM_SERVICE作为getSystemService(String)方法的参数。


2

这里是一些小贡献,我相信能对实现此问题的目标有更全面的了解。

首先:从你的应用程序中在AndroidManifest中配置一个“接收者”。

<receiver
    android:name=".AlarmBroadcastReceiver"
    android:enabled="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

第二步:使用扩展了抽象类BroadcastReceiver的Class,您应该确定Intent Action是否为“BOOT_COMPLETED”。如果满足条件,您可以从您的Class调用一个方法,该方法具有所有构建Alarm的内容。

请参见下面的代码片段。

public class AlarmBroadcastReceiver extends BroadcastReceiver {

    String TAG   = "ALARMS";
    String CLASS = this.getClass().getSimpleName() + ": ";

    Context alarmContext;

    @Override
    public void onReceive(final Context context, Intent intent) {

        Log.d(TAG, CLASS + "[START] onReceive()... ");

        alarmContext = context;

        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            Log.d(TAG, CLASS + "BOOT_COMPLETED action has been received.");
            setAlarmOnBoot();
        }

            Log.d(TAG, CLASS + "[END] onReceive()... ");

    }

    public void setAlarmOnBoot() {

        Log.d(TAG, CLASS + "[START] - setAlarmOnBoot()");

        final long beginAt  = SystemClock.elapsedRealtime() + 60 * 1000;
        final long interval = 300000; // 5 minutes

        try {
            AlarmManager alarm    = (AlarmManager)  alarmContext.getSystemService(Context.ALARM_SERVICE);
            Intent intent         = new Intent(alarmContext, AlarmBroadcastReceiver.class);
            PendingIntent pIntent = PendingIntent.getService(alarmContext, 0, intent, 0);
            alarm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, beginAt, interval, pIntent);
            Log.d(TAG, CLASS + "the Alarm has been configured successfully (5 minutes) of interval.");
        } catch (Exception e) {
            Log.d(TAG, CLASS + "an exception has ocurred while setting the Alarm...");
            e.printStackTrace();
        }  

        Log.d(TAG, CLASS + "[END] - setAlarmOnBoot()");

    }

}

1
非常棒的解决方案,感谢提供完整的代码,对像我这样的初学者来说易于理解。 - Sasa
1
不客气,伙计!我相信这段代码并不难,可以改进我们在这个答案中的解决方案。问候:)。 - ivanleoncz

0

在你的onReceive函数中:

if ("android.intent.action.BOOT_COMPLETED".equals (intent.getAction())){

   //start it again here

}

但我的问题是制作代码:我必须在广播接收器内部创建实例和AlarmManager。而我不知道该如何做:/ - carlosdiazp
如果我在上下文中更改,就不会出现警告和错误,但是在这一行中会出现:AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);在广播接收器内部使用此方法和变量存在问题... 难道我不能在广播接收器内部创建AlarmManager吗? - carlosdiazp
1
我认为您需要一个对象Context来调用getSystemService。 - pakopa
1
尝试从onReceive方法中传递的上下文参数获取SystemService。 - MariusBudin
我不知道该怎么办,因为这行代码出现了“ALARM_SERVICE 无法解析为变量”的错误:AlarmManager alarmManager= (AlarmManager)context.getSystemService(ALARM_SERVICE ); - carlosdiazp
显示剩余2条评论

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