Android 8/9通知时间表 [英] Android 8/9 Notification scheduling
问题描述
我尝试将通知安排在特定的日期和时间,但是在大多数设备上,通知似乎都没有显示.在android 9/8之前,我已经使用了AlarmManager,它非常容易使用并且可以正常工作,但是android的最后2个版本已经改变了这个...(感谢google使一切变得更容易...)
因此,这是我用来安排通知的代码.我正在使用 OneTimeWorkRequest
I have tried to schedule notifications for a specific date and time, but on majority of devices it seems that the notifications are not showing up. Before android 9/8 I have used AlarmManager which was pretty easy to use and it worked but the last 2 versions of android have changed this...(thanks google for making everything easier...)
So, here is my code that I use to schedule the notification. I'm using OneTimeWorkRequest
tag = new AlertsManager(this).getCarId(nrInmatriculare);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Data inputData = new Data.Builder().putString("type", alarmType).putString("nrInmatriculare", nrInmatriculare).build();
OneTimeWorkRequest notificationWork = new OneTimeWorkRequest.Builder(NotifyWorker.class)
.setInitialDelay(calculateDelay(when), TimeUnit.MILLISECONDS)
.setInputData(inputData)
.addTag(String.valueOf(tag))
.build();
WorkManager.getInstance().enqueue(notificationWork);
}
else {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, when, (24 * 60 * 60 * 1000), pendingIntent);
}
然后我用来显示通知的类是:
Then the class that I'm using to show the notification is this:
public class NotifyWorker extends Worker {
public NotifyWorker(@NonNull Context context, @NonNull WorkerParameters params) {
super(context, params);
}
@NonNull
@Override
public Worker.Result doWork() {
// Method to trigger an instant notification
new NotificationIntentService().showNotification(getInputData().getString("type"),getInputData().getString("nrInmatriculare"), getApplicationContext());
return Worker.Result.SUCCESS;
// (Returning RETRY tells WorkManager to try this task again
// later; FAILURE says not to try again.)
}
}
还有这个:
and this one :
public class NotificationIntentService extends IntentService {
final Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
int alarmId = 0;
public NotificationIntentService() {
super("NotificationIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
showNotification(intent);
}
//show notification with workmanager
public void showNotification(String type, String nrInmatriculare, Context context){
try
{
if (!TextUtils.isEmpty(type) && !TextUtils.isEmpty(nrInmatriculare)) {
AlertsManager alertsManager = new AlertsManager(context);
Notifications notification = alertsManager.getAlertForCar(nrInmatriculare);
String text ="";
Calendar endDate = null;
String date = notification.EndDate.get(Calendar.YEAR) + "-" + (notification.EndDate.get(Calendar.MONTH)/10==0 ? "0"+(notification.EndDate.get(Calendar.MONTH)+1) : (notification.EndDate.get(Calendar.MONTH))+1) + "-" + (notification.EndDate.get(Calendar.DAY_OF_MONTH)/10==0 ? "0"+notification.EndDate.get(Calendar.DAY_OF_MONTH) : notification.EndDate.get(Calendar.DAY_OF_MONTH));
text = context.getString(R.string.notificationText).toString().replace("#type#", type.toUpperCase()).replace("#nrInmatriculare#", nrInmatriculare).replace("#date#", date ).replace("#days#", String.valueOf(new Utils().getDateDifferenceInDays(Calendar.getInstance(), notification.EndDate)));
alarmId = alertsManager.getCarId(nrInmatriculare);
endDate = (Calendar)notification.EndDate.clone();
if (Calendar.getInstance().getTimeInMillis() > endDate.getTimeInMillis()){ //current time is after the end date (somehow the alarm is fired)
}
else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//define the importance level of the notification
int importance = NotificationManager.IMPORTANCE_HIGH;
//build the actual notification channel, giving it a unique ID and name
NotificationChannel channel = new NotificationChannel("AppName", "AppName", importance);
//we can optionally add a description for the channel
String description = "A channel which shows notifications about events at Masina";
channel.setDescription(description);
//we can optionally set notification LED colour
channel.setLightColor(Color.MAGENTA);
// Register the channel with the system
NotificationManager notificationManager = (NotificationManager)context.
getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
//---------
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "AppName");
builder.setContentTitle(context.getString(R.string.app_name));
builder.setContentText(text);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setAutoCancel(true);
builder.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS);
builder.setLights(Color.CYAN, 1000, 2000);
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
builder.setSound(notificationSound);
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(text));
Intent notifyIntent = null;
if (type.equals("CarteDeIdentitate") || type.equals("PermisDeConducere"))
notifyIntent = new Intent(context, PersonalDataActivity.class);
else
notifyIntent = new Intent(context, DetailActivity.class);
notifyIntent.putExtra("car", new SharedPreference(context).getCarDetailString(nrInmatriculare));
// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntentWithParentStack(notifyIntent);
//PendingIntent pendingIntent = PendingIntent.getActivity(context, alarmId, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(alarmId, PendingIntent.FLAG_UPDATE_CURRENT);
//to be able to launch your activity from the notification
builder.setContentIntent(pendingIntent);
//trigger the notification
NotificationManagerCompat notificationAlert = NotificationManagerCompat.from(context);
notificationManager.notify(alarmId, builder.build());
}
}
}
else
{
Log.d("here","No extra");
}
}
catch(Exception ex)
{
Log.d("here","Error");
}
}
}
我在做什么错?有一种最佳,更有效的方法吗?
what am I doing wrong? there is a best and more efficient way of doing this?
我想看一个有关如何将通知安排到特定日期和时间的示例,该示例确实有效.
I would like to see an example about how to schedule a notification to a specific date + time, that really works.
推荐答案
这是我在我的一个项目中使用的一种可行的实现.
Here is one working implementation that I've used in one of my project.
将此添加到您的 build.gradle(应用程序)
(由于它位于Kotlin中)
Add this to your build.gradle (app)
(Since it's in Kotlin)
//android-jet pack
implementation 'android.arch.work:work-runtime-ktx:1.0.1'
创建方法 scheduleNotification
.传递您的必要数据
Create a method scheduleNotification
.
Pass your necessary data
fun scheduleNotification(timeDelay: Long, tag: String, body: String) {
val data = Data.Builder().putString("body", body)
val work = OneTimeWorkRequestBuilder<NotificationSchedule>()
.setInitialDelay(timeDelay, TimeUnit.MILLISECONDS)
.setConstraints(Constraints.Builder().setTriggerContentMaxDelay(Constant.ONE_SECOND, TimeUnit.MILLISECONDS).build()) // API Level 24
.setInputData(data.build())
.addTag(tag)
.build()
WorkManager.getInstance().enqueue(work)
}
NotificationSchedule
类
class NotificationSchedule (var context: Context, var params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
val data = params.inputData
val title = "Title"
val body = data.getString("body")
TriggerNotification(context, title, body)
return Result.success()
}
}
TriggerNotification
类.根据您的需要自定义此类
TriggerNotification
Class. Customize this class according to your need
class TriggerNotification(context: Context, title: String, body: String) {
init {
sendNotification(context, title, body)
}
private fun createNotificationChannel(context: Context, name: String, description: String): String {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
val chanelId = UUID.randomUUID().toString()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val importance = NotificationManager.IMPORTANCE_HIGH
val channel = NotificationChannel(chanelId, name, importance)
channel.enableLights(true)
channel.enableVibration(true)
channel.description = description
channel.lightColor = Color.BLUE
channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
val notificationManager = context.getSystemService(NotificationManager::class.java)
notificationManager?.createNotificationChannel(channel)
}
return chanelId
}
private fun sendNotification(context: Context, title: String, body: String) {
val notificationManager = NotificationManagerCompat.from(context)
val mBuilder = NotificationCompat.Builder(context, createNotificationChannel(context, title, body))
val notificationId = (System.currentTimeMillis() and 0xfffffff).toInt()
mBuilder.setDefaults(Notification.DEFAULT_ALL)
.setTicker("Hearty365")
.setContentTitle(title)
.setContentText(body)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSmallIcon(R.drawable.icon)
.setContentInfo("Content Info")
.setAutoCancel(true)
notificationManager.notify(notificationId, mBuilder.build())
}
}
这篇关于Android 8/9通知时间表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!