当应用程序关闭时,AlarmManager无法正常工作。为什么会这样?

5

您好, 我在我的Android应用程序中添加了一个计时器,可以在一定时间后发送消息。为此,我添加了一个带有挂起意图的AlarmManager。当我打开应用程序时,一切都按预期工作。它也可以在锁定屏幕上正常工作。但是当我关闭应用程序时,挂起意图不再被激活,给定时间也不会出现任何消息。 这是我的Alarm Manager:

Intent notifyIntent = new Intent(getContext(), MyReceiver.class);
 alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
        pendingIntent = PendingIntent.getBroadcast
                (getContext(), NOTIFICATION_ID, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);

//when the alarm gets activated:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                            alarmManager.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+delta_time2, pendingIntent);

                        }
 else {
                            alarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+delta_time2, pendingIntent);

                        }

在IntentService类中(通知被声明和调用的地方):

Intent notifyIntent = new Intent(this, BigTextMainActivity.class);

      
        notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

        PendingIntent notifyPendingIntent =
                PendingIntent.getActivity(
                        this,
                        0,
                        notifyIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );



       
        Intent snoozeIntent = new Intent(this, BigTextIntentService.class);
        snoozeIntent.setAction(BigTextIntentService.ACTION_SNOOZE);

        PendingIntent snoozePendingIntent = PendingIntent.getService(this, 0, snoozeIntent, 0);
        NotificationCompat.Action snoozeAction =
                new NotificationCompat.Action.Builder(
                        R.drawable.ic_alarm_white_48dp,
                        "Snooze",
                        snoozePendingIntent)
                        .build();

        Intent dismissIntent = new Intent(this, BigTextIntentService.class);
        dismissIntent.setAction(BigTextIntentService.ACTION_DISMISS);

        PendingIntent dismissPendingIntent = PendingIntent.getService(this, 0, dismissIntent, 0);
        NotificationCompat.Action dismissAction =
                new NotificationCompat.Action.Builder(
                        R.drawable.ic_cancel_white_48dp,
                        "Dismiss",
                        dismissPendingIntent)
                        .build();

        NotificationCompat.Builder notificationCompatBuilder =
                new NotificationCompat.Builder(
                        getApplicationContext(), notificationChannelId);

        GlobalNotificationBuilder.setNotificationCompatBuilderInstance(notificationCompatBuilder);

        Notification notification = notificationCompatBuilder
                .setStyle(bigTextStyle)
                .setContentTitle(bigTextStyleReminderAppData.getContentTitle())
                .setContentText(bigTextStyleReminderAppData.getContentText())
                .setSmallIcon(R.drawable.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(
                        getResources(),
                        R.drawable.ic_alarm_white_48dp))
                .setContentIntent(notifyPendingIntent)
                .setDefaults(NotificationCompat.DEFAULT_ALL)
    
                .setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))


                .setCategory(Notification.CATEGORY_REMINDER)

                .setPriority(bigTextStyleReminderAppData.getPriority())

                .setVisibility(bigTextStyleReminderAppData.getChannelLockscreenVisibility())

             
                .addAction(snoozeAction)
                .addAction(dismissAction)

                .build();
//I am not quite shure, if I declared the foregroundservice for the notification at the right place
 
        startForeground(NOTIFICATION_ID, notification);
        mNotificationManagerCompat.notify(NOTIFICATION_ID, notification);
        Vibrator vibrator = (Vibrator) getApplication().getSystemService(Context.VIBRATOR_SERVICE);
        vibrator.vibrate(2 * 1000);

这些是我的权限:

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

感谢您的帮助!(顺便说一下,如果这个问题有什么愚蠢的地方,那是因为我没有真正处理过这个话题,只是想快速为我的应用程序设置一个警报,对此提前道歉)


我在运行Android 10的设备上进行了测试。我检查了logcat并发现消息“java.lang.RuntimeException:无法启动接收器com.example.myapplication.ui.dashboard.MyReceiver:java.lang.IllegalStateException:不允许启动服务Intent {cmp = com.example.myapplication / .ui.dashboard.MyNewIntentService}:应用程序在后台uid UidRecord {1ea9ce7 u0a353 RCVR idle change:idle | uncached procs:1 seq(0,0,0)}”出现。在模拟器设备上(其运行Android 11),一切正常。 - Simba
MyReceiver.onReceive() 的代码只有:"public class MyReceiver extends BroadcastReceiver { public MyReceiver() { }@Override public void onReceive(Context context, Intent intent) { Intent intent1 = new Intent(context, MyNewIntentService.class); context.startService(intent1); }}" - Simba
"你的设备"的制造商是谁? - David Wasser
另外,请不要在评论中放置代码。这样做不利于排版和阅读。请直接编辑您的问题,将代码添加到原始问题中。 - David Wasser
1
我得改正一下:这也不适用于 Android 模拟器。同样的提示消息出现,表明我的应用在后台运行。我需要做什么修改才能让我的应用保持在前台运行? - Simba
显示剩余3条评论
1个回答

1
根据您的评论,看起来警报触发正常,但是在尝试启动您的Service时,您的BroadcastReceiver失败了。最有可能的原因是您的设备对后台处理有额外的限制。一些设备,主要是低端和中国制造的设备,对允许在后台运行的应用程序有限制。如果您的应用程序不在允许的应用程序“白名单”上,Android将不允许启动应用程序的组件在后台运行。
请参见https://developer.android.com/about/versions/oreo/background以了解后台Service的限制,并查看https://stackoverflow.com/a/45482394/769265作为一个示例,其中我讨论了某些制造商限制后台处理的问题。
注意: 由于安卓8及以上版本的限制,您无法启动后台Service,但是您可以将其作为前台Service启动,方法如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService(intent)
} else {
    context.startService(intent)
}

非常感谢,使用ForegroundService现在可以工作了! - Simba
除了我的应用程序在您将其保持打开并且闹钟已过期时总是关闭之外,通知仍然会发送,但应用程序会关闭。如果您还有时间,能否告诉我原因?(在Logcat中发送消息:“android.app.RemoteServiceException:Context.startForegroundService()没有调用Service.startForeground():ServiceRecord {7fae484 u0 com.example.myapplication / .ui.dashboard.MyNewIntentService}”) - Simba
1
错误信息基本上告诉了您问题所在。您需要阅读有关前台服务的文档。如果您的服务作为前台服务运行,则需要调用startForeground()。显然,您还没有将此添加到您的服务代码中。请参见https://developer.android.com/guide/components/foreground-services - David Wasser
现在我有一个问题,通知在短时间内就从屏幕上消失了。我不知道我改变了什么,但你能告诉我为什么会发生这种情况吗? - Simba
不好意思,请查看Logcat或尝试回溯您的更改。 - David Wasser

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