i'm developing an application that uses Google Maps to update the location. So far, i have had only one issue and that is of access fine location permission. This is my Manifest file.
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- Network State Permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- <android:uses-permission android:name="android.permission.READ_PHONE_STATE" /> -->
<!-- <android:uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> -->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="@string/title_activity_maps" >
</activity>
<activity
android:name=".HelpMe"
android:label="@string/title_activity_help_me"
android:theme="@style/AppTheme" >
</activity>
<service
android:name=".MyLocationUpdate"
android:exported="false" >
</service>
</application>
This is my IntentService through which i'll pass the control over to my service class.
public class MyLocationUpdate extends IntentService {
double latitude,longitude;
AppLogic app = new AppLogic();
HelpMe activity;
IETrackerDTO iedto= new IETrackerDTO();
public MyLocationUpdate() {
super("MyLocationUpdate");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d("Inside", "Intent Service");
/*IETrackerDTO ide = intent.getExtras().("currentUser");*/
ScheduledThreadPoolExecutor s = new ScheduledThreadPoolExecutor(1);
s.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
LocationFinder gps;
Log.d("Calling other service", "Calling other service");
gps = new LocationFinder(MyLocationUpdate.this);
latitude = gps.getLatitude();
longitude = gps.getLongitude();
Log.d("Location", latitude + " " + longitude);
updateLocation();
toast();
}
}, 0, 10, TimeUnit.SECONDS);
}
public void toast() {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "Lat: " + latitude + " long:" + longitude, Toast.LENGTH_SHORT).show();
}
});
}
This is my Service class that updates the lat long of the user on a timely basis
public class LocationFinder extends Service implements LocationListener {
private final Context mContext;
static Class<? extends Context> activity;
// flag for GPS status
// boolean isGPSEnabled = false;
boolean canGetLocation = false;
// flag for network status
// boolean isNetworkEnabled = false;
// flag for GPS status
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
public LocationFinder(Context context) {
Log.d("Inside constructor", "Inside Constructor");
this.mContext = context;
Log.d("After setting context", "After setting context");
getLocation();
}
public Location getLocation() {
Log.d("Inside getLocation", "Inside getLocation");
Log.d("Inside doInBackground", "Inside doInBackground");
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
Log.d("Inside enabled", "Inside enabled");
this.canGetLocation = true;
if (isNetworkEnabled) {
Log.d("Inside networ enabled", "Inside network enabled");
if (locationManager != null) {
new Thread(){
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler()
{
public void handleMessage(Message msg) {
if (ActivityCompat.checkSelfPermission(mContext,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && mContext.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// public void requestPermissions(@NonNull String[] permissions, int requestCode)
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
});
}
};
Looper.loop();
}
}.start();
}/**/
/*locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, (LocationListener) this);*/
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
Log.d("Inside gps enabled", "Inside gps enabled");
if (location == null) {
new Thread(){
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler()
{
public void handleMessage(Message msg) {
if (ActivityCompat.checkSelfPermission(mContext,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && mContext.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// public void requestPermissions(@NonNull String[] permissions, int requestCode)
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
});
}
};
Looper.loop();
}
}.start();
/* locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);*/
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app
* */
public void stopUsingGPS() {
if (locationManager != null) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// public void requestPermissions(@NonNull String[] permissions, int requestCode)
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
}
locationManager.removeUpdates(LocationFinder.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
* @return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog
* On pressing Settings button will lauch Settings Options
* */
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS is settings");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
@Override
public void onLocationChanged(Location location) {
getLocation();
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
Everything is running just fine except for the fact that compiler asks for location permission and without that the control doesn't passes to the service class method
Here's my logcat
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Calling other service﹕ Calling other service
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside constructor﹕ Inside Constructor
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/After setting context﹕ After setting context
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside getLocation﹕ Inside getLocation
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside doInBackground﹕ Inside doInBackground
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside enabled﹕ Inside enabled
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside gps enabled﹕ Inside gps enabled
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/GPS Enabled﹕ GPS Enabled
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ java.lang.SecurityException: "gps" location provider requires ACCESS_FINE_LOCATION permission.
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.os.Parcel.readException(Parcel.java:1599)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.os.Parcel.readException(Parcel.java:1552)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.location.ILocationManager$Stub$Proxy.getLastLocation(ILocationManager.java:717)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.location.LocationManager.getLastKnownLocation(LocationManager.java:1200)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at com.mindtree.igxbridge.getuseraddress.LocationFinder.getLocation(LocationFinder.java:206)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at com.mindtree.igxbridge.getuseraddress.LocationFinder.<init>(LocationFinder.java:59)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at com.mindtree.igxbridge.getuseraddress.MyLocationUpdate$1.run(MyLocationUpdate.java:56)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:278)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:270)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Location﹕ 0.0 0.0
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside updateLocatiion﹕ Inside UpdateLocation
02-11 11:05:57.050 2114-2131/com.mindtree.igxbridge.getuseraddress W/EGL_emulation﹕ eglSurfaceAttrib not implemented
02-11 11:05:57.050 2114-2131/com.mindtree.igxbridge.getuseraddress W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f4e5aaabf40, error=EGL_SUCCESS
02-11 11:05:59.000 2114-2131/com.mindtree.igxbridge.getuseraddress E/Surface﹕ getSlotFromBufferLocked: unknown buffer: 0x7f4e5a8b93f0