Alvrey
Alvrey

Reputation: 81

requestLocationUpdates never called in android service

I'm developing android application that reads the latitude and longitude of the user periodically in the background , then checks if the lat and lng is within a predefined boundary or not. If No we shall close the application.

I'm using android service and locationManager for this requirements.However, the below code is worked perfectly fine when I tried to use it in a new android project. but when I add it to my original project the method requestLocationUpdates() is never called .. I have spent 2 days trying to figure out what the main cause of this problem. I have tried all the solution in stack overflow but nothing worked for me.

This is My code

public class LocationControService extends Service {

List<LatLng> pointsList = new ArrayList<>();
private LocationManager locationManager;
double lat;
double lng;
LatLng userLocation;
private static Timer timer = new Timer();


// run on another Thread to avoid crash
private Handler mHandler = new Handler();


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

@Override
public void onCreate() {


    // It Should Be A Query From The DB
    pointsList.add(new LatLng(24.75057, 46.57516));
    pointsList.add(new LatLng(24.81291, 46.74545));
    pointsList.add(new LatLng(24.65076, 46.85119));
    pointsList.add(new LatLng(24.57335, 46.67404));

    locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

    startService();
}

private void startService()
{
    timer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, 10000); }

@Override
public void onDestroy() {
    timer.cancel();}



class TimeDisplayTimerTask extends TimerTask {

    @Override
    public void run() {
        // run on another thread
        mHandler.post(new Runnable() {

            @Override
            public void run() {
                getUserLocation();

            }

        });
    }

}



private void getUserLocation () {


    try {

        Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

        locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER,0 , 0, new LocationListener() {
                    @Override
                    public void onLocationChanged(Location location) {

                        lat = location.getLatitude();
                        lng = location.getLongitude();

                        userLocation = new LatLng( lat,lng);


                        if (isUserWhithinBoundray(userLocation))
                            Toast.makeText(getApplicationContext(),"You Are Within The Boundray", Toast.LENGTH_LONG).show();

                        else {
                            Toast.makeText(getApplicationContext(), "You Are Out Of The Boundray", Toast.LENGTH_LONG).show();
                            // SHOW DIALOG MSG .. OPEN SIGNIN INTENT

                            Intent myIntent = new Intent(LocationControService.this, MyDialog.class);
                            LocationControService.this.startActivity(myIntent);



                        }


                        locationManager.removeUpdates(this);
                    }

                    @Override
                    public void onStatusChanged(String s, int i, Bundle bundle) {

                    }

                    @Override
                    public void onProviderEnabled(String s) {

                    }

                    @Override
                    public void onProviderDisabled(String s) {
                        Toast.makeText(getApplicationContext(),"Turn the GPS on", Toast.LENGTH_LONG).show();
                        Intent viewIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivity(viewIntent);

                    }
                }
        );

    }

    catch (SecurityException e) { }

}




public Boolean isUserWhithinBoundray (LatLng userLocation) {
    return PolyUtil.containsLocation(userLocation,pointsList,false);
}

}

I have added the LOGs @CaoMinhVu Mentioned :

1. print a log inside getUserLocation, before try

 Log.d("Trck","Before Try");

2. print a log inside catch: e.printStackTrace() and print a log here also

  e.printStackTrace();
  Log.d("Trck", e.getMessage() );

3. Print a log inside each callback ( I've done the same for each callbacl )

 Log.d("Trck", "onLocationChanged" );

Here is the result :

 03-17 08:26:22.192 18559-18559/vigilant.com.vigilant.vigilant D/Trck: "network" location provider requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission.
03-17 08:26:32.183 18559-18559/vigilant.com.vigilant.vigilant D/Trck: Before Try
03-17 08:26:32.185 18559-18559/vigilant.com.vigilant.vigilant W/System.err: java.lang.SecurityException: "network" location provider requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission.
03-17 08:26:32.185 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at android.os.Parcel.readException(Parcel.java:1693)
03-17 08:26:32.185 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at android.os.Parcel.readException(Parcel.java:1646)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at android.location.ILocationManager$Stub$Proxy.getLastLocation(ILocationManager.java:792)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at android.location.LocationManager.getLastKnownLocation(LocationManager.java:1205)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at vigilant.com.vigilant.vigilant.LocationControService.getUserLocation(LocationControService.java:100)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at vigilant.com.vigilant.vigilant.LocationControService.access$000(LocationControService.java:30)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at vigilant.com.vigilant.vigilant.LocationControService$TimeDisplayTimerTask$1.run(LocationControService.java:83)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at android.os.Looper.loop(Looper.java:154)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6692)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
03-17 08:26:32.186 18559-18559/vigilant.com.vigilant.vigilant D/Trck: "network" location provider requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission.

Upvotes: 1

Views: 316

Answers (1)

Cao Minh Vu
Cao Minh Vu

Reputation: 1948

It is quite clear now, you need to request permission: ACCESS_CORSE_LOCATION and ACCESS_FINE_LOCATION at runtime. Please read this for sample:

https://developer.android.com/training/permissions/requesting.html

if (ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.ACCESS_CORSE_LOCATION)
    != PackageManager.PERMISSION_GRANTED) {

    // Permission is not granted
    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.ACCESS_CORSE_LOCATION)) {

        // Show an explanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed; request the permission
        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.ACCESS_CORSE_LOCATION},
                0x0);


    }
} else {
    // Permission has already been granted
}

Upvotes: 0

Related Questions