Моя работа выполняется отлично, если приложение открыто, но если я закрою приложение, служба работы никогда не выполняется. Я следил за учебником здесь; Job Scheduler — Code In Flow, и он просто не запускается (или, может быть, запускается, а мы не знаю, он работает?). Я добавил уведомления и методы Log.d в свои методы, чтобы я мог видеть, выполняется ли задание, и пока приложение открыто, сообщения журнала и уведомления проходят, как и ожидалось.
Любая помощь будет оценена по достоинству. Спасибо
ОБНОВЛЕНИЕ 2
================
Я обнаружил, что, поскольку задание выполняется, когда приложение открыто, если я закрою приложение, задание отменяется без вызова onStopJob
. теоретически, если я не ошибаюсь, планировщик заданий должен продолжать работу независимо от того, запущено приложение или нет. сообщение Log.d выглядит так
D/global_PEA: Job Scheduled //Schedule Job Button Pressed
D/global_PEA: Job Started //ExJobService runs
D/global_PEA: run: 0
D/global_PEA: run: 1
D/global_PEA: run: 2
D/global_PEA: run: 3
D/global_PEA: run: 4
// App closed and the output and notifications stop
// in theory it should continue till 9
=======
ОБНОВЛЕНИЕ
================
Вот дамп оболочки adb моего приложения. вроде по расписанию?
Я не могу получить какие-либо уведомления или сообщения Log.d, когда принудительно запускаю задание из adb, например adb shell cmd jobscheduler run -f com.raaif.pea 902
что наводит меня на мысль, что, возможно, задание действительно выполняется, но пользователю об этом ничего не показывается, как уведомление. Есть ли способ уведомить приложение, даже если оно откроет приложение, когда работа будет выполнена?
==============
вот мои файлы кода
public class HomeFragment extends Fragment {
private Context mContext;
private Button btn1;
private Button btn2;
@Override
public void onAttach(Context context) {
mContext = context;
super.onAttach(context);
}
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home, container, false);
btn1 = root.findViewById(R.id.button1);
btn2= root.findViewById(R.id.button2);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scheduleJob();
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cancelJob();
}
});
return root;
}
public void scheduleJob(){
ComponentName componentName = new ComponentName(mContext, ExJobService.class);
JobInfo info = new JobInfo.Builder(JOB_ID_1, componentName)
.setRequiresCharging(false)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setPersisted(true)
.setPeriodic(15 * 60 * 1000)
.build();
JobScheduler scheduler = (JobScheduler) mContext.getSystemService(JOB_SCHEDULER_SERVICE);
int resultcode = scheduler.schedule(info);
if(resultcode==JobScheduler.RESULT_SUCCESS){
Log.d(globals.appTag,"Job Scheduled");
}else{
Log.d(globals.appTag,"Job Scheduling failed");
}
}
public void cancelJob(){
JobScheduler scheduler = (JobScheduler)getContext().getSystemService(JOB_SCHEDULER_SERVICE);
scheduler.cancel(JOB_ID_1);
Log.d(globals.appTag,"Job cancelled");
}
}
А вот мой класс JobService
import android.app.Notification;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Intent;
import android.util.Log;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import static com.raaif.pea.Constants.CHANNEL_ID_NOTIFICATION_HIGH;
import static com.raaif.pea.Constants.HIGH_NOTIF_ID;
public class ExJobService extends JobService {
private Globals globals = Globals.getInstance();
private boolean jobcancelled = false;
private boolean reschedulestatus = false;
@Override
public boolean onStartJob(JobParameters params) {
Log.d(globals.appTag, "Job Started");
//output low notification
notify("Scheduled JobService", "Starting Background Work");
doBackgroundWork(params);
return true;
}
private void doBackgroundWork(final JobParameters params) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
if (jobcancelled) return;
Log.d(globals.appTag, "run: " + i);
ExJobService.this.notify("Thread Iterator",
String.format("Iteration Count: %d", i));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.d(globals.appTag, "Job Finished");
ExJobService.this.notify("Scheduled JobService", "Background Work Finished");
jobFinished(params, reschedulestatus);
Log.d(globals.appTag, "Job Service Params returned with " + reschedulestatus);
ExJobService.this.notify("Scheduled JobService", "Job Params returned");
}
}).start();
}
@Override
public boolean onStopJob(JobParameters params) {
Log.d(globals.appTag, "Job Cancelled before completion");
jobcancelled = true;
notify("OnStopJob", "Job Cancelled");
return false;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//return Service.START_STICKY;
return super.onStartCommand(intent, flags, startId);
}
public void notify(String title, String content) {
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
Notification notification =
new NotificationCompat.Builder(ExJobService.this, CHANNEL_ID_NOTIFICATION_HIGH)
.setSmallIcon(R.drawable.ic_memory_black_24dp)
.setContentTitle(title)
.setContentText(content)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setOnlyAlertOnce(false)
.build();
notificationManager.notify(HIGH_NOTIF_ID, notification);
}
}
Манифест.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.raaif.pea">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<!-- SERVICES -->
<service android:name=".ExJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
adb shell dumpsys jobscheduler
- person H4SN   schedule 05.02.2020