首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android 8/9通知调度

Android 8/9通知调度
EN

Stack Overflow用户
提问于 2019-05-13 05:17:04
回答 2查看 3.5K关注 0票数 9

我尝试将通知安排在特定的日期和时间,但在大多数设备上,似乎没有显示通知。在Android9/8之前,我使用了AlarmManager,它非常容易使用,而且很有效,但是最后两个版本的android已经改变了.(感谢谷歌让一切变得更容易.)

下面是我用来安排通知的代码。我用的是OneTimeWorkRequest

代码语言:javascript
复制
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);
}

然后,我用来显示通知的类是:

代码语言:javascript
复制
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.)
    }
}

而这个:

代码语言:javascript
复制
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");
        }
    }

}

我做错什么了?有一种最好、更有效的方法来做到这一点吗?

编辑:我希望看到一个关于如何将通知安排到特定日期+时间的示例,这个示例非常有效。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-21 06:47:24

下面是我在我的一个项目中使用的一个工作实现。

将此添加到您的build.gradle (app)中(因为它在Kotlin中)

代码语言:javascript
复制
//android-jet pack
implementation 'android.arch.work:work-runtime-ktx:1.0.1'

或者使用Android:

代码语言:javascript
复制
implementation "androidx.work:work-runtime-ktx:2.5.0"

https://developer.android.com/jetpack/androidx/releases/work

创建一个方法scheduleNotification。传递必要的数据

代码语言:javascript
复制
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

代码语言:javascript
复制
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类根据需要自定义这个类

代码语言:javascript
复制
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())
}


}
票数 11
EN

Stack Overflow用户

发布于 2019-05-15 09:57:59

尝试下面的代码,我已经使用它在我的应用程序之一,对我来说很好。

代码语言:javascript
复制
private void startWorkForWeekNotification() {
    OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(
        OpenAppNotifyWorker.class)
        .setInitialDelay(OpenAppNotifyWorker.NOTIFY_TO_OPEN_APP_IN_DAYS, TimeUnit.DAYS)
        .build();

    WorkManager.getInstance().beginUniqueWork(
        OpenAppNotifyWorker.WORKER_NAME,
        ExistingWorkPolicy.REPLACE,
        oneTimeWorkRequest).enqueue();
}

工人阶级

代码语言:javascript
复制
public class OpenAppNotifyWorker extends Worker {

public static final String WORKER_NAME = "OpenAppNotifyWorker";

public static final int NOTIFY_TO_OPEN_APP_IN_DAYS = 7;

public OpenAppNotifyWorker(@NonNull Context context,
    @NonNull WorkerParameters workerParams) {
    super(context, workerParams);
}

@NonNull
@Override
public Result doWork() {
    NotificationUtils
        .showNotification(getApplicationContext(), NotificationUtils.UPDATE_CHANNEL_ID,
            NotificationUtils.UPDATE_NOTIFICATION_ID);
    return Result.success();
}

}

NotificationUtils类

代码语言:javascript
复制
public class NotificationUtils {

public static final String UPDATE_CHANNEL_ID = "updates";

public static final int UPDATE_NOTIFICATION_ID = 1;

public static final int NOTIFICATION_REQUEST_CODE = 50;

public static void showNotification(Context context, String channelId, int notificationId) {
    createNotificationChannel(context, channelId);
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
        context, channelId)
        .setSmallIcon(R.drawable.ic_splash_logo)
        .setContentTitle(context.getString(R.string.title_notification))
        .setContentText(context.getString(R.string.msg_body_notification))
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);
    NotificationManagerCompat notificationManager = NotificationManagerCompat
        .from(context);
    notificationManager.notify(notificationId, mBuilder.build());
}

public static void createNotificationChannel(Context context, String channelId) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        //TODO change channel name and description
        CharSequence name = context.getString(R.string.notification_channel_updates);
        String description = context.getString(R.string.desc_notification_channel);
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(
            channelId, name, importance);
        channel.setDescription(description);
        NotificationManager notificationManager = context
            .getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}

public static void createPushNotification(Context context, String message) {
    NotificationUtils
        .createNotificationChannel(context, NotificationUtils.UPDATE_CHANNEL_ID);
    Intent notificationIntent = new Intent(context, SplashActivity.class);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    notificationIntent.setAction(Intent.ACTION_MAIN);
    notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
    notificationIntent.putExtra(FcmPushListenerService.EXTRAS_NOTIFICATION_DATA, message);
    PendingIntent contentIntent = PendingIntent
        .getActivity(context, NOTIFICATION_REQUEST_CODE, notificationIntent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
        context, NotificationUtils.UPDATE_CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_notification_app_logo)
        .setContentTitle(context.getString(R.string.app_name))
        .setContentText(message)
        .setAutoCancel(true)
        .setContentIntent(contentIntent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);
    NotificationManagerCompat notificationManager = NotificationManagerCompat
        .from(context);
    notificationManager.notify(NotificationUtils.UPDATE_NOTIFICATION_ID, mBuilder.build());
}

public static void cancelAllNotification(Context context) {
    NotificationManagerCompat notificationManager = NotificationManagerCompat
        .from(context);
    notificationManager.cancelAll();
}
}

如果您想启动服务,可以这样做:

代码语言:javascript
复制
public class OpenAppNotifyWorker extends Worker {

public static final String WORKER_NAME = "OpenAppNotifyWorker";

public static final int NOTIFY_TO_OPEN_APP_IN_DAYS = 7;

public Context context;

public OpenAppNotifyWorker(@NonNull Context context,
@NonNull WorkerParameters workerParams) {
    this.context = context
    super(context, workerParams);
}

@NonNull
@Override
public Result doWork() {

    context.startService(new NotificationIntentService())
    return Result.success();
}

}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56106112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档