studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones java android google-api location activity-recognition

java - para - manual de programacion android pdf



Actualización de ubicación según el estado del dispositivo (2)

Necesito obtener la ubicación (por la API de ubicación de fused) del usuario después de la Reconocimiento de la actividad. Detectar el estado del usuario (que llama cada 3 minutos), como IN_VEHICLE, ON_FOOT, RUNNING, etc.

En cada evento, necesito la ubicación del usuario después del intervalo regular Por ejemplo:

si el usuario aún está setInterval(5*60*60*1000); , setInterval(5*60*60*1000); y verifique la próxima actualización de ubicación en no antes de 5 horas. Pero ActivityRecognation llamará cada 3 min.

si el usuario se está ejecutando, entonces setInterval(2*60*1000); y verifique la próxima actualización de ubicación en no antes / Después de 2 minutos. Pero ActivityRecognation llamará cada 3 min.

si el usuario se está ejecutando, envíe la ubicación cada 1 min. si el usuario conduce y luego envíe la ubicación cada 15 minutos.

Intenté establecer booleano falso en onConnected en falso y verdadero en el nivel de clase. Pero siempre se convierte en verdad porque se llama al servicio Intent completo después de 3 minutos.

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. }

Problema, estoy actual teniendo

  • ActivityRecognation Obtiene Estado de usuario cada 3 minutos, pero no debe entrar en startLocationFirst boolean hasta que proceda de otro estado startLocationFirst de actividad y mantener la actualización de la ubicación como se establece en startLocationFirst

Aquí está IntentService con FusedLocation

public class Activity_Recognized_Service extends IntentService implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks, LocationListener { /** * Creates an IntentService. Invoked by your subclass''s constructor. * * @param name Used to name the worker thread, important only for debugging. */ public static final String TAG = "###RECOGNISED SRVCE###"; Timer timer; GoogleApiClient LocationAPIclient; LocationRequest mLocationRequest; Location mCurrentLocation; boolean startLocationFirst=true; public Activity_Recognized_Service() { super("Activity_Recognized_Service"); } public Activity_Recognized_Service(String name) { super(name); } @Override protected void onHandleIntent(@Nullable Intent intent) { Log.d(TAG, "On Handle Intent"); if (ActivityRecognitionResult.hasResult(intent)) { Log.d(TAG, "ActivityRecognition Has Result"); ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent); handleDetectedActivities(result.getProbableActivities()); Navigation_Drawer nav = new Navigation_Drawer(); nav.UserMovementResult(result); } } @Override public void onCreate() { super.onCreate(); Log.d(TAG,"On Create Calling"); if (LocationAPIclient == null) { Log.d(TAG, "Location API is NULL Value Of This "); LocationAPIclient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); } } private void handleDetectedActivities(List<DetectedActivity> probableActivities) { for (DetectedActivity activity : probableActivities) { switch (activity.getType()) { case DetectedActivity.IN_VEHICLE: Log.d(TAG, "In Vehicle " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //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(10*60*1000,8*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); if (startLocationFirst){ Log.d(TAG,"Start Location Update For Car"); } } break; case DetectedActivity.ON_BICYCLE: Log.d(TAG, "On Bicycle " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //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()); requestLocatonSetting(7*60*1000,5*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.ON_FOOT: Log.d(TAG, "On Foot " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //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.RUNNING: Log.d(TAG, "On Running " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //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()); requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.STILL: Log.d(TAG, "On Still " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //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()); requestLocatonSetting(5*60*60*1000,3*60*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds // requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.TILTING: Log.d(TAG, "On Tilting " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //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()); requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.WALKING: Log.d(TAG, "On Walking " + activity.getConfidence()); if (activity.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()); requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds LocationAPIclient.connect(); } break; case DetectedActivity.UNKNOWN: Log.d(TAG, "UnKnown " + activity.getConfidence()); break; } } } public void setTimer(int Minutes) { Log.d(TAG, "=================================================="); Log.d(TAG, "Set Timeer Starts It will Run Every " + Minutes); int MilliSeconds = 60000 * Minutes; final Handler handler = new Handler(); timer = new Timer(); TimerTask doAsynchronousTask = new TimerTask() { @Override public void run() { handler.post(new Runnable() { public void run() { try { //CODE THAT YOU WANT TO EXECUTE AT GIVEN INTERVAL } catch (Exception e) { // TODO Auto-generated catch block } } }); } }; timer.schedule(doAsynchronousTask, 0, MilliSeconds); Log.d(TAG, "=================================================="); } @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; } mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(LocationAPIclient); if (mCurrentLocation!=null){ Log.d(TAG,"Last Known Location Is not Null "); 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"); LocationServices.FusedLocationApi.requestLocationUpdates(LocationAPIclient,mLocationRequest,this); } } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } @Override public void onLocationChanged(Location location) { Log.d(TAG,"On Location Changed Calling"); mCurrentLocation=location; new Location_sendeToServer_AsyncTask(this).execute(String.valueOf(mCurrentLocation.getLatitude()),String.valueOf(mCurrentLocation.getLongitude()),String.valueOf(mCurrentLocation.getAccuracy())); Log.d(TAG,"Stopping Location Update"); // LocationServices.FusedLocationApi.removeLocationUpdates(LocationAPIclient,this); } public void requestLocatonSetting(int Interval,int FastestInterval,int LocationAccuracy){ mLocationRequest=new LocationRequest(); mLocationRequest.setInterval(Interval); mLocationRequest.setFastestInterval(FastestInterval); mLocationRequest.setPriority(LocationAccuracy); } }


EDITAR

Aquí hay un mejor ejemplo usando solo el código que ha proporcionado arriba:

Utilice este servicio al registrar su 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); } }

Y este sería el servicio de intención de usar en lugar de utilizar AsyncTask que estaba usando:

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()); } } } }

Este servicio de intención puede manejar el bloqueo de solicitudes de red siempre que se llamen dentro de onHandleIntent .

handleDetectedActivity un poco el código handleDetectedActivity para que en cada actualización de actividad no se produzca una nueva actualización de ubicación.

En primer lugar, no recomendaría que use un servicio de IntentService tal como está ahora, ya que el servicio se onHandleIntent una vez que salga de onHandleIntent , lo que causaría muchos problemas ya que depende de las devoluciones de llamada. Todo esto debería ponerse en un Service .

En cuanto a la gestión de actualizaciones de ubicación basadas en el reconocimiento de actividad, encontré esta bonita biblioteca que simplifica esto y es bastante fácil de usar. https://github.com/mrmans0n/smart-location-lib

Aquí hay un ejemplo de cómo usar la biblioteca con actualizaciones de ubicación basadas en los resultados de la actividad.

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. } });

Esto debe onStart en un Service en la función onStart , con onStartCommand manejando los cambios basados ​​en los extras de intención que usted proporciona. También puede usar esta biblioteca para obtener la última ubicación conocida y obtener una solución única.

Una última cosa, le recomendaría que se aleje de AsyncTask si le está pasando contextos. En su lugar, use IntentService , ya que la función onHandleIntent se ejecuta en una onHandleIntent fondo y puede usar el contexto de IntentService para realizar las tareas que necesite con ella. Puede pasar el objeto Location como un extra en la intención cuando inicie su IntentService .


Ejecuto este código después de agregar algunas líneas al mismo código que el anterior.

  • Primero declaro static int en el nivel de clase en IntentService porque DectectedActivity.getType() return int. static int detectedActivity;
  • Luego, al comprobar si su estado es el mismo que el de la última, if (activity.getConfidence() >= 75 && activity.getType()!=detectedActivity)

Eso es todo. Gracias a @Pablo Baxter, que me dio algún tipo de lógica para aplicar. Probé esto en IntentService pero necesito probarlo en el servicio para poder actualizar las ubicaciones. Pronto lo actualizaré.