如果应用程序关闭,我如何显示通知?
How do i show a notification if app is closed?
我有一个应用程序,在早上 7 点需要检查白天是否有一些任务来显示他们的通知,工作流示例:
早上 7 点:检查今天是否有任何任务 -> 在下午 5 点找到一个 -> 在下午 5 点设置通知
我已经尝试实现 Worker、JobScheduler、AlarmReceiver、Broadcast Receiver、JobService,但如果应用程序至少不在后台,则不会触发任何内容。
关于实施什么来执行我需要的任何建议?
谢谢!
编辑:添加输出:adb shell dumpsys jobscheduler
Implicit constraints:
BackgroundJobsController:
Forced App Standby Feature enabled: true
Force all apps standby: false
Small Battery Device: false
Force all apps standby for small battery device: false
Plugged In: true
Active uids: [u0a112 u0a113 u0a118 u0a119 u0a123 u0a124 u0a131 u0a140 u0a176 u0a190 u0a191 u0a192 u0a196 u0a201 u0a205 u0a212 u0a219 u0a228 u0a244 u0a253 u0a256 u0a287 u0a294 u0a433]
Foreground uids: [u0a112 u0a119 u0a123 u0a131 u0a176 u0a190 u0a191 u0a196 u0a201 u0a205 u0a212 u0a244 u0a253 u0a256 u0a287 u0a294 u0a433]
Except-idle + user whitelist appids: [1001, 2000, 10113, 10117, 10118, 10121, 10122, 10126, 10133, 10134, 10152, 10156, 10159, 10161, 10191, 10192, 10193, 10201, 10205, 10215, 10219, 10230, 10433, 10447]
User whitelist appids: [10159, 10219, 10230, 10433, 10447]
Temp whitelist appids: [10253]
Exempted packages:
User 0
com.francesco.pickem
Foreground UIDs: {1000=true, 1001=true, 1027=true, 1037=true, 1068=true, 10112=true, 10119=true, 10131=true, 10191=true, 10196=true, 10201=true, 10205=true, 10212=true, 10253=true, 10256=true, 10287=true, 10294=true, 99960=true}
Cached UID->package map:
10447: {com.francesco.pickem}
<0>com.francesco.pickem
ACTIVE: expirationTime=2051448531, windowSizeMs=600000, jobCountLimit=75, sessionCountLimit=75, executionTimeInWindow=0, bgJobCountInWindow=0, executionTimeInMaxPeriod=0, bgJobCountInMaxPeriod=0, sessionCountInWindow=0, inQuotaTime=0, jobCountExpirationTime=0, jobCountInRateLimitingWindow=0, sessionCountExpirationTime=0, sessionCountInRateLimitingWi
ndow=0
Historical stats at 2021-03-26-10-27-54 (-1h24m10s391ms) over +30m1s114ms:
u0a447 / com.francesco.pickem:
9x pending 61% 3x active-top
11x canceled
Max concurrency: 8 total, 2 foreground
Historical stats at 2021-03-26-09-56-28 (-1h55m36s45ms) over +31m25s654ms:
u0a447 / com.francesco.pickem:
24x pending 99% 8x active-top
23x canceled
Max concurrency: 8 total, 2 foreground
Historical stats at 2021-03-26-08-41-09 (-3h10m55s336ms) over +33m6s679ms:
u0a446 / com.francesco.pickem:
3x pending 2% 1x active-top
3x canceled
u0a447 / com.francesco.pickem:
6x pending 14% 2x active-top
5x canceled
Max concurrency: 6 total, 2 foreground
Current stats at 2021-03-26-10-57-55 (-54m9s277ms) over +54m9s278ms:
u0a447 / com.francesco.pickem:
27x pending 22% 7x active-top
27x canceled
Max concurrency: 6 total, 3 foreground
Job history:
-11m26s720ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-11m26s715ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-11m21s695ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-5m42s273ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-5m42s260ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-5m42s208ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-5m41s321ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-5m41s319ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-5m36s313ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-5m04s703ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-5m04s683ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-5m04s683ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-5m04s671ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-4m59s730ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-4m59s709ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-4m13s802ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-4m13s777ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-4m13s776ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-4m13s766ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-4m08s818ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-4m08s800ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-1m43s958ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-1m43s842ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-1m43s839ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-1m41s389ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-1m41s387ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-1m36s367ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-32s680ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-32s668ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-32s628ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-29s854ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-29s851ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-24s834ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-19s005ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-18s975ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-18s967ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
Pending queue:
Active jobs:
Slot #0: inactive since -6s437ms, stopped because: app called jobFinished
Slot #1: inactive since -5s631ms, stopped because: app called jobFinished
Slot #2: inactive since -8s14ms, stopped because: last work dequeued
Slot #3: inactive since -19s778ms, stopped because: cancel() called by app, callingUid=10196 uid=10196 jobId=-439
Slot #4: inactive since -19s751ms, stopped because: cancel() called by app, callingUid=10196 uid=10196 jobId=-459
Slot #5: inactive since -5m41s932ms, stopped because: cancel() called by app, callingUid=10196 uid=10196 jobId=-439
Slot #6: inactive since -1h22m42s81ms, stopped because: app called jobFinished
Slot #7: inactive since -1h22m42s441ms, stopped because: app called jobFinished
Slot #8: inactive
Slot #9: inactive
Slot #10: inactive
Slot #11: inactive
Slot #12: inactive
Slot #13: inactive
Slot #14: inactive
Slot #15: inactive
mReadyToRock=true
mReportedActive=false
Concurrency:
Screen state: current ON effective ON
Last screen ON : 2021-03-26 08:46:09.717 (-2h5m54s784ms)
Last screen OFF: 2021-03-26 08:42:01.879 (-2h10m2s622ms)
Current max jobs:
Config={tot=8 bg min/max=2/6} Running[FG/BG (total)]: 0 / 0 (0) Pending: 0 / 0 (0) Actual max: 0 / 0 (0) Res BG: 0 Starting: 0 / 0 (0) Total: 0 / 0 (0)
mLastMemoryTrimLevel: 0
Stats:
assignJobsToContexts: count=413694, total=704690,5ms, avg=1,703ms, max calls/s=3604 max dur/s=71812,1ms max time=71812,0ms
refreshSystemState: count=80114, total=157823,1ms, avg=1,970ms, max calls/s=10 max dur/s=26915,4ms max time=26915,4ms
PersistStats: FirstLoad: 124/28/25 LastSave: 119/27/24
C:\Users\Francesco\AndroidStudioProjects\LeagueOfLegendsApp\PickEm2020>
编辑 2:
C:\Users\Francesco\AndroidStudioProjects\LeagueOfLegendsApp\PickEm2020>adb shell dumpsys jobscheduler | find "JOB #u0a447"
JOB #u0a447/3: d3eed36 com.francesco.pickem/.NotificationsService.BackgroundTasks
JOB #u0a447/4: aadcfa5 com.francesco.pickem/.NotificationsService.BackgroundTasks
我建议您也使用 WorkerManager 并设置 PeriodicWorkRequest。
当然,该应用程序应该 运行 至少一次。
然后在应用程序打开时定期检查工作是否计划周全。
但是正如文档所说,PeriodicWorkRequest 应该足够了:
Robust Scheduling
WorkManager allows you to schedule work to run one- time or repeatedly using flexible scheduling windows. Work can be tagged and named as well, allowing you to schedule unique, replaceable work and monitor or cancel groups of work together. Scheduled work is stored in an internally managed SQLite database and WorkManager takes care of ensuring that this work persists and is rescheduled across device reboots. In addition, WorkManager adheres to power-saving features and best practices like Doze mode, so you don’t have to worry about it.
是的,它非常冗长,也许您可以使用 https://pastebin.com/。
您看到的停止只是通知作业开始然后停止,因为它已完成。
转储中有几个有趣的部分可以分析 jobscheduler 问题。要知道这份工作是否计划周全,请至少分享名为:“已注册的 XX 工作”的部分。它看起来像这样:
Registered 65 jobs:
JOB #1000/800: f44b386 android/com.android.server.pm.BackgroundDexOptService
1000 tag=*job*/android/com.android.server.pm.BackgroundDexOptService
Source: uid=1000 user=0 pkg=android
JobInfo:
Service: android/com.android.server.pm.BackgroundDexOptService
PERIODIC: interval=+1d0h0m0s0ms flex=+1d0h0m0s0ms
Requires: charging=true batteryNotLow=false deviceIdle=true
Backoff: policy=1 initial=+30s0ms
Has early constraint
Has late constraint
Required constraints: CHARGING TIMING_DELAY DEADLINE IDLE [0xc0000005]
Satisfied constraints: CHARGING BATTERY_NOT_LOW TIMING_DELAY DEVICE_NOT_DOZING BACKGROUND_NOT_RESTRICTED [0x82400003]
Unsatisfied constraints: DEADLINE IDLE [0x40000004]
Uid: active
Tracking: BATTERY IDLE TIME
Standby bucket: ACTIVE
Enqueue time: -20h45m53s452ms
Run time: earliest=-27m55s737ms, latest=+23h32m4s263ms
Last successful run: 2021-03-25 16:56:16
Last run heartbeat: 885
Ready: false (job=false user=true !pending=true !active=true !backingup=true comp=true)
您还可以使用 grep 过滤您的应用程序包名称或 uid。如果我关注你最后的评论,它可能是:
adb shell dumpsys jobscheduler | grep "JOB #u0a447" -A 22
我找到了解决这个问题的好方法,如果你接受前台服务,你可以实现它:
- 创建通知渠道:
private static final String CHANNEL_ID = "1";
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "channel_name";
String description = "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 = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
- 实现前台服务的启动(我有一个开关可以打开它on/off):
switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b){
createNotificationChannel();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent serviceIntent = new Intent(SettingsActivity.this, ForegroundService.class);
ContextCompat.startForegroundService(SettingsActivity.this, serviceIntent);
}
serviceIntent);
}else {
Intent serviceIntent = new Intent(SettingsActivity.this, ForegroundService.class);
stopService(serviceIntent);
}
}
});
- 如果您需要检查前台服务是否启动:
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager)
getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service :
manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
- 前台服务class:
public class ForegroundService extends Service {
DatabaseHelper databaseHelper;
public static final String TAG ="ForegroundService";
@Override
public void onCreate() {
super.onCreate();
databaseHelper = new DatabaseHelper(getBaseContext());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, "1")
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.icon)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
setAlarmManager();
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void setAlarmManager() {
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("TYPE", "TEST");
PendingIntent sender = PendingIntent.getBroadcast(this, 2, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
long l = new Date().getTime();
if (l < new Date().getTime()) {
l += 86400000; // start at next 24 hour
}
am.setRepeating(AlarmManager.RTC_WAKEUP, l, 60000, sender); // 86400000
}
}
- 不要忘记在清单上添加:
<service
android:name=".NotificationsService.ForegroundService">
</service>
每日重复服务取自 NyanLH Solution to this other problem
我有一个应用程序,在早上 7 点需要检查白天是否有一些任务来显示他们的通知,工作流示例: 早上 7 点:检查今天是否有任何任务 -> 在下午 5 点找到一个 -> 在下午 5 点设置通知
我已经尝试实现 Worker、JobScheduler、AlarmReceiver、Broadcast Receiver、JobService,但如果应用程序至少不在后台,则不会触发任何内容。
关于实施什么来执行我需要的任何建议? 谢谢!
编辑:添加输出:adb shell dumpsys jobscheduler
Implicit constraints:
BackgroundJobsController:
Forced App Standby Feature enabled: true
Force all apps standby: false
Small Battery Device: false
Force all apps standby for small battery device: false
Plugged In: true
Active uids: [u0a112 u0a113 u0a118 u0a119 u0a123 u0a124 u0a131 u0a140 u0a176 u0a190 u0a191 u0a192 u0a196 u0a201 u0a205 u0a212 u0a219 u0a228 u0a244 u0a253 u0a256 u0a287 u0a294 u0a433]
Foreground uids: [u0a112 u0a119 u0a123 u0a131 u0a176 u0a190 u0a191 u0a196 u0a201 u0a205 u0a212 u0a244 u0a253 u0a256 u0a287 u0a294 u0a433]
Except-idle + user whitelist appids: [1001, 2000, 10113, 10117, 10118, 10121, 10122, 10126, 10133, 10134, 10152, 10156, 10159, 10161, 10191, 10192, 10193, 10201, 10205, 10215, 10219, 10230, 10433, 10447]
User whitelist appids: [10159, 10219, 10230, 10433, 10447]
Temp whitelist appids: [10253]
Exempted packages:
User 0
com.francesco.pickem
Foreground UIDs: {1000=true, 1001=true, 1027=true, 1037=true, 1068=true, 10112=true, 10119=true, 10131=true, 10191=true, 10196=true, 10201=true, 10205=true, 10212=true, 10253=true, 10256=true, 10287=true, 10294=true, 99960=true}
Cached UID->package map:
10447: {com.francesco.pickem}
<0>com.francesco.pickem
ACTIVE: expirationTime=2051448531, windowSizeMs=600000, jobCountLimit=75, sessionCountLimit=75, executionTimeInWindow=0, bgJobCountInWindow=0, executionTimeInMaxPeriod=0, bgJobCountInMaxPeriod=0, sessionCountInWindow=0, inQuotaTime=0, jobCountExpirationTime=0, jobCountInRateLimitingWindow=0, sessionCountExpirationTime=0, sessionCountInRateLimitingWi
ndow=0
Historical stats at 2021-03-26-10-27-54 (-1h24m10s391ms) over +30m1s114ms:
u0a447 / com.francesco.pickem:
9x pending 61% 3x active-top
11x canceled
Max concurrency: 8 total, 2 foreground
Historical stats at 2021-03-26-09-56-28 (-1h55m36s45ms) over +31m25s654ms:
u0a447 / com.francesco.pickem:
24x pending 99% 8x active-top
23x canceled
Max concurrency: 8 total, 2 foreground
Historical stats at 2021-03-26-08-41-09 (-3h10m55s336ms) over +33m6s679ms:
u0a446 / com.francesco.pickem:
3x pending 2% 1x active-top
3x canceled
u0a447 / com.francesco.pickem:
6x pending 14% 2x active-top
5x canceled
Max concurrency: 6 total, 2 foreground
Current stats at 2021-03-26-10-57-55 (-54m9s277ms) over +54m9s278ms:
u0a447 / com.francesco.pickem:
27x pending 22% 7x active-top
27x canceled
Max concurrency: 6 total, 3 foreground
Job history:
-11m26s720ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-11m26s715ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-11m21s695ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-5m42s273ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-5m42s260ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-5m42s208ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-5m41s321ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-5m41s319ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-5m36s313ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-5m04s703ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-5m04s683ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-5m04s683ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-5m04s671ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-4m59s730ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-4m59s709ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-4m13s802ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-4m13s777ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-4m13s776ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-4m13s766ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-4m08s818ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks canceled
-4m08s800ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-1m43s958ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-1m43s842ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-1m43s839ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-1m41s389ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-1m41s387ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-1m36s367ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-32s680ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-32s668ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-32s628ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-29s854ms START: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks
-29s851ms START: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks
-24s834ms START-P: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks
-19s005ms STOP-P: #u0a447/3 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-18s975ms STOP-P: #u0a447/2 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
-18s967ms STOP: #u0a447/4 com.francesco.pickem/.NotificationsService.BackgroundTasks unexpectedly disconnected
Pending queue:
Active jobs:
Slot #0: inactive since -6s437ms, stopped because: app called jobFinished
Slot #1: inactive since -5s631ms, stopped because: app called jobFinished
Slot #2: inactive since -8s14ms, stopped because: last work dequeued
Slot #3: inactive since -19s778ms, stopped because: cancel() called by app, callingUid=10196 uid=10196 jobId=-439
Slot #4: inactive since -19s751ms, stopped because: cancel() called by app, callingUid=10196 uid=10196 jobId=-459
Slot #5: inactive since -5m41s932ms, stopped because: cancel() called by app, callingUid=10196 uid=10196 jobId=-439
Slot #6: inactive since -1h22m42s81ms, stopped because: app called jobFinished
Slot #7: inactive since -1h22m42s441ms, stopped because: app called jobFinished
Slot #8: inactive
Slot #9: inactive
Slot #10: inactive
Slot #11: inactive
Slot #12: inactive
Slot #13: inactive
Slot #14: inactive
Slot #15: inactive
mReadyToRock=true
mReportedActive=false
Concurrency:
Screen state: current ON effective ON
Last screen ON : 2021-03-26 08:46:09.717 (-2h5m54s784ms)
Last screen OFF: 2021-03-26 08:42:01.879 (-2h10m2s622ms)
Current max jobs:
Config={tot=8 bg min/max=2/6} Running[FG/BG (total)]: 0 / 0 (0) Pending: 0 / 0 (0) Actual max: 0 / 0 (0) Res BG: 0 Starting: 0 / 0 (0) Total: 0 / 0 (0)
mLastMemoryTrimLevel: 0
Stats:
assignJobsToContexts: count=413694, total=704690,5ms, avg=1,703ms, max calls/s=3604 max dur/s=71812,1ms max time=71812,0ms
refreshSystemState: count=80114, total=157823,1ms, avg=1,970ms, max calls/s=10 max dur/s=26915,4ms max time=26915,4ms
PersistStats: FirstLoad: 124/28/25 LastSave: 119/27/24
C:\Users\Francesco\AndroidStudioProjects\LeagueOfLegendsApp\PickEm2020>
编辑 2:
C:\Users\Francesco\AndroidStudioProjects\LeagueOfLegendsApp\PickEm2020>adb shell dumpsys jobscheduler | find "JOB #u0a447"
JOB #u0a447/3: d3eed36 com.francesco.pickem/.NotificationsService.BackgroundTasks
JOB #u0a447/4: aadcfa5 com.francesco.pickem/.NotificationsService.BackgroundTasks
我建议您也使用 WorkerManager 并设置 PeriodicWorkRequest。 当然,该应用程序应该 运行 至少一次。 然后在应用程序打开时定期检查工作是否计划周全。
但是正如文档所说,PeriodicWorkRequest 应该足够了:
Robust Scheduling
WorkManager allows you to schedule work to run one- time or repeatedly using flexible scheduling windows. Work can be tagged and named as well, allowing you to schedule unique, replaceable work and monitor or cancel groups of work together. Scheduled work is stored in an internally managed SQLite database and WorkManager takes care of ensuring that this work persists and is rescheduled across device reboots. In addition, WorkManager adheres to power-saving features and best practices like Doze mode, so you don’t have to worry about it.
是的,它非常冗长,也许您可以使用 https://pastebin.com/。
您看到的停止只是通知作业开始然后停止,因为它已完成。
转储中有几个有趣的部分可以分析 jobscheduler 问题。要知道这份工作是否计划周全,请至少分享名为:“已注册的 XX 工作”的部分。它看起来像这样:
Registered 65 jobs:
JOB #1000/800: f44b386 android/com.android.server.pm.BackgroundDexOptService
1000 tag=*job*/android/com.android.server.pm.BackgroundDexOptService
Source: uid=1000 user=0 pkg=android
JobInfo:
Service: android/com.android.server.pm.BackgroundDexOptService
PERIODIC: interval=+1d0h0m0s0ms flex=+1d0h0m0s0ms
Requires: charging=true batteryNotLow=false deviceIdle=true
Backoff: policy=1 initial=+30s0ms
Has early constraint
Has late constraint
Required constraints: CHARGING TIMING_DELAY DEADLINE IDLE [0xc0000005]
Satisfied constraints: CHARGING BATTERY_NOT_LOW TIMING_DELAY DEVICE_NOT_DOZING BACKGROUND_NOT_RESTRICTED [0x82400003]
Unsatisfied constraints: DEADLINE IDLE [0x40000004]
Uid: active
Tracking: BATTERY IDLE TIME
Standby bucket: ACTIVE
Enqueue time: -20h45m53s452ms
Run time: earliest=-27m55s737ms, latest=+23h32m4s263ms
Last successful run: 2021-03-25 16:56:16
Last run heartbeat: 885
Ready: false (job=false user=true !pending=true !active=true !backingup=true comp=true)
您还可以使用 grep 过滤您的应用程序包名称或 uid。如果我关注你最后的评论,它可能是:
adb shell dumpsys jobscheduler | grep "JOB #u0a447" -A 22
我找到了解决这个问题的好方法,如果你接受前台服务,你可以实现它:
- 创建通知渠道:
private static final String CHANNEL_ID = "1";
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "channel_name";
String description = "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 = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
- 实现前台服务的启动(我有一个开关可以打开它on/off):
switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b){
createNotificationChannel();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent serviceIntent = new Intent(SettingsActivity.this, ForegroundService.class);
ContextCompat.startForegroundService(SettingsActivity.this, serviceIntent);
}
serviceIntent);
}else {
Intent serviceIntent = new Intent(SettingsActivity.this, ForegroundService.class);
stopService(serviceIntent);
}
}
});
- 如果您需要检查前台服务是否启动:
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager)
getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service :
manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
- 前台服务class:
public class ForegroundService extends Service {
DatabaseHelper databaseHelper;
public static final String TAG ="ForegroundService";
@Override
public void onCreate() {
super.onCreate();
databaseHelper = new DatabaseHelper(getBaseContext());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, "1")
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.icon)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
setAlarmManager();
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void setAlarmManager() {
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("TYPE", "TEST");
PendingIntent sender = PendingIntent.getBroadcast(this, 2, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
long l = new Date().getTime();
if (l < new Date().getTime()) {
l += 86400000; // start at next 24 hour
}
am.setRepeating(AlarmManager.RTC_WAKEUP, l, 60000, sender); // 86400000
}
}
- 不要忘记在清单上添加:
<service
android:name=".NotificationsService.ForegroundService">
</service>
每日重复服务取自 NyanLH Solution to this other problem