PeriodicWorker 不显示通知

问题描述 投票:0回答:1

我正在使用PeriodicWorker对我的应用程序数据进行每日备份,即将mu本地数据上传到云存储服务。 但是,当我首先使用

setForegroundAsync(foregroundInfo);
时,会显示警告 (
startForegroundService() not allowed due to mAllowStartForeground false: service com.mydomain/androidx.work.impl.foreground.SystemForegroundService
)在这个过程中,它给了我下面的错误

Unable to stop foreground service
android.app.BackgroundServiceStartNotAllowedException: Not allowed to start service Intent { act=ACTION_STOP_FOREGROUND cmp=com.mydomain/androidx.work.impl.foreground.SystemForegroundService }: app is in background uid UidRecord{dff373e u0a386 TRNB bg:+3m49s885ms idle change:procadj procs:0 seq(7594403,7591739)} caps=------
    at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1945)
    at android.app.ContextImpl.startService(ContextImpl.java:1900)
    at android.content.ContextWrapper.startService(ContextWrapper.java:825)
    at androidx.work.impl.Processor.stopForegroundService(Processor.java:425)
    at androidx.work.impl.Processor.stopForeground(Processor.java:303)
    at androidx.work.impl.WorkerWrapper.resolve(WorkerWrapper.java:464)
    at androidx.work.impl.WorkerWrapper.resetPeriodicAndResolve(WorkerWrapper.java:577)
    at androidx.work.impl.WorkerWrapper.handleResult(WorkerWrapper.java:480)
    at androidx.work.impl.WorkerWrapper.onWorkFinished(WorkerWrapper.java:358)
    at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:335)
    at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
    at java.lang.Thread.run(Thread.java:1012)

“有趣”的部分是该过程运行得非常好,所有数据都完美地复制到云端,除了未显示的通知之外没有任何问题。

有人知道如何在应用程序处于后台时显示通知吗?

这是我的工人代码。

public class DatabaseCloudBackupWorker extends Worker {
    public static final String TAG = DatabaseCloudBackupWorker.class.getName();

    @Override
    public Result doWork() {
        Result result = Result.failure();

        Log.i(TAG, "Starting Database Backup");
        this.showProgressNotification();

        try {
            uploadData()
            result = Result.success();

        } catch (Exception e) {
            Log.e(TAG, "Error")

        }

        return result;
    }

    private void showProgressNotification() {
        Log.i(TAG, "Showing Database Backup Progress Notification");

        Notification notification = this.newProgressNotification();

        ForegroundInfo foregroundInfo;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            foregroundInfo = new ForegroundInfo(PROGRESS_NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);
        } else {
            foregroundInfo = new ForegroundInfo(PROGRESS_NOTIFICATION_ID, notification);
        }

        this.setForegroundAsync(foregroundInfo);

    }

    private Notification newProgressNotification() {
        Notification notification = new NotificationCompat.Builder(MyApp.getAppContext(), MyNotificationManager.CHANNEL_ID)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setOnlyAlertOnce(true)
                .setOngoing(true)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setProgress(0, 0, true)
                .setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
                .setContentTitle("Database Backup")
                .setContentText("Database Backup in Progress")
                .build();

        return notification;
    }
}

这是我的清单会话,我在其中设置了前台服务的类型

        <service
            android:name="androidx.work.impl.foreground.SystemForegroundService"
            android:foregroundServiceType="dataSync"
            tools:node="merge" />

这是我创建PeriodicWorkRequest的地方


            // Creating Work Request
            Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.UNMETERED).build();
            PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(DatabaseCloudBackupWorker.class, 1, TimeUnit.DAYS)
                    .setInitialDelay(initialDelayInMinutes, TimeUnit.MINUTES)
                    .addTag(DatabaseCloudBackupWorker.TAG_PERIODIC_WORKER)
                    .setConstraints(constraints)
                    .setInputData(inputData)
                    .build();

            //
            WorkManager workManager = WorkManager.getInstance(MyApp.getAppContext());

            Log.i(TAG, "Enqueuing DatabaseCloudBackupWorker");
            Operation operation = workManager.enqueueUniquePeriodicWork(DatabaseCloudBackupWorker.NAME_PERIODIC, ExistingPeriodicWorkPolicy.UPDATE, workRequest);

java android notifications android-workmanager foreground-service
1个回答
0
投票

使用以下代码获取通知。

您必须在 Android 8.1 及更高版本中创建通知通道。

 private static final int NOTIFICATION_ID = 1;
 private static final String CHANNEL_ID = "MyChannelId";
 
 // Create a notification channel
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "My Channel", NotificationManager.IMPORTANCE_LOW);
     NotificationManager notificationManager = getSystemService(NotificationManager.class);
    notificationManager.createNotificationChannel(channel);
    }

Notification notification = buildNotification();
startForeground(NOTIFICATION_ID, notification);

 @RequiresApi(api = Build.VERSION_CODES.M)
private Notification buildNotification() {

    Intent fullScreenIntent = new Intent(this, HomeActivity.class);
    PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
            fullScreenIntent, PendingIntent.FLAG_IMMUTABLE);

    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(this, CHANNEL_ID)
                    .setSmallIcon(R.drawable.ic_notification)
                    .setContentTitle("Title")
                    .setContentText("Text")
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setCategory(NotificationCompat.CATEGORY_CALL)

                    // Use a full-screen intent only for the highest-priority alerts where you
                    // have an associated activity that you would like to launch after the user
                    // interacts with the notification. Also, if your app targets Android 10
                    // or higher, you need to request the USE_FULL_SCREEN_INTENT permission in
                    // order for the platform to invoke this notification.
                    .setFullScreenIntent(fullScreenPendingIntent, true);

    return notificationBuilder.build();
}
© www.soinside.com 2019 - 2024. All rights reserved.