android - 使用 FusedLocationProviderClient、JobScheduler 和 JobService 更新位置

标签 android background-service android-jobscheduler fusedlocationproviderclient

我正在尝试使用带有 JobScheduler 和 JobService 的新 FusedLocationProviderClient 创建后台位置跟踪服务。我读过 here

我们应该使用 requestLocationUpdates (LocationRequest request, PendingIntent callbackIntent)以此目的。我在我的 MainActivity 中安排工作是这样的:

final ComponentName serviceComponent = new ComponentName(this, LocationJobService.class);
final JobScheduler jobScheduler;
final JobInfo.Builder builder = new JobInfo.Builder(LocationJobService.LOCATION_JOB_SERVICE_ID,
                        serviceComponent);
builder.setPeriodic(JobInfo.getMinPeriodMillis(), JobInfo.getMinFlexMillis());
builder.setPersisted(true);
final JobInfo jobInfo = builder.build();
jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
if (jobScheduler != null)
{
    if(jobScheduler.schedule(jobInfo) == JobScheduler.RESULT_SUCCESS)
       Log.d(TAG, String.format("Job %s successfully scheduled", LocationJobService.LOCATION_JOB_SERVICE_ID));
    else
       Log.e(TAG, "Job schedule failed!");
    }

LocationJobService 类:

private static final String TAG = "Class " + LocationJobService.class.getSimpleName();
public static final int LOCATION_JOB_SERVICE_ID = 1001;
private FusedLocationProviderClient client;

@Override
public boolean onStartJob(final JobParameters params)
{
    //some logic before initializing location update
    initializeLocationUpdate(getApplicationContext());
}
private void initializeLocationUpdate(Context context)
{
    client = LocationServices.getFusedLocationProviderClient(context);
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(3000);
    locationRequest.setFastestInterval(1000);

    client.requestLocationUpdates(locationRequest, pendingIntent)
            .addOnCompleteListener(new OnCompleteListener<Void>()
            {
                @Override
                public void onComplete(@NonNull Task<Void> task)
                {
                    Log.d(TAG, "onComplete " + task.getResult());
                }
            }).addOnFailureListener(new OnFailureListener()
            {
                @Override
                public void onFailure(@NonNull Exception e)
                {
                    Log.d(TAG, "onFailure");
                }
            });
    }

关于如何为 requestLocationUpdates 提供 PendingIntent 的任何想法以及如何获得 Location来自 onComplete(@NonNull Task<Void> task)

最佳答案

我想出的解决方案是我创建了扩展 BroadcastReceiver 的 Receiver,然后用它来创建 PendingIntent。然后从我在 onReceive 方法中获得的 Intent 中提取位置。 在 JobService 中:

client = LocationServices.getFusedLocationProviderClient(getApplicationContext());
Intent locationReceiverIntent = new Intent(getApplicationContext(), LocationJobServiceReceiver.class);
locationReceiverIntent.setAction(LocationJobServiceReceiver.PROCESS_UPDATES);
PendingIntent locationReceiverPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), LocationJobServiceReceiver.LOCATION_JOB_SERVICE_RECEIVER_CODE, locationReceiverIntent, PendingIntent.FLAG_UPDATE_CURRENT);
LocationRequest locationRequest = new LocationRequest();
locationRequest.setInterval(60000);
locationRequest.setFastestInterval(30000);
locationRequest.setExpirationDuration(60000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (checkPermission(getApplicationContext()))
{
    client.requestLocationUpdates(locationRequest,locationReceiverPendingIntent);
    jobFinished(jobParameters, false);
}

LocationJobServiceReceiveronReceive(final Context context, Intent intent) 中:

client = LocationServices.getFusedLocationProviderClient(context);
final LocationResult locationResult = LocationResult.extractResult(intent);
final String action = intent.getAction();
pendingIntent = PendingIntent.getBroadcast(context, LOCATION_JOB_SERVICE_RECEIVER_CODE, intent, PendingIntent.FLAG_NO_CREATE);
if (PROCESS_UPDATES.equals(action))
{
    if (locationResult != null)
    {
        Location location;
        List<Location> locations = locationResult.getLocations();
        if (locations.size() > 0)
        {
            location = locations.get(0);
        }
        else
        {
            location = locationResult.getLastLocation();
        }
    }
}
client.removeLocationUpdates(pendingIntent);

关于android - 使用 FusedLocationProviderClient、JobScheduler 和 JobService 更新位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48170499/

相关文章:

android - 当应用程序在 Android 中更新时,后台服务会发生什么变化?

android - 使用 SyncAdapter/不同线程更新时,LiveData 不会观察到变化

c# - 如何在 Xamarin Android 中实现 JobScheduler

android - 编译后将 Android 应用程序设置为可调试

Android、javamail 和 proguard

android - 如何使用具有相同 url 的新图像缓存图像?

android - 如何在使用服务的Android 8.0(Oreo设备)上的后台应用程序中获取用户GPS位置?

Android-JobScheduler 的 setPeriodic 将不起作用

android - JobScheduler 的问题 - JobsService 多次触发

android - 我想在我的 String JsonObject 中获取值(value)