Android 安卓服务赢得';不要从AlarmManager运行

Android 安卓服务赢得';不要从AlarmManager运行,android,service,alarmmanager,Android,Service,Alarmmanager,我在从Alarm manager运行服务时遇到问题 我正在开发一个应用程序,可以在facebook好友的姓名日通知其所有者。这一切都很好,但通知不会出现 我设置了一个AlarmTask,它创建PendingEvent并设置AlarmManager,如下所示: public void run() { // Request to start are service when the alarm date is upon us Intent intent = new Intent

我在从Alarm manager运行服务时遇到问题

我正在开发一个应用程序,可以在facebook好友的姓名日通知其所有者。这一切都很好,但通知不会出现

我设置了一个AlarmTask,它创建PendingEvent并设置AlarmManager,如下所示:

public void run() {


    // Request to start are service when the alarm date is upon us

    Intent intent = new Intent(context, NotifyService.class);
    intent.putExtra(NotifyService.INTENT_NOTIFY, true);
    intent.putExtra("notifyID", ID);
    PendingIntent pendingIntent = PendingIntent.getService(context, ID, intent, 0);

    // Sets an alarm - note this alarm will be lost if the phone is turned off and on again
    am.set(AlarmManager.RTC_WAKEUP, date.getTimeInMillis(), pendingIntent);
}
public class NotificationBroadcastReciever extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
    System.out.println("BROADCAST RECIEVED");

}
  <receiver 
        android:name="cz.cvut.kubispe2.jmeniny.NotificationBroadcastReciever" 
        android:exported="false">
        <intent-filter>
            <action android:name="NotificationBroadcast" />
        </intent-filter>
    </receiver>
该ID对于每个nameday都是特定的

现在,在NotifyService中,我设置了以下各项:

 @Override
public void onCreate() {
    super.onCreate();
    System.out.println("NOTIFICATION SERVICE onCreate()");
    mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    System.out.println("INTENT RECIEVED: " + intent + " " + flags + " " + startId);

    // If this service was started by out AlarmTask intent then we want to show our notification
    if(intent.getBooleanExtra(INTENT_NOTIFY, false)){
        int ID = intent.getIntExtra("notifyID", -1);
        showNotification(ID);
    }
    // We don't care if this service is stopped as we have already delivered our notification
    return START_STICKY;
}
当我启动应用程序时,这两种方法都会执行一次,但是当通知出现时,什么都不会发生

有没有办法测试AlarmManager是否真的执行了PendingEvent? 我应该使用IntentService吗?为什么/如何

非常感谢

我试图将其更改为BroadcastReceiver,如下所示:

public void run() {


    // Request to start are service when the alarm date is upon us

    Intent intent = new Intent(context, NotifyService.class);
    intent.putExtra(NotifyService.INTENT_NOTIFY, true);
    intent.putExtra("notifyID", ID);
    PendingIntent pendingIntent = PendingIntent.getService(context, ID, intent, 0);

    // Sets an alarm - note this alarm will be lost if the phone is turned off and on again
    am.set(AlarmManager.RTC_WAKEUP, date.getTimeInMillis(), pendingIntent);
}
public class NotificationBroadcastReciever extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
    System.out.println("BROADCAST RECIEVED");

}
  <receiver 
        android:name="cz.cvut.kubispe2.jmeniny.NotificationBroadcastReciever" 
        android:exported="false">
        <intent-filter>
            <action android:name="NotificationBroadcast" />
        </intent-filter>
    </receiver>
}

AlarmTask位更改为:

Intent intent = new Intent("NotificationBroadcast");
    intent.putExtra(NotifyService.INTENT_NOTIFY, true);
    intent.putExtra("notifyID", ID);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), ID, intent, 0);
     System.out.println("date for notification: " + date.get(Calendar.DAY_OF_MONTH) + "." + date.get(Calendar.MONTH) + "." + date.get(Calendar.YEAR));
     System.out.println("epoch time in milils: " + date.getTimeInMillis());
    // Sets an alarm - note this alarm will be lost if the phone is turned off and on again
    am.set(AlarmManager.RTC_WAKEUP, date.getTimeInMillis(), pendingIntent);
相关清单部分如下所示:

public void run() {


    // Request to start are service when the alarm date is upon us

    Intent intent = new Intent(context, NotifyService.class);
    intent.putExtra(NotifyService.INTENT_NOTIFY, true);
    intent.putExtra("notifyID", ID);
    PendingIntent pendingIntent = PendingIntent.getService(context, ID, intent, 0);

    // Sets an alarm - note this alarm will be lost if the phone is turned off and on again
    am.set(AlarmManager.RTC_WAKEUP, date.getTimeInMillis(), pendingIntent);
}
public class NotificationBroadcastReciever extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
    System.out.println("BROADCAST RECIEVED");

}
  <receiver 
        android:name="cz.cvut.kubispe2.jmeniny.NotificationBroadcastReciever" 
        android:exported="false">
        <intent-filter>
            <action android:name="NotificationBroadcast" />
        </intent-filter>
    </receiver>


我检查了要设置的日期是否等于历元时间,但仍然没有调用OnReceive方法。

尝试使用应用程序上下文

PendingIntent pendingIntent = PendingIntent.getService(context.getApplicationContext(), ID, intent, 0);
和安卓一起工作。然后您将看到它是否在您的控制台中运行

当我启动应用程序时,这两种方法都会执行一次,但是当通知出现时,什么都不会发生

\u WAKEUP
只有当报警路由到
广播接收器时,才保证唤醒设备,而不是
服务
。只要您所做的非常短(1-2毫秒),您就可以在
广播接收器的
onReceive()
中安全地完成这项工作。您目前在
服务中所做的工作将符合要求

除此之外,使用adb shell dumpsys alarm
确认您的报警已安排在您认为合适的时间

我应该使用IntentService吗


它肯定比常规的
服务
更好,因为您当前的实现中正在泄漏该服务。然而,
\u WAKEUP
限制仍然有效,这就是为什么它有助于缩小差距。不过,同样,由于您目前所做的工作有限,仅使用
广播接收器就足够了。

似乎我最终解决了这个问题,我使用了广播接收器,发现了错误所在-Calendar将月份参数从0到11,而不是我认为的1到12,因为所有其他参数都是正常处理的。所以我只是在5月底发布了一个通知,而不是今天测试的时候


无论如何,感谢大家的帮助,非常感谢。

是否要在am.set()中添加一些延迟?date.getTimeInMillis()+DELAY_IN_Millis我正在尝试在指定的日期启动通知(这里date是一个包含通知信息的日历实例),因此我认为不需要延迟。根据您的描述,服务在应用程序启动时启动,看起来时间是现在还是过去,而不是将来。否则,为什么应用程序启动时服务启动?添加日志消息时,代码看起来正常。这可能是可能的。有没有办法重新启动服务?我希望全年有更多的通知,而不仅仅是一个。当然。服务完成后,可以通过alarm manager在一段时间后安排一个新的PendingEvent,然后关闭它本身。我尝试了应用程序上下文,但它仍然不起作用。此外,我可以在Eclipse日志中看到System.out。我知道它不是很男性化,但我没有太多时间,改变它需要一些时间。不过谢谢。嗯,我真的不知道如何阅读dumpsys日志。这是日志中的一个示例记录,您能帮助我理解它的含义吗?RTC#u WAKEUP#35:Alarm{44e31838 type 0 cz.cvut.kubispe2.jmenny}type=0 when=1369227635942 repeatInterval=0 count=0 operation=PendingIntent{44ea5ac8:PendingIntentRecord{44f34048 cz.cvut.kubispe2.jmenny}@PetrKubišta:您可能希望在较新的设备或模拟器上进行测试。您看到的
时间可能是自Unix时代以来的毫秒。较新的环境应该更像
when=+11h1m38s567ms
显示事件发生前的时/分/秒/毫秒。我尝试按照您的建议将其更改为广播接收器,但功能仍然没有更改。我更新了问题的代码。还有什么建议吗?另外,我确实在为测试设置的dumpsys中找到了警报,它被设置为正确的时间,目的是广播意图,我想应该是这样。@PetrKubišta:我会从
广播接收器
中删除
,删除
android:exported=“false”
(删除
后不需要),并对
挂起内容使用显式
意图
新意图(此,NotificationBroadcastReceiver)
)。下面是一个示例应用程序,演示了这一点,尽管它使用的是
WakefulIntentService
,而不仅仅是
BroadcastReceiver