android - 创建服务以在后台运行并创建通知
问题描述
好的,所以从很多问题的意义上来说,这是一种重复,例如这个问题:使用服务运行后台并创建通知,我从中获取代码并让它做我需要工作的事情。
但是,现在所有答案都存在问题,他们想使用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" />
运行时,我不再收到任何通知,所以我显然做错了什么,但我不知所措,因为这是我需要做的。
解决方案
我最近遇到了这个问题,我使用广播接收器解决了我的问题。
虽然 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);
}
}
}
这是谷歌的指南通知概述通知概述
这里也是构建通知的官方指南 关于如何创建通知的官方指南。
我希望这有帮助。
推荐阅读
- c - c语言中这两种语法有什么区别?
- websocket - 我可以在 Chromecast 中使用自定义 Websocket 连接吗?
- kotlin - Kotlin/JS:检查 T 是否为枚举
- python - 我需要编码我的列值,然后我需要为 python DataFrame 解码它们
- discord - 来自 discord 服务器的 discord.py bot 中添加/删除新/现有命令(自定义回复)
- blockchain - 错误:使用 web3.js 为 Binance Smart Chain Ethereum Blockchain 发送交易中的“未知帐户”
- swift - 如何调用本机方法并将回调作为参数传递?
- asp.net - 获取 ASPX 链接以继承浏览器当前的 HTTP 方法(HTTP VS HTTPS
- c# - 如何使用 Open XML SDK 以 (-123) 格式显示设置的单元格值?
- node.js - 无法从 vue.js 发送 api 请求来表达