我需要在ActivityRecognition检测用户状态(每3分钟调用一次)之后获取用户的位置(通过fusionlocation API),如IN_VEHICLE,ON_FOOT,RUNNING等。
在每个事件中,我需要定期间隔后的用户位置例如:
如果用户仍然是SELECT
sum(if(ticket = 1,1,0)) as child,
sum(if(ticket = 2,1,0)) as adult FROM tickets where ticket in (1,2)
GROUP by ticket
并检查下一个位置
在5小时之前更新。但ActivityRecognation将每3分钟调用一次。
如果用户正在运行setInterval(5*60*60*1000);
并在2分钟之前/之后检查下一个位置更新。但ActivityRecognation将每隔3分钟调用一次。
如果用户正在运行,则每隔1分钟发送一次位置 如果用户正在驾驶,则每隔15分钟发送一次位置。
我试图在setInterval(2*60*1000);
中将boolean false设置为false,并在类级别设置为true。但它总是变成真实的,因为整个意图服务在3分钟后被调用。
onConnected
问题我现在有
if (startLocationFirst){
requestLocatonSetting(5*60*60*1000,3*60*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationAPIclient.connect();// RequestLocation and GoogleAPIClient won't call until device comes from another ActivityRecognation State running,walking etc. And keep Updating location every 5 hours.
}
布尔值,直到它来自另一个ActivityRecognation状态并保持更新位置startLocationFirst
这是带有FusedLocation的IntentService
startLocationFirst
答案 0 :(得分:1)
我在向上面的相同代码添加几行之后执行此代码。
IntentService
的类级别声明static int,因为DectectedActivity.getType()
返回int。 static int detectedActivity;
if (activity.getConfidence() >= 75 && activity.getType()!=detectedActivity)
那就是了。感谢@Pablo Baxter,他给了我一些应用的逻辑。我在IntentService
测试了这个,但我需要在服务上测试它,这样我就可以更新位置。会更新很快。
答案 1 :(得分:0)
修改强>
以下是仅使用您在上面提供的代码的更好示例:
注册ActivityRecognitionApi时使用此服务:
public class LocationUpdateService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
public static final String TAG = "###RECOGNISED SRVCE###";
private GoogleApiClient apiClient;
private PendingIntent pendingIntent;
private DetectedActivity lastActivity;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
apiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
apiClient.connect();
pendingIntent = PendingIntent.getService(this, 1, new Intent(this, YourIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public int onStartCommand(Intent intent, int flag, int startId) {
Log.d(TAG, "onStartCommand");
if (ActivityRecognitionResult.hasResult(intent)) {
Log.d(TAG, "ActivityRecognition Has Result");
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
handleDetectedActivity(result);
/* You should really use LocalBroadcastManager to send events out to an activity for UI updates */
// Navigation_Drawer nav = new Navigation_Drawer();
// nav.UserMovementResult(result);
}
return START_STICKY;
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.d(TAG, "On Connected Running");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(apiClient);
if (location!=null){
Log.d(TAG,"Last Known Location Is not Null ");
Intent intent = new Intent(this, YourIntentService.class).putExtra("lastKnown", location);
startService(intent);
/* No more need for this! */
// new Location_sendeToServer_AsyncTask(this).execute(String.valueOf(mCurrentLocation.getLatitude()),String.valueOf(mCurrentLocation.getLongitude()),String.valueOf(mCurrentLocation.getAccuracy()));
}
else {
Log.d(TAG,"Last Known Location Is NULL Start Location Updates");
updateLocationSetting(5*60*60*1000,3*60*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY);
// LocationServices.FusedLocationApi.requestLocationUpdates(apiClient,mLocationRequest,this);
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
private void handleDetectedActivity(ActivityRecognitionResult result) {
DetectedActivity mostProbableActivity = result.getMostProbableActivity();
switch (result.getMostProbableActivity().getType()) {
case DetectedActivity.IN_VEHICLE:
// Log.d(TAG, "In Vehicle " + activity.getConfidence());
if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) {
//Send Notification To User
// NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// builder.setContentText("In Vehicle");
// builder.setSmallIcon(R.drawable.elaxer_x);
// builder.setContentTitle("Elaxer");
// NotificationManagerCompat.from(this).notify(0, builder.build());
//requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST
if (apiClient.isConnected()) {
updateLocationSetting(10 * 60 * 1000, 8 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
lastActivity = mostProbableActivity;
}
}
break;
case DetectedActivity.ON_BICYCLE:
Log.d(TAG, "On Bicycle " + mostProbableActivity.getConfidence());
if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) {
//Send Notification To User
// NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// builder.setContentText("On Bicycle");
// builder.setSmallIcon(R.drawable.elaxer_x);
// builder.setContentTitle("Elaxer");
// NotificationManagerCompat.from(this).notify(0, builder.build());
if (apiClient.isConnected()) {
updateLocationSetting(7 * 60 * 1000, 5 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
lastActivity = mostProbableActivity;
}
}
break;
case DetectedActivity.ON_FOOT:
Log.d(TAG, "On Foot " + mostProbableActivity.getConfidence());
if (mostProbableActivity.getConfidence() >= 75) {
DetectedActivity nextHighest = result.getProbableActivities().get(1);
if (nextHighest.getType() == DetectedActivity.RUNNING && nextHighest != lastActivity) {
Log.d(TAG, "On Running " + mostProbableActivity.getConfidence());
//Send Notification To User
// NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// builder.setContentText("Running");
// builder.setSmallIcon(R.drawable.elaxer_x);
// builder.setContentTitle("Elaxer");
// NotificationManagerCompat.from(this).notify(0, builder.build());
if (apiClient.isConnected()) {
updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
lastActivity = nextHighest;
}
}
else if (nextHighest.getConfidence() >= 75 && nextHighest != lastActivity) {
Log.d(TAG, "On Walking " + mostProbableActivity.getConfidence());
//Send Notification To User
// NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// builder.setContentText("Let's Walk");
// builder.setSmallIcon(R.drawable.elaxer_x);
// builder.setContentTitle("Elaxer");
// NotificationManagerCompat.from(this).notify(0, builder.build());
if (apiClient.isConnected()) {
updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
lastActivity = nextHighest;
}
}
//Send Notification To User
// NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// builder.setContentText("On Foot");
// builder.setSmallIcon(R.drawable.elaxer_x);
// builder.setContentTitle("Elaxer");
// NotificationManagerCompat.from(this).notify(0, builder.build());
}
break;
case DetectedActivity.STILL:
Log.d(TAG, "On Still " + mostProbableActivity.getConfidence());
if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) {
//Send Notification To User
// NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// builder.setContentText("Still");
// builder.setSmallIcon(R.drawable.elaxer_x);
// builder.setContentTitle("Elaxer");
// NotificationManagerCompat.from(this).notify(0, builder.build());
if (apiClient.isConnected()) {
updateLocationSetting(5 * 60 * 60 * 1000, 3 * 60 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
lastActivity = mostProbableActivity;
}
}
break;
case DetectedActivity.TILTING:
Log.d(TAG, "On Tilting " + mostProbableActivity.getConfidence());
if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) {
//Send Notification To User
// NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// builder.setContentText("Tilting");
// builder.setSmallIcon(R.drawable.elaxer_x);
// builder.setContentTitle("Elaxer");
// NotificationManagerCompat.from(this).notify(0, builder.build());
if (apiClient.isConnected()) {
updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
lastActivity = mostProbableActivity;
}
}
break;
// case DetectedActivity.WALKING:
// Log.d(TAG, "On Walking " + mostProbableActivity.getConfidence());
// if (mostProbableActivity.getConfidence() >= 75) {
// //Send Notification To User
// NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// builder.setContentText("Let's Walk");
// builder.setSmallIcon(R.drawable.elaxer_x);
// builder.setContentTitle("Elaxer");
// NotificationManagerCompat.from(this).notify(0, builder.build());
//
// if (apiClient.isConnected()) {
// updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
// }
// }
// break;
case DetectedActivity.UNKNOWN:
Log.d(TAG, "UnKnown " + mostProbableActivity.getConfidence());
lastActivity = mostProbableActivity;
break;
}
}
private void updateLocationSetting(int Interval, int FastestInterval, int LocationAccuracy) {
LocationRequest request = new LocationRequest();
request.setInterval(Interval);
request.setFastestInterval(FastestInterval);
request.setPriority(LocationAccuracy);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) {
//TODO DO SOMETHING HERE!
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, request, pendingIntent);
}
}
这将是使用的IntentService,而不是使用您正在使用的AsyncTask:
public class YourIntentService extends IntentService {
public YourIntentService() {
super("YOUR_INTENT_SERVICE");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
if (intent != null) {
if (LocationResult.hasResult(intent)) {
LocationResult result = LocationResult.extractResult(intent);
Location location = result.getLastLocation();
Log.d("YourIntentService", "Got new location: " + location);
}
else if (intent.hasExtra("lastKnown")) {
Location location = intent.getParcelableExtra("lastKnown");
Log.d("YourIntentService", "Got last known location: " + location);
}
else if (LocationAvailability.hasLocationAvailability(intent)) {
LocationAvailability locationAvailability = LocationAvailability.extractLocationAvailability(intent);
Log.d("YourIntentService", "Location Availability: " + locationAvailability.isLocationAvailable());
}
}
}
}
只要在onHandleIntent
内调用它们,此意图服务就可以处理阻止网络请求。
我稍微修改了handleDetectedActivity
代码,以便在每次活动更新时都不会发生新的位置更新。
首先,我建议你不要像现在这样使用IntentService
,因为服务会在退出onHandleIntent
后被杀死,这会导致很多问题,因为你依赖在回调上。所有这些都应该放在Service
中。
至于处理基于活动识别的位置更新,我确实找到了这个简化了这个并且非常易于使用的漂亮库。 https://github.com/mrmans0n/smart-location-lib
以下是如何根据活动结果使用具有位置更新的库的示例。
SmartLocation.with(this).location(new LocationBasedOnActivityProvider(new LocationBasedOnActivityProvider.LocationBasedOnActivityListener() {
@Override
public LocationParams locationParamsForActivity(DetectedActivity detectedActivity) {
if (detectedActivity.getConfidence() >= 75) {
LocationParams.Builder builder = new LocationParams.Builder();
switch (detectedActivity.getType()) {
case DetectedActivity.IN_VEHICLE:
builder.setInterval(/*Interval*/)
.setAccuracy(/*Locaiton Accuracy*/);
break;
case DetectedActivity.ON_BICYCLE:
/* So on and so forth.... */
break;
}
return builder.build();
}
return null;
}
})).start(new OnLocationUpdatedListener() {
@Override
public void onLocationUpdated(Location location) {
//Do what you need here.
}
});
这应放入Service
函数中的onStart
,onStartCommand
根据您提供的意图附加内容处理更改。您还可以使用此库获取最后的已知位置,并获得单个修复。
最后一件事,如果您要传递背景,我会建议您远离AsyncTask
。而是使用IntentService
,因为onHandleIntent
函数在后台线程中运行,您可以使用IntentService
上下文来执行您需要的任何任务。当您开始Location
时,您可以在意图中将IntentService
对象作为额外内容传递。