4

I want to create an App which fetch user's location in every 5 min between 9:00 AM to 9:00 PM. Now i am not able to think the flow. I am confused on:

  1. Should i implement 2 repeating alarm managers , one for every 5 min and another one for time slot. ?
  2. Or do it in a way, fire alarm every 5 min and check if it is in between time slot then only run location service and upload to server work. ?

Please help me with suggestions/advice. How to achieve this in best approach in terms of phone battery, efficiency.

young_08
  • 1,106
  • 1
  • 12
  • 32
  • 1
    Before that is it a good idea to locate every 5 minutes? I dont that the phone battery will last till 9PM – Sanoop Surendran Jun 26 '17 at 06:43
  • @Sanoop i know u right. Not a good practice but this is what client requires. – young_08 Jun 26 '17 at 06:44
  • Hi there, Google recently updated API for fetching user location in more efficient way. https://android-developers.googleblog.com/2017/06/reduce-friction-with-new-location-apis.html This may help you. – vijaypalod Jun 26 '17 at 06:49

4 Answers4

0

Well you can use handler for querying the location, you can do something like this

 Handler handler = new Handler();
 Runnable runnable = new Runnable() {
        public void run() {
            currentLocation = getCurrentUserLocation();
            handler.postDelayed(this, 1000*60*5);
        }
    }
 };
 handler.postDelayed(runnable, 1000*60*5);

And for checking the time interval is between, you can set a Alarm manager for this task,

And once time limit is reached, you need to remove the handler callbacks by

handleLocation.removeCallbacksAndMessages(null);
marc_s
  • 675,133
  • 158
  • 1,253
  • 1,388
Sanoop Surendran
  • 3,241
  • 3
  • 24
  • 46
0

You should not use Handler.postDelayer() for time intervals, longer than 30sec, because it may cause memory leaks. Develop a couple of strategies - one for short time intervals - less than 30 secs, which use Handler and another - with AlarmManager (for longer intervals).

Alex Shutov
  • 3,128
  • 2
  • 11
  • 11
  • can i use Firebase job dispatcher, 1 at 9:AM to start service and another one at 9:PM to stop? – young_08 Jun 26 '17 at 07:10
  • I didn't work with Firebase's job dispatcher, but there is one more thing - if you use AlarmManager, you should listen for device reboot events, because resetting device cancels all pending alarms – Alex Shutov Jun 26 '17 at 07:18
0

refer https://codelabs.developers.google.com/codelabs/background-location-updates-android-o/index.html?index=..%2F..%2Findex#0

you can set update interval as 5 min in location request.it is compatible with Android "O" also.

Hardik Mehta
  • 857
  • 10
  • 20
0

Here I have created a service which gives current location at interval of 1 Minute.You can modify it as per your requirement-

Also add this in gradle file-

compile 'com.google.android.gms:play-services:9.4.0'

LocationService.class

import android.Manifest;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import java.text.SimpleDateFormat;
import java.util.Date;

public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener, LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
    protected static final String TAG = "location-updates";
    private static final long day = 24 * 60 * 60 * 1000;
    private static final long hours = 60 * 60 * 1000;
    private static final long minute = 60 * 1000;
    private static final long fiveSec = 5 * 1000;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    @Override
    public void onCreate() {
        super.onCreate();
        mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(minute);
        mLocationRequest.setFastestInterval(5000);
        mLocationRequest.setSmallestDisplacement(0);

        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }
    }


    @Override
    public void onConnected(Bundle bundle) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }


    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
    }

    //Location Listener
    @Override
    public void onLocationChanged(final Location location) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
        String currentDateandTime = sdf.format(new Date());
        Log.e("Location ", location.getLatitude() + " " + location.getLongitude() + " " + currentDateandTime);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        boolean isGranted = false;
        for (int i = 0; i < grantResults.length; i++)
            if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION) && (grantResults[i] == PackageManager.PERMISSION_GRANTED))
                isGranted = true;
        if (isGranted) {
            startService(new Intent(this, LocationService.class));

        } else {

        }
    }
}
PankajSharma
  • 1,946
  • 13
  • 28
  • What implications does this have for battery usage? Would this be more battery efficient than just setting up an AlarmManager to fire every minute and check the location? – Nikaoto Dec 07 '17 at 12:04
  • 1
    Hi @Nikaoto, Yes its more efficient and battery saver because if you use alarm manager to fire request periodically it always check for location check at a regular interval. – PankajSharma Dec 11 '17 at 06:46