0

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.

+0

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

+0

Je n'ai aucune idée de qui "ils" sont. – CommonsWare

+0

@CommonsWare pouvez-vous s'il vous plaît montrer l'implémentation en utilisant Threads, je suis confus. – theSereneRebel

Répondre

1

Vous devez demander l'autorisation de localisation à la fois dans le manifeste et le code pour le faire fonctionner.

Manifest

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 

classe MainActivity:

oncreate():

private static final int MY_PERMISSIONS_REQUEST_FINE_LOCATION = 111; 

    if (ContextCompat.checkSelfPermission(MainActivity.this, // Check for permission 
      android.Manifest.permission.ACCESS_FINE_LOCATION) 
      != PackageManager.PERMISSION_GRANTED) { 
     ActivityCompat.requestPermissions(
       this, // Activity 
       new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 
       MY_PERMISSIONS_REQUEST_FINE_LOCATION); 
    }