如何使用 Work Manager 处理来自 FusedLocationProviderClient 的位置更新?
How can location updates from FusedLocationProviderClient be processed with Work Manager?
首先,我完全是一个Android菜鸟。现在已经寻找解决方案一段时间了,但到目前为止找不到正确方向上的任何有用提示。这可能一般是由问题本身的性质引起的,非常小众。
下面的工作代码基于 https://codelabs.developers.google.com/codelabs/realtime-asset-tracking 的代码实验室。
虽然我想知道,因为它在多个资源中被提到为现在的首选方式,你如何基于 Android 的工作管理器而不是具有持续通知的服务来做类似的事情?
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 的 "listener"。一旦有新的位置更新,它就会调用 onLocationResult
和相应的位置结果。
到目前为止,我对工作管理器的了解是,您可以将工作管理器设置为 doWork()
一次或定期。就像一个 cron 作业一样有效...
我不明白的是,如果后台没有 运行 服务,Worker 和位置更新请求会从哪里发起?他们将如何合作?
我在这里创建了演示: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);
希望对您有所帮助。如果您遇到任何问题,请告诉我。谢谢
首先,我完全是一个Android菜鸟。现在已经寻找解决方案一段时间了,但到目前为止找不到正确方向上的任何有用提示。这可能一般是由问题本身的性质引起的,非常小众。
下面的工作代码基于 https://codelabs.developers.google.com/codelabs/realtime-asset-tracking 的代码实验室。
虽然我想知道,因为它在多个资源中被提到为现在的首选方式,你如何基于 Android 的工作管理器而不是具有持续通知的服务来做类似的事情?
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 的 "listener"。一旦有新的位置更新,它就会调用 onLocationResult
和相应的位置结果。
到目前为止,我对工作管理器的了解是,您可以将工作管理器设置为 doWork()
一次或定期。就像一个 cron 作业一样有效...
我不明白的是,如果后台没有 运行 服务,Worker 和位置更新请求会从哪里发起?他们将如何合作?
我在这里创建了演示: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);
希望对您有所帮助。如果您遇到任何问题,请告诉我。谢谢