首页 > 解决方案 > 创建服务以在后台运行并创建通知

问题描述

好的,所以从很多问题的意义上来说,这是一种重复,例如这个问题:使用服务运行后台并创建通知,我从中获取代码并让它做我需要工作的事情。

但是,现在所有答案都存在问题,他们想使用WakefulBroadcastReceiver现在已贬值的答案。我知道我现在需要使用 JobService,所以我尝试将上一篇文章中的代码更新为如下所示(部分使用本教程https://www.vogella.com/tutorials/AndroidTaskScheduling/article.html

public class NotificationEventReceiver extends JobService {

    private static final String ACTION_START_NOTIFICATION_SERVICE = "ACTION_START_NOTIFICATION_SERVICE";
    private static final String ACTION_DELETE_NOTIFICATION = "ACTION_DELETE_NOTIFICATION";
    private static final int NOTIFICATIONS_INTERVAL = 1;

    public static void setupAlarm(Context context) {
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        PendingIntent alarmIntent = getStartPendingIntent(context);
        alarmManager.setRepeating(AlarmManager.RTC,
                getTriggerAt(new Date()),
                NOTIFICATIONS_INTERVAL * AlarmManager.INTERVAL_DAY,
                alarmIntent);
    }

    private static long getTriggerAt(Date now) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        //calendar.add(Calendar.HOUR, NOTIFICATIONS_INTERVAL_IN_HOURS);
        calendar.set(Calendar.HOUR_OF_DAY, 5);
        calendar.set(Calendar.MINUTE, 0);
        return calendar.getTimeInMillis();
    }

    @Override
    public boolean onStartJob(JobParameters params) {
        Intent service = new Intent(getApplicationContext(), NotificationIntentService.class);
        getApplicationContext().startService(service);
        setupAlarm(getApplicationContext()); // reschedule the job
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return true;
    }

    private static PendingIntent getStartPendingIntent(Context context) {
        Intent intent = new Intent(context, NotificationEventReceiver.class);
        intent.setAction(ACTION_START_NOTIFICATION_SERVICE);
        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    public static PendingIntent getDeleteIntent(Context context) {
        Intent intent = new Intent(context, NotificationEventReceiver.class);
        intent.setAction(ACTION_DELETE_NOTIFICATION);
        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }
}

然后在 Android Manifest

    <service
        android:name=".NotificationEventReceiver"
        android:label="Notification Service"
        android:permission="android.permission.BIND_JOB_SERVICE" />

运行时,我不再收到任何通知,所以我显然做错了什么,但我不知所措,因为这是我需要做的。

标签: androidservice

解决方案


我最近遇到了这个问题,我使用广播接收器解决了我的问题。

虽然 WakefulBroadcastReceiver 已被弃用,但它的父类并未被弃用。

Intent intent = new Intent(context, ClassReminderReceiver.class);

  PendingIntent pendingIntent = PendingIntent.getBroadcast(
     context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
  AlarmManager alarmManager = (AlarmManager) 
     context.getSystemService(Context.ALARM_SERVICE);
  alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), 
        AlarmManager.INTERVAL_DAY, pendingIntent);

我正在使用警报管理器 setRepeating() 和 RTC_WAKEUP 请参阅适当的警报类型指南以了解适当的警报类型

另外,请参阅下面的链接以查看有关警报的最佳做法。 报警最佳实践

您需要在清单中声明您的广播接收器

<receiver
        android:name=".ClassReminderReceiver"
        android:enabled="true"
        android:exported="true" />

这是广播接收器类

 public class ClassReminderReceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
      ClassReminderNotification.notify(context);
     }
  }

你说你想创建一个通知,但正如@Chuong Le Van 提到的,我看不到你在代码中定义通知的位置。

下面是 ClassNotification 类

class ClassReminderNotification {

static void notify(Context context) {
    createNotificationChannel(context);
    // Create an explicit intent for an Activity in your app
    Intent intent = new Intent(context, YourActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);


    NotificationCompat.Builder builder = new NotificationCompat.Builder(context, 
          "class_reminder")
            .setSmallIcon(R.drawable.ic_school_black_24dp)
            .setContentTitle("Your Notification Title")
            .setContentText("Your Text")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            // Set the intent that will fire when the user taps the notification
            .setContentIntent(pendingIntent)
            .setAutoCancel(true);

    NotificationManagerCompat notificationManager = 
    NotificationManagerCompat.from(context);

    // notificationId is a unique int for each notification that you must define
    int notificationId = 1;
    notificationManager.notify(notificationId, builder.build());

}

private static void createNotificationChannel(Context context) {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is new and not in the support library
    String CHANNEL_ID = "class_reminder";
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = context.getString(R.string.channel_name);
        String description = context.getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, 
          importance);
        channel.setDescription(description);
        // Register the channel with the system; you can't change the importance
        // or other notification behaviors after this
        NotificationManager notificationManager = 
           context.getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
        }
    }
}

这是谷歌的指南通知概述通知概述

这里也是构建通知的官方指南 关于如何创建通知的官方指南。

我希望这有帮助。


推荐阅读