J'essaie d'aller chercher l'emplacement à certains intervalles de temps lorsque l'application est fermée. Pour cela, j'ai essayé d'utiliser le dernier emplacement connu de GoogleApiClient et de le déclencher. un JobService. J'ai implémenté le ConnectionCallbacks sur la classe JobScheduler. Mais le problème est que le rappel onConnected() n'est jamais appelé. Je pense que le service est détruit avant que tout rappel ne soit retourné. Alors, quel sera un moyen efficace de mettre en œuvre cette logique.Utilisation de GoogleApiClient dans un Job Service à l'aide de Job Scheduler API - rappels manquants
Ma classe de service d'emploi
public class TestJobService extends JobService
{
protected GoogleApiClient mGoogleApiClient;
protected Location mLastLocation;
protected JobParameters mJobParameters;
public TestJobService() {
super();
}
private class GetLocation extends AsyncTask<Integer, Void, Integer> implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener {
protected Integer doInBackground(Integer... jobID) {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(getBaseContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
return jobID[0];
}
protected void onPostExecute(Integer jobID) {
Log.i("JobSchedulerTest","Job Finished!");
jobFinished(mJobParameters, true);
}
@Override
public void onConnected(@Nullable Bundle bundle) {
mLastLocation=LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Log.i("JobSchedulerTest", "on start job: " + mJobParameters.getJobId() + "," +
DateFormat.getTimeInstance().format(new Date())+
",Location("+mLastLocation.getLatitude()+","+mLastLocation.getLongitude()+")");
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
}
@Override
public boolean onStartJob(JobParameters jobParameters) {
Log.i("JobSchedulerTest","Job Running!");
mJobParameters=jobParameters;
Integer i=new Integer(mJobParameters.getJobId());
new GetLocation().execute(i);
return true;
}
@Override
public boolean onStopJob(JobParameters jobParameters) {
Log.i("JobSchedulerTest","Job Stopped!");
return true;
}
}
J'ai appelé le travail dans une activité donnant ces paramètres
private void scheduleJob() {
ComponentName mServiceComponent = new ComponentName(this, TestJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(5,mServiceComponent);
//builder.setMinimumLatency(5 * 1000); // wait at least
//builder.setOverrideDeadline(50 * 1000); // maximum delay
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);// require unmetered network
builder.setBackoffCriteria(5000,JobInfo.BACKOFF_POLICY_LINEAR);
builder.setRequiresDeviceIdle(false); // we dont care if device should be idle
builder.setRequiresCharging(false);// we don't care if the device is charging or not
//builder.setPersisted(true);
builder.setPeriodic(50*1000);
JobScheduler jobScheduler = (JobScheduler)getApplication().getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(builder.build());
}
Journaux sur le travail:
04-16 00:48:35.266 10455-10455/com.google.android.gms.location.sample.basiclocationsample I/JobSchedulerTest: Job Running!
04-16 00:48:35.293 10455-10455/com.google.android.gms.location.sample.basiclocationsample I/JobSchedulerTest: Job Finished!
04-16 00:48:37.484 2028-2951/? V/AlarmManager: sending alarm {c169dc type 3 *alarm*:android.content.jobscheduler.JOB_DELAY_EXPIRED}
04-16 00:48:37.550 2028-2028/? V/AlarmManager: done {c169dc, *alarm*:android.content.jobscheduler.JOB_DELAY_EXPIRED} [67ms]
04-16 00:48:37.555 10455-10455/com.google.android.gms.location.sample.basiclocationsample I/JobSchedulerTest: Job Running!
04-16 00:48:37.563 10455-10455/com.google.android.gms.location.sample.basiclocationsample I/JobSchedulerTest: Job Finished!
04-16 00:48:39.927 2028-2951/? V/AlarmManager: sending alarm {c169dc type 3 *alarm*:android.content.jobscheduler.JOB_DELAY_EXPIRED}
04-16 00:48:39.947 2028-2028/? V/AlarmManager: done {c169dc, *alarm*:android.content.jobscheduler.JOB_DELAY_EXPIRED} [23ms]
04-16 00:48:39.952 10455-10455/com.google.android.gms.location.sample.basiclocationsample I/JobSchedulerTest: Job Running!
04-16 00:48:39.957 10455-10455/com.google.android.gms.location.sample.basiclocationsample I/JobSchedulerTest: Job Finished!
04-16 00:48:50.078 2028-2951/? V/AlarmManager: sending alarm {c169dc type 3 *alarm*:android.content.jobscheduler.JOB_DELAY_EXPIRED}
04-16 00:48:50.114 2028-2028/? V/AlarmManager: done {c169dc, *alarm*:android.content.jobscheduler.JOB_DELAY_EXPIRED} [154ms]
04-16 00:48:50.117 10455-10455/com.google.android.gms.location.sample.basiclocationsample I/JobSchedulerTest: Job Running!
04-16 00:48:50.120 10455-10455/com.google.android.gms.location.sample.basiclocationsample I/JobSchedulerTest: Job Finished!
Ma mise en œuvre onConnected est jamais mis à la porte.
Votre 'AsyncTask' est décédé dès le retour' doInBackground() ', et votre travail est terminé microsecondes plus tard via 'jobFinished()'. À ce stade, tout votre processus pourrait être détruit. IMHO, 'AsyncTask' est la mauvaise solution ici (il suffit d'utiliser un' Thread'), et vous ne pouvez pas terminer le travail jusqu'à ce que vous obteniez votre position (ou après un certain délai de votre choix, au cas où vous n'obtiendrez jamais un emplacement). – CommonsWare
Je n'ai aucune idée de qui "ils" sont. – CommonsWare
@CommonsWare pouvez-vous s'il vous plaît montrer l'implémentation en utilisant Threads, je suis confus. – theSereneRebel