1

I have been trying to receive location updates when my phone is locked I am using a service that is launched by my main activity. I receive location updates when the application is open just fine but when locking the phone the service continues to run but the location stored is the same every time.

import static com.example.kromby.mapsapplication.featureOptions.date;


public class BackgroundLocationUpdate extends Service implements GoogleApiClient.ConnectionCallbacks, LocationListener {

// I've removed code that does not relate to the question so please ignore most imports. 

    private GoogleApiClient mClient;

    private boolean connected = false;

    private LocationRequest mLocationRequest;

    public static List<LatLng> globalLatLng = Collections.synchronizedList(new ArrayList<LatLng>());

    public static GoogleMap mMap;

    Location mLastLocation;

    private static double latitude;

    private static double longitude;

    public LatLng mLatLng = new LatLng(latitude, longitude);

    private static final String TAG = "MapActivity";

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

    @TargetApi(Build.VERSION_CODES.O)
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Runnable r = new Runnable() {

            @Override
            public void run() {
                buildGoogleApiClient();
            }
        };

        Runnable q = new Runnable() {

            @Override
            public void run() {

                long p = System.currentTimeMillis() + 4000;

                boolean continueLooping = true;

                while (continueLooping) {

                    if (System.currentTimeMillis() >= p) {

                        locationUpdates();

                        continueLooping = false;
                    }
                }
            }
        };

        Thread mThread = new Thread(r);

        Thread mThreadTwo = new Thread(q);

        mThread.start();

        mThreadTwo.start();

        return Service.START_STICKY;
    }

    public void locationUpdates() {

        long i = System.currentTimeMillis();

        while (true) {

              if (System.currentTimeMillis() == i) {

                  i = System.currentTimeMillis() + 3000;

                  // Checks that the application has user permissions to location.

                  if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED 
                      && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                      return;
                  }

                  mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mClient);

                  // Once the phone is locked this will return the same location each time and not change.

                  Log.d(TAG, "Client is working " + mClient.isConnected() + "\n Current mLastLocation LatLng " + mLastLocation.getLatitude() + "," + mLastLocation.getLatitude());

                  latitude = mLastLocation.getLatitude();

                  longitude = mLastLocation.getLongitude();

                  Log.d(TAG, "latitude = " + String.valueOf(latitude) );

                  mLatLng = new LatLng(latitude, longitude);

                  globalLatLng.add(mLatLng);

                  Log.d(TAG, "Global List = " + globalLatLng);

            }
        }
    }

    protected synchronized void buildGoogleApiClient() {

        mClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addApi(LocationServices.API).build();

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }

        mClient.connect();
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {

        connected = true;

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(3000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        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(mClient, mLocationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int i) {

        mClient.connect();
    }

    @Override
    public void onDestroy() {

        Log.i(TAG, "OnDestroy method called");
    }
}

My aim is to receive a location save that into a Latlng list and store it into a text file, that can be read and shown on the map in a polyline. I am running them on two seperate threads because googles api clients does not finish so it wont reach any other code.

M. Prokhorov
  • 3,894
  • 25
  • 39
Ricky
  • 11
  • 1
  • Why did you decide to roll your own thread instead of implementing LocationListener? – M. Prokhorov Apr 04 '18 at 15:43
  • From what I tried the location listener did not work in the background at all. – Ricky Apr 04 '18 at 15:49
  • I doubt that using first-class way of receiving update is better than manually rolled one. What type is this service in particular? Have you read [this article](https://developer.android.com/about/versions/oreo/background-location-limits.html)? – M. Prokhorov Apr 04 '18 at 16:05
  • I think you will need a PowerManager.WakeLock to keep the CPU from sleeping while screen if off. – user221256 Apr 04 '18 at 16:05
  • @user221256, no, not really. He needs the app to still work even when screen is turned off, not keep the phone from turning it off. – M. Prokhorov Apr 04 '18 at 16:18
  • @M.Porkhorov Its an intent service I think? – Ricky Apr 04 '18 at 16:19
  • It's just weird how it works, its retrieving a location but the location is the same each time after the phone is locked – Ricky Apr 04 '18 at 16:21
  • @M.Prokhorov Turning screen off, will after a while cause the CPU to sleep. Regular WakeLock prevents both turning screen off and CPU from sleeping. Partial WakeLock allows turning off the screen while keeping the CPU from sleeping. – user221256 Apr 04 '18 at 16:23
  • @Ricky, no, I mean, is it a foreground or backrgound service? There is a big difference between them in later Android versions. Refer to the article I've linked. The behavior is not weird, your app just doesn't receive *updates*, but you call a method to receive last known location. Without updates, last known location won't change. – M. Prokhorov Apr 04 '18 at 16:25
  • @user221256, if CPU was sleeping, he wouldn't be writing into a list at all. I still don't think this is a problem to solve via wake-locks. – M. Prokhorov Apr 04 '18 at 16:26
  • @M.Prokhorov Is there a way to check which one I am using? I'm not really sure. – Ricky Apr 04 '18 at 16:34
  • @user221256 If I was to implement a wake lock where do I put it ? – Ricky Apr 04 '18 at 16:35
  • @Ricky, it depends on the code which you use to start the service. Foreground service uses [startForeground](https://developer.android.com/reference/android/content/Context.html#startForegroundService(android.content.Intent)). I again advise to read the article which talks about [changes to background processes in Android O](https://developer.android.com/about/versions/oreo/background-location-limits.html) – M. Prokhorov Apr 04 '18 at 16:42
  • @Ricky It depends on your service design, but probably declare it as field in your service. Call `WakeLock.acquire()` when you start listening for updates and `WakeLock.release()` when you stop. Do not hold the WakeLock if not required as this can result in an increased battery drain. I really recommend you to read the docs: https://developer.android.com/reference/android/os/PowerManager.WakeLock.html. If you are going to try this. – user221256 Apr 04 '18 at 16:47
  • @M.Prokhorov the service is started on the main application in the foreground – Ricky Apr 04 '18 at 16:53
  • you can check my answer here : https://stackoverflow.com/a/50245508/6033946 – iDeveloper May 09 '18 at 05:17

0 Answers0