Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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);
}
}
like image 952
user1781028 Avatar asked Jul 17 '13 15:07

user1781028


2 Answers

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();
}
like image 117
dan_flo10 Avatar answered Sep 19 '22 22:09

dan_flo10


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!
like image 38
AndroidHacker Avatar answered Sep 20 '22 22:09

AndroidHacker