简体   繁体   English

AlarmManager从不在AlarmReceiver / BroadcastReceiver中调用onReceive

[英]AlarmManager never calling onReceive in AlarmReceiver/BroadcastReceiver

I still cannot get my AlarmReceiver class' onReceive method to fire. 我仍然无法触发我的AlarmReceiver类'onReceive方法。 Does anything stick out as wrong with this implementation? 这个实现有什么问题吗?

All this is supposed to do is wait a certain period of time (preferably 6 days) and then pop up a notification. 所有这一切应该是等待一段时间(最好是6天),然后弹出一个通知。 (Can you believe there isn't a built in system for this? crontab anyone!?) (你能相信没有内置系统吗?crontab任何人!?)

MyActivity and BootReceiver both set up an alarm under the necessary conditions. MyActivity和BootReceiver都在必要条件下设置了警报。 AlarmService kicks out a notification. AlarmService启动通知。 And AlarmReceiver is supposed to catch the alarm and kick off AlarmService, but it has never caught that broadcast, and won't no matter what I do. 并且AlarmReceiver 应该捕获警报并启动AlarmService,但它从未捕获过该广播,并且不管我做什么都不会。

Oh, and I've been testing on my Droid X, 2.3.4. 哦,我一直在测试我的Droid X,2.3.4。 Project being built against API 8. 项目是针对API 8构建的。

PS Most of this has been adapted from http://android-in-practice.googlecode.com/svn/trunk/ch02/DealDroidWithService/ PS大部分内容改编自http://android-in-practice.googlecode.com/svn/trunk/ch02/DealDroidWithService/

------------ MyActivity.java ------------ ------------ MyActivity.java ------------

public class MyActivity extends Activity implements SensorEventListener {

    private void setupAlarm() {
        Log.i(TAG, "Setting up alarm...");
        AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, new Intent(context, AlarmReceiver.class), 0);

        // Get alarm trigger time from prefs
        Log.i(TAG, "Getting alarm trigger time from prefs...");
        SharedPreferences mPrefs2 = PreferenceManager.getDefaultSharedPreferences(context);
        long trigger = SocUtil.getLongFromPrefs(mPrefs2, AlarmConst.PREFS_TRIGGER);
        Log.i(TAG, "Trigger from prefs: " + trigger + " (" + new Date(trigger).toString() + ").");

        // If alarm trigger is not set
        if(trigger == new Long(-1).longValue()) {
            // Set it
            trigger = new Date().getTime() + NOTIFY_DELAY_MILLIS;
            SocUtil.saveLongToPrefs(mPrefs2, AlarmConst.PREFS_TRIGGER, trigger);
            Log.i(TAG, "Trigger changed to: " + trigger + " (" + new Date(trigger).toString() + ").");

            // And schedule the alarm
            alarmMgr.set(AlarmManager.RTC, trigger, pendingIntent);
            Log.i(TAG, "Alarm scheduled.");
        }
        // If it is already set
        else {
            // Nothing to schedule. BootReceiver takes care of rescheduling it after a reboot
        }
    }

}

------------ AlarmService.java ------------ ------------ AlarmService.java ------------

public class AlarmService extends IntentService {

   public AlarmService() {
      super("AlarmService");
   }

   @Override
   public void onHandleIntent(Intent intent) {
      Log.i(AlarmConst.TAG, "AlarmService invoked.");
      this.sendNotification(this);
   }

   private void sendNotification(Context context) {
      Log.i(AlarmConst.TAG, "Sending notification...");
      Intent notificationIntent = new Intent(context, Splash.class);
      PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

      NotificationManager notificationMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
      Notification notification = new Notification(R.drawable.icon, "Test1", System.currentTimeMillis());
      notification.setLatestEventInfo(context, "Test2", "Test3", contentIntent);
      notificationMgr.notify(0, notification);
   }
}

------------ AlarmReceiver.java ------------ ------------ AlarmReceiver.java ------------

public class AlarmReceiver extends BroadcastReceiver {

   // onReceive must be very quick and not block, so it just fires up a Service
   @Override
   public void onReceive(Context context, Intent intent) {
      Log.i(AlarmConst.TAG, "AlarmReceiver invoked, starting AlarmService in background.");
      context.startService(new Intent(context, AlarmService.class));
   }
}

------------ BootReceiver.java ------------ (to restore wiped alarms, because stuff I schedule with the OS isn't important enough to stick around through a reboot -_-) ------------ BootReceiver.java ------------(恢复已擦除的警报,因为我在操作系统中安排的内容不够重要,无法通过重启 -_-)

public class BootReceiver extends BroadcastReceiver {

   @Override
   public void onReceive(Context context, Intent intent) {
      Log.i(AlarmConst.TAG, "BootReceiver invoked, configuring AlarmManager...");


      Log.i(AlarmConst.TAG, "Setting up alarm...");
      AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
      PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, new Intent(context, AlarmReceiver.class), 0);

      // Get alarm trigger time from prefs
      Log.i(AlarmConst.TAG, "Getting alarm trigger time from prefs...");
      SharedPreferences mPrefs2 = PreferenceManager.getDefaultSharedPreferences(context);
      long trigger = SocUtil.getLongFromPrefs(mPrefs2, AlarmConst.PREFS_TRIGGER);
      Log.i(AlarmConst.TAG, "Trigger from prefs: " + trigger + " (" + new Date(trigger).toString() + ").");

      // If trigger exists in prefs
      if(trigger != new Long(-1).longValue()) {
          alarmMgr.set(AlarmManager.RTC, trigger, pendingIntent);
          Log.i(AlarmConst.TAG, "Alarm scheduled.");
      }
   }
}

------------ Manifest ------------ ------------清单------------

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <activity
        android:name=".MyActivity"
        android:label="@string/app_name" >
    </activity>

<receiver android:name="com.domain.app.BootReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

<receiver android:name="com.domain.app.AlarmReceiver"></receiver>

    <service android:name="com.domain.app.AlarmService"></service>

Here is some code I recently used to make a notification every hour (This is in my MainActivity): 以下是我最近用于每小时发出通知的一些代码(这是我的MainActivity中):

AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent Notifyintent = new Intent(context, Notify.class);
PendingIntent Notifysender = PendingIntent.getBroadcast(this, 0, Notifyintent, PendingIntent.FLAG_UPDATE_CURRENT);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 3600000, Notifysender);

Then in Notify.java 然后在Notify.java中

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class Notify extends BroadcastReceiver{

    @SuppressWarnings("deprecation")
    @Override
    public void onReceive(Context context, Intent intent) {
          NotificationManager myNotificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
          Notification notification = new Notification(R.drawable.ic_launcher, "Update Device", 0);
          Intent notificationIntent = new Intent(context, MainActivity.class);
          PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
          notification.setLatestEventInfo(context, "Device CheckIn", "Please run Device CheckIn", contentIntent);
          notification.flags |= Notification.FLAG_HIGH_PRIORITY;
          myNotificationManager.notify(0, notification);
    }
}

Then lastly in the AndroidManifest.xml I have this in between the tags: 最后在AndroidManifest.xml中我在标签之间有这个:

<receiver android:name=".Notify" android:exported="true">
         <intent-filter>
                <action android:name="android.intent.action.NOTIFY" />
            </intent-filter>
</receiver>

I have the main code that I know works at the office, feel free to email me for more help as I faced the same issues. 我知道我在办公室工作的主要代码,随时向我发送电子邮件以获得更多帮助,因为我遇到了同样的问题。

email: sbrichards at mit.edu 电子邮件:mit.edu的sbrichards

You must register your AlarmReceiver with an intent Action. 您必须使用intent Action注册AlarmReceiver。 like below. 如下。 and the action string must be same to what action you are broadcasting by sendBroadcast() method.. 并且动作字符串必须与sendBroadcast()方法广播的动作相同。

like sendBroadcast(new Intent(""com.intent.action.SOMEACTION.XYZ"")); sendBroadcast(new Intent(""com.intent.action.SOMEACTION.XYZ""));

    <receiver android:name="com.domain.app.AlarmReceiver">

<intent-filter>
                <action android:name="com.intent.action.SOMEACTION.XYZ" />
            </intent-filter>
</receiver>

I solved this by not even using a BroadcastReceiver . 我甚至没有使用BroadcastReceiver解决了这个问题。 Every single one of the tutorials and posts I read about how to do notification alarms (and that was A LOT) said to use a BroadcastReceiver , but apparently I don't understand something, or that's a load of crap. 我读到的关于如何进行通知警报(也就是A LOT)的每一篇教程和帖子都说使用了BroadcastReceiver ,但显然我听不懂东西,或者说这是一堆垃圾。

Now I just have the AlarmManager set an alarm with an Intent that goes directly to a new Activity I created. 现在我让AlarmManager设置一个警报,其中一个Intent直接转到我创建的新Activity I still use the BootReceiver to reset that alarm after a reboot. 我仍然使用BootReceiver在重启后重置该警报。

This lets the notification work in-app, out-of-app, with the app process killed, and after a reboot. 这使得通知可以在应用程序内部,应用程序外进行,应用程序进程被终止,并且在重新启动后。

Thanks to the other commenters for your time. 感谢您的其他评论者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM