如何使用工作管理器处理来自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

我想知道,由于现在在多个资源中都提到它,因此您将如何基于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);
        }
    }
}

根据我在网络项目中的经验上面的代码基于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.

我发现了什么到目前为止,有关工作管理器的信息是您可以使用工作管理器将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天全站免登陆