我正在开发一个必须跟踪用户位置并将其发送到远程服务器的应用程序。我知道这里已经有很多其他问题,但我无法找到我需要的东西。
基本上我正在使用FusedLocationProviderApi
来接收位置更新。它非常实用且易于使用。问题是我需要经常查询位置并且它正在快速耗尽电池(尽管电池使用的一部分可能来自网络操作以将位置发送到服务器)。但是,我只需要在用户移动时频繁更新。
所以我正在寻找的东西就像谷歌跟踪Android用户一样(正如我们在LocationHistory中看到的那样)。有谁知道谷歌从智能手机获得的位置是否可以在某处获得?或者也许是实施类似的策略?
答案 0 :(得分:4)
建议降低电池消耗,您可以使用活动检测来确定您需要确定位置的频率。在这方面,我可以推荐我为活动检测部分提供的https://github.com/mcharmas/Android-ReactiveLocation。该库还极大地减少了获取融合位置所需的编码行。
正如您在评论中所写,找到使用ActivityDetectionApi的好例子并不容易。这也是我将其添加到库中的原因之一。事实上,谷歌当时提供的文档已经过时了,因为他们更新了Google Play Services API,但没有更新教程。
我对没有使用该库的教程没有任何好的指示,但我可以使用ReactiveLocation提供我的代码片段。此代码在服务中运行,因此无论应用程序是否处于焦点,它都会跟踪当前活动:
private void requestFilteredActivityUpdates() {
ReactiveLocationProvider locationProvider = new ReactiveLocationProvider(getApplicationContext());
filteredActivitySubscription = locationProvider.getDetectedActivity(0).doOnError(new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
String message = "Error on activitySubscription: " + throwable.getMessage();
Log.e(TAG, message, throwable);
Crashlytics.logException(throwable);
}
}).onErrorReturn(new Func1<Throwable, ActivityRecognitionResult>() {
@Override
public ActivityRecognitionResult call(Throwable throwable) {
List<DetectedActivity> list = new ArrayList<DetectedActivity>();
list.add(new DetectedActivity(DetectedActivity.UNKNOWN, 0));
return new ActivityRecognitionResult(list, System.currentTimeMillis(), SystemClock.elapsedRealtime());
}
}).filter(new Func1<ActivityRecognitionResult, Boolean>() {
@Override
public Boolean call(ActivityRecognitionResult activityRecognitionResult) {
DetectedActivity detectedActivity = activityRecognitionResult.getMostProbableActivity();
boolean highConfidence = detectedActivity.getConfidence() > 75;
DetectedActivity previousActivity = ActivityDetectionModule.Recent.getDetectedActivity();
boolean isNewActivity = detectedActivity.getType() != previousActivity.getType();
boolean hasHigherConfidence = detectedActivity.getConfidence() > previousActivity.getConfidence();
return mJustStarted || (highConfidence && (isNewActivity || hasHigherConfidence));
}
}).subscribe(new Action1<ActivityRecognitionResult>() {
@Override
public void call(ActivityRecognitionResult activityRecognitionResult) {
DetectedActivity detectedActivity = activityRecognitionResult.getMostProbableActivity();
Log.i(TAG, "Activity changed or increased in confidence:");
Log.i(TAG, "New: " + ActivityDetectionModule.getNameFromType(detectedActivity.getType()) + " confidence: " + detectedActivity.getConfidence());
}
});
}
在onDestroy()
我打电话
public void unsubscribeActivityUpdates() {
unsubscribe(filteredActivitySubscription);
}
private void unsubscribe(Subscription subscription) {
if (subscription != null && !subscription.isUnsubscribed()) {
Log.i(TAG, "Unsubscribe activity updates");
try {
subscription.unsubscribe();
} catch (Exception e) {
e.printStackTrace();
}
subscription = null;
}
}
我希望这足以说明如何使用该库,否则随意提问。
答案 1 :(得分:1)
您可以根据需要使用LocationRequest ..
LocationRequest location= new LocationRequest();
我确定构造函数接受了一个值..检查android文档。
因此,通过位置请求,您可以使用
等功能设置间隔,设置最小位移,每隔几秒钟取一个位置或移动的米。
您还可以为此实现locationlistener,每次获取新位置时都会调用它。
最后你需要做的就是从融合的api请求位置更新,并将请求作为参数传递。
答案 2 :(得分:0)
您可以使用FusedLocationProviderApi通知您位置更改,而不是查询当前位置。
您可能希望使用requestLocationUpdates,特别是this version,它最适合用于后台任务。 在LocationRequest中,您可以使用setInterval来定义更新间隔。
关于电池消耗:显然不断打开网络插座(或保持打开状态)以发送您的位置数据并不是最佳解决方案。您的应用应确定何时需要将更新发送到您的服务器。
Google并没有提供直接提取LocationHistory的API,这是他们为自己保留的东西。您可以查询kml位置文件并阅读它,但这不太适合实时监控。