java—使用workmanager触发推送通知有一些延迟

anhgbhbe  于 2021-07-11  发布在  Java
关注(0)|答案(0)|浏览(242)

我正在做一个样本项目来练习背景工作。首先,我用了firebasejobdispatcher,一切正常。。后来我知道了workmanager,这是目前做背景工作的最好方法。。
我的应用程序的想法是,用户输入他希望触发通知的分钟数,当使用firebasejobdispatcher时,通知会准时触发,但当我切换到workmanager时,通知会延迟近20秒+用户已经输入的时间。。换句话说,如果用户将触发器设置为1分钟,然后关闭应用程序,则在活动被销毁20秒后,倒计时再次开始。。这意味着通知将在1:20分钟后触发。
以下是mainactivity中的代码(使用workmanager):

Data data = new Data.Builder()
                    .putInt("number", minutes*60)
                    .build();

            OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class)                     
                    .setInputData(data)                        
                    .addTag("timer")
                    .build();

            WorkManager.getInstance(MainActivity.this).enqueue(oneTimeWorkRequest);

mainactivity(使用firebasejobdispatcher)

JobSchedulerUtils.scheduleNotification(MainActivity.this, minutes);

以下是扩展worker的java类:

public class MyWorker extends Worker {
public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
    super(context, workerParams);
}

@NonNull
@Override
/*
this is a simulation for background work, a countdown starts at a given number and this number decrements every second.
the process runs off of the main thread.
 */
public Result doWork() {
    // this is like an intent bundle, if you want to pass data from the activity to the Worker
    // in this app, the passed int is the number where we start countdown
    Data inputData = getInputData();
    int number = inputData.getInt("number", -1);

    for(int i = number; i >= 0; i--){
        Log.d("logmsg", i+"");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return Result.failure();
        }
    }

    TriggerTasks.executeTask(getApplicationContext(), TriggerTasks.TRIGGER_NOTIFICATION);
    return Result.success();
}

}
以下是使用firebasejobdispatcher时使用的类:
a-schedulerfirebasejobdispatcher.java

public class SchedulerFirebaseJobService extends JobService {

private AsyncTask mTask;
@Override
public boolean onStartJob(final JobParameters job) {

    mTask = new AsyncTask() {
        @Override
        protected Object doInBackground(Object[] objects) {
            // work to be done in background
            Context context = SchedulerFirebaseJobService.this;
            TriggerTasks.executeTask(context, TriggerTasks.TRIGGER_NOTIFICATION);
            return null;
        }

        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
            jobFinished(job, false);
        }
    };
    mTask.execute();
    return true;
}

@Override
public boolean onStopJob(JobParameters job) {
    if (mTask != null) mTask.cancel(true);
    return false;
}

}
b-作业计划rutils.java

public class JobSchedulerUtils {
private static final String TRIGGER_NOTIFICATION_JOB_TAG = "trigger-notification";

synchronized public static void scheduleNotification(@NonNull final Context context, int time){

    Driver driver = new GooglePlayDriver(context);
    // TODO: use WorkManager instead of FirebaseJobDispatcher
    FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(driver);
    // job is triggered in the service so we set service to SchedulerFirebaseJobService, but here we define the parameters of this job
    // to be done in the background..
    // in other words, services's doInBackground is triggered using the following parameters and after the event in setTrigger occurs
    Job job = dispatcher.newJobBuilder().setService(SchedulerFirebaseJobService.class)
            .setTag(TRIGGER_NOTIFICATION_JOB_TAG)
            .setLifetime(Lifetime.FOREVER)
            .setRecurring(false)
            .setTrigger(Trigger.executionWindow(time*60, time*60))
            .setReplaceCurrent(true)
            .build();

    dispatcher.schedule(job);
}

}
以下是两种情况下使用的其他类:
a-triggertasks.java

public class TriggerTasks {
public static final String DISMISS_NOTIFICATION = "dismiss-notification";
public static final String TRIGGER_NOTIFICATION = "trigger-notification";

public static void executeTask(Context context, String action){
    if(DISMISS_NOTIFICATION.equals(action)){
        NotificationUtils.clearAllNotifications(context);
    }
    if(TRIGGER_NOTIFICATION.equals(action)){
        NotificationUtils.createNotification(context);
    }
}

}
b-notificationutils.java

public class NotificationUtils {
private static final String NOTIFICATION_CHANNEL_ID = "notif-channel";
private static final String NOTIFICATION_CHANNEL_NAME = "Primary";
private static final int PENDING_INTENT_ID = 1991;
private static final int NOTIFICATION_ID = 500;
private static final int ACTION_IGNORE_PENDING_INTENT_ID = 24;

public static void clearAllNotifications(Context context){
    NotificationManager notificationManager = (NotificationManager)
            context.getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.cancelAll();
}

public static void createNotification(Context context){
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
        NotificationChannel notificationChannel = new NotificationChannel(
                NOTIFICATION_CHANNEL_ID,
                NOTIFICATION_CHANNEL_NAME,
                NotificationManager.IMPORTANCE_HIGH
                );
        notificationManager.createNotificationChannel(notificationChannel);
    }

    NotificationCompat.Builder builder = new NotificationCompat.Builder(context,NOTIFICATION_CHANNEL_ID);
    builder.setAutoCancel(true)
            .setContentText(context.getString(R.string.notification_text))
            .setContentTitle(context.getString(R.string.notification_title))
            // this attribute controls what happens when a notification is clicked
            .setContentIntent(contentIntent(context))
            .setSmallIcon(R.drawable.ic_launcher_background)
            .addAction(dismissNotification(context));

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
        builder.setPriority(NotificationCompat.PRIORITY_HIGH);
    }

    notificationManager.notify(NOTIFICATION_ID, builder.build());
}

/*
guarantees that a click on the notification will start MainActivity
 */
private static PendingIntent contentIntent(Context context){
    Intent toMainActivity = new Intent(context, MainActivity.class);
    return PendingIntent.getActivity(
            context,
            PENDING_INTENT_ID,
            toMainActivity,
            PendingIntent.FLAG_UPDATE_CURRENT);
}

private static NotificationCompat.Action dismissNotification (Context context){
    Intent intent = new Intent(context, TriggerIntentService.class);
    intent.setAction(TriggerTasks.DISMISS_NOTIFICATION);
    PendingIntent pendingIntent = PendingIntent.getService(
            context,
            ACTION_IGNORE_PENDING_INTENT_ID,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT);
    NotificationCompat.Action dismissNotificationAction = new NotificationCompat.Action(
            R.drawable.ic_launcher_foreground,
            context.getString(R.string.notification_action_dismiss),
            pendingIntent);
    return dismissNotificationAction;
}

}
c-triggerintentservice.java

public class TriggerIntentService extends IntentService {

public TriggerIntentService() {
    super("TriggerIntentService");
}

@Override
protected void onHandleIntent(@Nullable Intent intent) {
    String action = intent.getAction();
    TriggerTasks.executeTask(this, action);
}

}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题