Android开发:通知don';应用程序关闭时不显示

Android开发:通知don';应用程序关闭时不显示,android,android-studio,android-service,android-notifications,android-alarms,Android,Android Studio,Android Service,Android Notifications,Android Alarms,如何在Android Studio中发送预定通知? 我得到了这个任务:我想在每天选择的某个时间收到通知。当应用程序处于活动状态时,我可以很容易地获取它们,但当它的关闭通知不出现时 我已经尝试过JobScheduler、AlarmManager和WorkManager,但都没有成功。 我的项目至少运行SDK 26(Android Oreo)。目标SDK为30。最后一个代码版本如下所示: AlertReceiver.java public class AlertReceiver extends Br

如何在Android Studio中发送预定通知? 我得到了这个任务:我想在每天选择的某个时间收到通知。当应用程序处于活动状态时,我可以很容易地获取它们,但当它的关闭通知不出现时

我已经尝试过JobScheduler、AlarmManager和WorkManager,但都没有成功。 我的项目至少运行SDK 26(Android Oreo)。目标SDK为30。最后一个代码版本如下所示:

AlertReceiver.java

public class AlertReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        intent = new Intent(context, NotificationService.class);
        context.startService(intent);
    }
}
public class NotificationService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        showNotifications();

        return Service.START_STICKY;
    }

    private void showNotifications(){
        NotificationHelper notificationHelper = new NotificationHelper(getApplicationContext());

        NotificationCompat.Builder nb;

        nb = notificationHelper.getChannelNotification("Title", "Description");
        notificationHelper.getManager().notify(123, nb.build());
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
NotificationService.java

public class AlertReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        intent = new Intent(context, NotificationService.class);
        context.startService(intent);
    }
}
public class NotificationService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        showNotifications();

        return Service.START_STICKY;
    }

    private void showNotifications(){
        NotificationHelper notificationHelper = new NotificationHelper(getApplicationContext());

        NotificationCompat.Builder nb;

        nb = notificationHelper.getChannelNotification("Title", "Description");
        notificationHelper.getManager().notify(123, nb.build());
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
我按如下方式安排警报:

        ...
        Calendar calendar = Calendar.getInstance();

        calendar.set(Calendar.HOUR_OF_DAY, hours);
        calendar.set(Calendar.MINUTE, minutes);

        AlarmManager alarm_manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(this, AlertReceiver.class);
        PendingIntent pending_intent = PendingIntent.getBroadcast(this, 0, intent, 0);

        alarm_manager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pending_intent);
```

这是我在项目中使用的通知(抱歉使用Kotlin语言):


问题是Android 8不允许从后台调用
startService

在此代码中:

public class AlertReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        intent = new Intent(context, NotificationService.class);
        context.startService(intent);
    }
}
您可以从以下位置进行更改:

context.startService(intent);
致:

把这个放在你的舱单上:

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


setexecute
不起名称所示的作用。所有AlarmManager文档都需要仔细阅读,我建议在尝试任何依赖计时的
服务
实现之前,先详细研究“doze”。

为什么要使用
NotificationHelper
?@isthemartin我为我的任务尝试了许多不同的建议。其中一个建议(这是我最后一次尝试)包含了该代码。我还尝试直接从alarm manager调用通知,而无需重新直接调用其他类(如notification helper等)。你在logcat里得到了什么?我希望看到类似的东西:“java.lang.IllegalStateException:不允许启动服务意图,应用程序在后台”。@Elletlar是的,我得到过几次。我在谷歌上搜索了这个问题,并得到了一些建议,比如“使用作业调度程序”来解决这个问题。但作业调度程序和其他方法不一样——作业调度程序在应用程序关闭后无法工作。我在下面更改了您当前的实现。它至少应该让服务在后台运行,但我不知道它是否是您想要的解决方案。如果可能的话,听起来你真正想使用的是Firebase云消息。这对我来说也一样,但你没有使用计划通知吗?您发送到那里的代码只是显示如何使用通知,而不是在应用程序关闭后如何安排通知。它有前台服务通知-有没有办法隐藏它/不显示它?我读了一些关于这件事的建议,其中一些人说这是非法的,因为谷歌的市场政策。恐怕不是。谷歌将其定为强制性,以便用户在后台运行某项服务时始终能够知道。但是,也有一些技巧,比如将其设置为低优先级,并将其设置为私有,这样它就不会出现在锁定屏幕上。如果您的服务只需要非常短的时间运行,那么您可能不需要调用startForeground(),而是在5秒限制到期之前调用stopSelf()。我从来没有尝试过,因为我没有任何这样琐碎的服务。这似乎不明智,但从技术上讲可能是可行的。但总的来说,如果可能的话,最好使用像WorkManager这样的固定解决方案,即使它们通常不适合开发人员在时间方面考虑的原始规范。
setExactAndAllowWhileIdle
setAlarmClock