Can't receive LocationClient's location updates after screen gone off
Asked Answered
P

3

7

I'm trying to write a simple Android Service that runs in background and receives location updates from LocationClient (Google Map API Android V2). The problem is that when the screen go off, my Service doesn't receives anymore location updates. I tried to check if the service was active, even with screen off, and it does (I have a TimerTask scheduling a log). When screen is on I can receive location updates, but when screen goes off I see only TimerTask's logs and I don't receive any location update. Waking up screen turns on location updates again. How can this be solved?

Here is my simple service:

public class LocationService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener{

private static final String TAG = LocationService.class.getSimpleName();

private LocationClient mLocationClient;

private Timer timer;
private static final LocationRequest REQUEST = LocationRequest.create()
          .setInterval(5*1000)      // 5 seconds
          .setFastestInterval(3*1000) // 3 seconds
          .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);


@Override
public void onCreate() {
    Log.d(TAG, "Creating..");
    mLocationClient = new LocationClient(this, this, this);
    timer = new Timer();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "Starting..");
    if(!mLocationClient.isConnected() || !mLocationClient.isConnecting()) {
        Log.d(TAG, "Connecting location client..");
        mLocationClient.connect();
    }
    timer.scheduleAtFixedRate(new TimerTask(){
        @Override
        public void run() {
            Log.d(TAG, "TimerTask executing");
        }}, 0, 3*1000);
    return START_STICKY;
}

@Override
public void onConnectionFailed(ConnectionResult result) {
    Log.d(TAG, "Connection failed..");
    stopSelf();
}

@Override
public void onConnected(Bundle bundle) {
    System.out.println("Connected ...");
    mLocationClient.requestLocationUpdates(REQUEST, this);
}

@Override
public void onDisconnected() {
    Log.d(TAG, "Disconnected..");
    stopSelf();
}

@Override
public IBinder onBind(Intent arg0) {
    throw new UnsupportedOperationException("Not yet implemented");
}

@Override
public void onLocationChanged(Location location) {
    Log.d(TAG, "Received location update");
}

@Override
public void onDestroy() {
    Log.d(TAG, "Destroying..");
    timer.cancel();
    mLocationClient.removeLocationUpdates(this);
}
}
Petrography answered 17/7, 2013 at 15:25 Comment(5)
I Have the same problem. I can't solve it. Any news? Is it a bug?Tricorn
add a bounty you too, in order to put more reward on the question...Tricorn
could you accept the editing? could you start a bounty? @PetrographyTricorn
@User1781028, can you tell me why created a separate thread (timer) in this service. Thanks youCrabtree
I have the same problem, using the LocationManager didn't solve the problem. I was thinking about using the wakeLock but it would drain the battery too fast..Jump
N
2

Use WakeLock

in onStartCommand

wl = ((PowerManager)getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, yourTAG);
wl.acquire();

in onDestroy

if (wl != null && wl.isHeld()) {
    wl.release();
}
Nkrumah answered 22/11, 2013 at 18:12 Comment(0)
E
1

Update:--

Firstly you need to define LocationClient in your OnCreate() which will call your onConnected() ...

Define you locationClient like this ..

locationClient = new LocationClient(this, this, this);
        locationClient.connect();

Now in your onConnected() .. Just request for Location update like this..

@Override
    public void onConnectionFailed(ConnectionResult arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onConnected(Bundle arg0) {
        src = locationClient.getLastLocation();
        System.out.println("======================location 1==" + src);


        LocationRequest lrequest = new LocationRequest();
        lrequest.setInterval(0);
        lrequest.setSmallestDisplacement(0);
        lrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        locationClient.requestLocationUpdates(lrequest, new LocationListener() {

            @Override
            public void onLocationChanged(Location arg0) {
                 System.out.println("======================location 1233==" +
                 arg0);
                /*Toast.makeText(getApplicationContext(),
                        "Location is 12" + arg0.getLatitude(),
                        Toast.LENGTH_SHORT).show();*/


            }
        });


    }

    @Override
    public void onDisconnected() {
        // TODO Auto-generated method stub

    }

*************** BEFORE ************

If your main concern is finding your location update continually.. then U can use undermentioned.

Use this :: ( This will periodically update user's location based on GPS )

For OnCreate()::
----------------------

@Override
        protected void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.speed);


            initui();

            lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            provider = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);

            if(!provider){
                String text = "ENABLE GPS TO ACCESS SPEEDO METER!";
                Toast.makeText(Speedometer.this, text, Toast.LENGTH_LONG).show();
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(intent);

            }

            if (location != null) {

                /*lat = (int) (location.getLatitude() * 1E6);
                longi = (int)(location.getLongitude() * 1E6);*/
                String text = "Got Coordinates";
                Toast.makeText(Speedometer.this, text, Toast.LENGTH_SHORT).show();

            }
            //lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 2, this);
        }


Now use onLocationChanged()
---------------------------


@Override
        public void onLocationChanged(Location loc) {
            // TODO Auto-generated method stub

            float distance = 0;
            //float prevDis = 0;

            try{
            if(prevLoc==null)
            {
                prevLoc = loc;
                //Toast.makeText(MainActivity.this, "PrevLOC" + prevLoc, Toast.LENGTH_SHORT).show();
                Log.i("Main Activity", "Prev LOC" + prevLoc);
            }
            else {
                try{
                Runtime r = Runtime.getRuntime();
                r.gc();
                }catch(Exception e){
                    e.printStackTrace();
                }
                // When prevLoc is not null
                Log.i("Main Activity", "Prev LOC in new LOC BLAH BLAH BLAH" + prevLoc);
                newLoc = loc;
                //Toast.makeText(MainActivity.this, "NewLoc" + newLoc, Toast.LENGTH_SHORT).show();
                Log.i("Main Activity", "New LOC" + newLoc);
                distance = prevLoc.distanceTo(newLoc);
                Log.i("Main Activity", "New DISTANCE DISTANCE DISTANCE DISTANCE DISTANCE DISTANCE " + distance);

                distance = (float) (3.6*distance); 
                speed = distance;
                prevLoc = newLoc;
                Log.i("Main Activity", "New Coordinates set to PrevLoc" + prevLoc);
            }

            }catch(Exception e){
                e.printStackTrace();
            }


            if(speed <= 160){

                try
                {
                mView.calculateAngleOfDeviation(speed);
                }
                catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }else
            {
                Toast.makeText(Speedometer.this, "CONTROL SPEED", Toast.LENGTH_SHORT).show();
            }

        }

You can also utilize same in your activity ::
-----------------------------------------------

@Override
        public void onProviderDisabled(String provider) {
            // TODO Auto-generated method stub
        }
        @Override
        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub
        }
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // TODO Auto-generated method stub
        }
        @Override
        protected void onPause() {
            // TODO Auto-generated method stub
            stopListening();
            super.onPause();
        }
        private void stopListening() {
            // TODO Auto-generated method stub
            try{
            if(lm != null){
                lm.removeUpdates(this);
            }else{
                lm.removeUpdates(this);
                 }
            }catch(Exception e){
                e.printStackTrace();
            }
        }



        @Override
        protected void onResume() {
            // TODO Auto-generated method stub
            super.onResume();
            startListening();
        }

        private void startListening() {
            // TODO Auto-generated method stub
            try{
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
            }catch(Exception e){
                e.printStackTrace();
            }
        }

        @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
            lm.removeUpdates(Speedometer.this);
            //System.exit(0);
            finish();
        } 



Finally there's always a lot of way to do single thing.
Hope it helps... 
Cheers!
Eyewash answered 1/11, 2013 at 7:53 Comment(3)
the question is about LocationClient not LocationManager. your solution, could be a workaround. It could be acceptable if you well explain why Location Client is not working as expected.Tricorn
Defiantly what I stated above was a workaround .. for your own specific concern have U tried " PARTIAL_WAKE_LOCK " that helps your app not to go in sleep mode. Try this.Eyewash
last comments on the following thread are mine. the wake lock doesn't solve the problem: #17614388Tricorn
F
0

I'm not sure where your problem is. I've made a project with your code and it seems to be working as desired here. I received updates even when the screen was off. In any case here are the steps that I took, perhaps your problem isn't in the service, but in how you start it, or somewhere else:

  1. I created a default android project with a single main activity.
  2. I included your code in a separate file named "LocationService"
  3. I added the google play service library to the project.
  4. I added the following permissions to the manifest:

    < uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> < uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

and in the application tag I declared the service:

   <service
        android:name=".LocationService"
        android:process=":Location_Service_Test" />

finally I added the following to the onCreate of the main activity:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //Start the service
    Intent service = new Intent(this, LocationService.class);
    startService(service);
} 

If this doesn't solve your problem: please include the rest of your code.

Frankhouse answered 30/10, 2013 at 16:21 Comment(6)
i edited the question, let's wait it is reviewed by the author. anyway, i posted the entire code. I did exactly what you did.Tricorn
on the logcat i can see the "timertask" continuously executing, but the "Received location update" is shown only when the screen is on. My smartphone is android 4.2.1. what about yours?Tricorn
did you simulate the location changes?Tricorn
I get the "Received location update" log when the screen is off. I'm running on android 4.3 and I didn't simulate the location changes. Here's the android project, see if you missed anything: s000.tinyupload.com/?file_id=81195373734373847745Frankhouse
I unzipped your folder on my desktop, i imported in android and launched. same effect. when i lock the screen i don't receive updates. Could you send me even the apk generated with your code? If it is not a compile problem, it could be related to android versionTricorn
my compiled apk, gives the same effect even on android 2.2Tricorn

© 2022 - 2024 — McMap. All rights reserved.