如何使用工作管理器处理来自 FusedLocationProviderClient 的位置更新? [英] How can location updates from FusedLocationProviderClient be processed with Work Manager?

本文介绍了如何使用工作管理器处理来自 FusedLocationProviderClient 的位置更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我是一个完全的 Android 菜鸟.寻找解决方案已经有一段时间了,但到目前为止还没有在正确的方向上找到任何有用的提示.这通常可能是由问题本身的性质引起的,非常小众.

First of all, I'm a total Android noob. Have looked for solutions for some time now, but can't find any helpful hints in the right direction so far. This might be generally caused by the nature of the issue itself, being quite niche.

以下工作代码基于位于 https://codelabs 的代码实验室.developers.google.com/codelabs/realtime-asset-tracking.

The working code below is based on a code lab at https://codelabs.developers.google.com/codelabs/realtime-asset-tracking.

我想知道,既然在几个资源中都提到它是现在的首选方式,你将如何基于 Android 的工作管理器而不是具有持续通知的服务来做这样的事情?

I was wondering though, since it was mentioned within several resources as the preferred way now, how you'd do something like that based on Android's Work Manager instead of a Service with an ongoing notification?

public class TrackerService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        requestLocationUpdates();
    }

    private void requestLocationUpdates() {
        LocationRequest request = new LocationRequest();
        request.setInterval(5 * 60 * 1000);
        request.setFastestInterval(30 * 1000);
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this);
        int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
        if (permission == PackageManager.PERMISSION_GRANTED) {
            client.requestLocationUpdates(request, new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {
                    Location location = locationResult.getLastLocation();
                    if (location != null) {
                        Log.d(TAG, "location update " + location);
                    }
                }
            }, null);
        }
    }
}

根据我在 Web 项目中的经验,上面的代码基于 FusedLocationProviderClient 建立了一个侦听器".一旦有新的位置更新,它就会使用相应的位置结果调用 onLocationResult.

With my experience from web projects the above code establishes a "listener" based on the FusedLocationProviderClient. As soon as there's a new location update, it would call onLocationResult with the respective location result.

到目前为止,我对 Work Manager 的发现是,您可以使用 Work Manager 设置一个 Worker 以doWork() 一次或定期.有效地像一个 cron 工作......

What I found out about the Work Manager so far is that you can set up a Worker with Work Manager to doWork() once or periodically. Effectively like a cron job...

我不明白的是,如果后台没有正在运行的服务,那么 Worker 和位置更新请求将在哪里启动?他们将如何合作?

What I don't understand, if there's no running service in the background where would the Worker and the request for location updates be initiated? And how would they work together?

推荐答案

这里我创建了演示:LocationTracker-WorkManager

Here I have create demo : LocationTracker-WorkManager

MyWorker.java

public class MyWorker extends Worker {

    private static final String TAG = "MyWorker";

    /**
     * The desired interval for location updates. Inexact. Updates may be more or less frequent.
     */
    private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;

    /**
     * The fastest rate for active location updates. Updates will never be more frequent
     * than this value.
     */
    private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
            UPDATE_INTERVAL_IN_MILLISECONDS / 2;
    /**
     * The current location.
     */
    private Location mLocation;

    /**
     * Provides access to the Fused Location Provider API.
     */
    private FusedLocationProviderClient mFusedLocationClient;

    private Context mContext;
    /**
     * Callback for changes in location.
     */
    private LocationCallback mLocationCallback;

    public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
        mContext = context;
    }

    @NonNull
    @Override
    public Result doWork() {
        Log.d(TAG, "doWork: Done");

                mFusedLocationClient = LocationServices.getFusedLocationProviderClient(mContext);
                mLocationCallback = new LocationCallback() {
                    @Override
                    public void onLocationResult(LocationResult locationResult) {
                        super.onLocationResult(locationResult);
                    }
                };

                LocationRequest mLocationRequest = new LocationRequest();
                mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
                mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
                mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

                try {
                    mFusedLocationClient
                            .getLastLocation()
                            .addOnCompleteListener(new OnCompleteListener<Location>() {
                                @Override
                                public void onComplete(@NonNull Task<Location> task) {
                                    if (task.isSuccessful() && task.getResult() != null) {
                                        mLocation = task.getResult();
                                        Log.d(TAG, "Location : " + mLocation);
                                        mFusedLocationClient.removeLocationUpdates(mLocationCallback);
                                    } else {
                                        Log.w(TAG, "Failed to get location.");
                                    }
                                }
                            });
                } catch (SecurityException unlikely) {
                    Log.e(TAG, "Lost location permission." + unlikely);
                }

                try {
                    mFusedLocationClient.requestLocationUpdates(mLocationRequest, null);
                } catch (SecurityException unlikely) {
                    //Utils.setRequestingLocationUpdates(this, false);
                    Log.e(TAG, "Lost location permission. Could not request updates. " + unlikely);
                }

        } catch (ParseException ignored) {

        }

        return Result.success();
    }
}

如何开始工作:

PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(MyWorker.class, 15, TimeUnit.MINUTES)
                            .addTag(TAG)
                            .build();
WorkManager.getInstance().enqueueUniquePeriodicWork("Location", ExistingPeriodicWorkPolicy.REPLACE, periodicWork);

希望能帮到你.如果您遇到任何问题,请告诉我.谢谢.

Hope it will be helpful. Do let me know if you get any problem. Thanks.

这篇关于如何使用工作管理器处理来自 FusedLocationProviderClient 的位置更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆