广播接收器的onReceiver方法未被调用,AlarmManager

12

我正在构建一款打车应用程序,我需要每20秒获取出租车的当前位置。

我定义了一个AlarmManager,并需要每20秒重复一次。但它没有按照规律重复。相反,它在233秒后重复了一次。我做错了什么?

我的HomeScreen有一个内部类OnAlarmReceiver,在HomeScreen的onCreate中调用了AlarmManager。

    AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent i = new Intent(this, OnAlarmReceiver.class);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.SECOND, 20);
    mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
            cal.getTimeInMillis(), God.UPDATE_PENDING_INTERVAL, pi);

HomeScreen中的内部类

public class OnAlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // PullPendingRequests.acquireStaticLock(context);
        Toast.makeText(context, "Don't panik but your time is up!!!!.", Toast.LENGTH_LONG)
                .show();
        Log.d("Taxeeta:PullPendingRequets", "CallService Location");
        context.startService(new Intent(context, PullPendingRequests.class));
    }
}

我的AndroidManifest文件中有

    <service
        android:name="com.taxeeta.support.PullPendingRequests"
        android:enabled="true"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:theme="@android:style/Theme.Light.NoTitleBar" />

    <receiver android:name=".com.taxeeta.HomeScreen.OnAlarmReceiver" />
</application>

adb shell dumpsys alarm 的输出结果

 com.taxeeta
    51471ms running, 5248 wakeups
    5248 alarms: flg=0x4 cmp=com.taxeeta/.HomeScreen$OnAlarmReceiver

adb shell dumpsys alarm | grep taxeeta 的输出结果:

 ELAPSED_WAKEUP #7: Alarm{409303b0 type 2 com.taxeeta}
    operation=PendingIntent{408ba2d8: PendingIntentRecord{40887be8 com.taxeeta broadcastIntent}}
 com.taxeeta
    5248 alarms: flg=0x4 cmp=com.taxeeta/.HomeScreen$OnAlarmReceiver
5个回答

14
为了修复这个问题,我删除了内部类OnAlarmReceiver并修复了androidmanifest.xml文件。
    <receiver
        android:name="com.taxeeta.support.OnAlarmReceiver"
        android:exported="true" >
        <intent-filter>
            <action android:name="android.intent.action.NOTIFY" />
        </intent-filter>
    </receiver>

8
如果上面的答案对您不起作用,那么有另一种方法可以在AlarmManager触发过期警报时接收任何回调。您只需要检查这个方法:在实例化PendingIntent时发送错误的Intent。例如,您想要在其中一个接收器上接收onReceive调用,但是您通过getActivitygetService实例化了PendingIntent,而您实际上想要的是getReceiver
创建PendingIntent实例时,有许多方法可供选择(getServicegetActivitygetReceivergetForegroundService):
如果您希望Activity成为意图的接收器,则:
PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_*);

如果您想将BroadcastReceiver作为意图的接收器:

PendingIntent.getReceiver(this, 0, intent, PendingIntent.FLAG_*);

如果您想要一个前台Service,则需要将意图的接收者设置为:
PendingIntent.getForegroundService(this, 0, intent, PendingIntent.FLAG_*);

如果您想要一个 Service,则需要为意图的接收方指定:
PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_*);

同时确保你的意图(intents)指向了正确的类别(比如创建针对Activity,Service等的意图)。如果你错误地传递了类别参数,那么将不会收到任何回调。

Intent intent = new Intent(this, MyReceiver.class); // You wanted receiver

// PendingIntent was created in such a way 
// you wanted this to be received by an activity. 
// you will not receive any call if you set it up like this.
PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_*); 

我也在这里发布了类似的答案

希望对你有所帮助。


1
使用AlarmManager和Receiver时,需要使用PendingIntent.getBroadcast(...),它就像魔法一样工作;) - homerun

1
这段代码对我很有用,确保你已经在Android清单文件中添加了接收器。
AlarmManager service = (AlarmManager) context
            .getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, OnAlarmReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
                         PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
// Start 20 seconds after boot completed
cal.add(Calendar.SECOND, 20);
//
// Fetch every 20 seconds
// InexactRepeating allows Android to optimize the energy consumption
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                       cal.getTimeInMillis(), 1000*20, pending);

1
不行,不起作用。OnAlarmReceiver,onReceive也没有被调用。 - Siddharth
1
同样的问题,闹钟管理器对我也没有用。我尝试了所有的建议,不确定该怎么办,很困扰。 - JPM
那是很久以前的事了,甚至不确定我当时需要它做什么。抱歉,伙计,如果我记得的话,我会发布出来的。 - JPM

1
上述解决方案对我没有用。 此外,通过代码动态注册可以解决问题:
Intent intent = new Intent();
intent.setAction("android.intent.action.NOTIFY");

//Register the receiver
context.registerReceiver(new OnAlarmReceiver(),new IntentFilter());

0

对于仍然卡住的人 - 确保您的广播接收器不会在后台崩溃。一定要检查您的LogCat!


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