Reputation: 81
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.
I have added these permission (ACCESS_FINE_LOCATION , ACCESS_COARSE_LOCATION)
I have added these dependenies
implementation 'com.google.android.gms:play-services-maps:11.8.0' compile 'com.google.maps.android:android-maps-utils:0.5'
I have tried both providers (GPS and Network)
I'm Calling this service in my main activity
I've add the service in my manifest
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
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