Can't turn on location on android api23? - android

I have used the following code and the dialogue that asks for permission shows as expected. But when I click "allow" it doesn't do anything. The log message doesn't appear as if the permission wasn't granted so I went to my parameters to verify if location is "on" and it was "off". Wasn't it supposed to be on because I granted the app access to my location ?
If I manually turn it "on" and then run the app again, once it asks for my permission, it works and shows the log message but isn't the whole point of asking for permissions (via dialogue) to turn on location (when it's off) if the user clicks "allow" ?
Am I doing something wrong ? I should mention that I'm running the app on api23
is is the code in my Oncreate:
mApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mApiClient.connect();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
and this is my OnConnected method:
public void onConnected(#Nullable Bundle bundle) {
//start the service
//checking and asking for permission
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSION_ACCESS_FINE_LOCATION);
}
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(mApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mApiClient, mLocationRequest, this);
} else {
//If everything went fine lets get latitude and longitude
currentLatitude = location.getLatitude();
currentLongitude = location.getLongitude();
Log.v("currentLatitude",currentLatitude + " WORKS " + currentLongitude + "");
}
}

try this code:
private LocationCoord gps = null;
private static final int PERMISSION_REQUEST_CODE = 1;
In OnCreate():
//GPS Manage
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean gps_enabled = false;
boolean network_enabled = false;
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
}
try {
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
}
if (!gps_enabled && !network_enabled) {
// notify user
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setMessage("Allow ImHere to access this device's location?");
dialog.setPositiveButton("Allow", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
//get gps
}
});
dialog.setNegativeButton("Deny", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
}
});
dialog.show();
}
gps = new LocationCoord(this);
#Override
protected void onStart() {
super.onStart();
// permission android 6.0
if (!checkPermission()) {
requestPermission();
}
}
private boolean checkPermission(){
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
if (result == PackageManager.PERMISSION_GRANTED) return true;
else return false;
}
private void requestPermission(){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_CODE);
}
You will need this permissions on the Manifest.xml:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
You can get LoocationCord.java here: https://github.com/toomyy94/ImHere-Chatbot/blob/master/app/src/main/java/pt/ua/tomasr/imhere/modules/LocationCoord.java

you might have to add a dependency in your build.gradle:
compile 'com.google.android.gms:play-services-location:10.0.1

Related

Unable to view current coordinates on button click in android studio

I am creating an app which will get a user name from DB and print the ID and then on button click it will show the current GPS coordinates. I have implemented it but don't know why its not working.
Here is my Manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Below is my MainActivity.java
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final String TAG = "MainActivity";
private TextView tv_lat;
private TextView tv_long;
private Button btn_loc;
private GoogleApiClient googleApiClient;
private Location location;
private LocationManager mLocationManager;
private LocationManager locationManager;
private LocationRequest locationRequest;
private LocationListener locationListener;
private long UPDATE_INTERVAL = 2 * 1000; /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_lat = (TextView)findViewById(R.id.tv_lat);
tv_long = (TextView)findViewById(R.id.tv_long);
btn_loc = (Button)findViewById(R.id.btn_loc);
// show location button click event
btn_loc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
googleApiClient = new GoogleApiClient.Builder(MainActivity.this)
.addConnectionCallbacks(MainActivity.this)
.addOnConnectionFailedListener(MainActivity.this)
.addApi(LocationServices.API)
.build();
}
});
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
checkLocation(); //check whether location service is enable or not in your phone
}
#Override
public void onConnected(Bundle bundle) {
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED )
{
// TODO: Consider calling
// ActivityCompat#requestPermissions
// 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 ActivityCompat#requestPermissions for more details.
return;
}
startLocationUpdates();
location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if(location == null)
{
startLocationUpdates();
}
if (location != null)
{
}
else {
Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection Suspended");
googleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode());
}
#Override
protected void onStart() {
super.onStart();
if (googleApiClient != null) {
googleApiClient.connect();
}
}
#Override
protected void onStop() {
super.onStop();
if (googleApiClient.isConnected()) {
googleApiClient.disconnect();
}
}
private void startLocationUpdates() {
// Create the location request
locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
// Request location updates
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED )
{
// TODO: Consider calling
// ActivityCompat#requestPermissions
// 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 ActivityCompat#requestPermissions for more details.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient,
locationRequest, this);
Log.d("reque", "--->>>>");
}
#Override
public void onLocationChanged(Location location) {
double lattitude = location.getLatitude();
double longitude = location.getLongitude();
String msg = "Updated Location: " +
Double.toString(lattitude) + " , " +
Double.toString(longitude);
tv_lat.setText("Latitude is " + lattitude );
tv_long.setText("Longitude is " + longitude);
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
// You can now create a LatLng Object for use with maps
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
}
private boolean checkLocation() {
if(!isLocationEnabled())
showAlert();
return isLocationEnabled();
}
private boolean isLocationEnabled() {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void showAlert() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("Enable Location")
.setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
"use this app")
.setPositiveButton("Location Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
}
});
dialog.create().show();
}
}
else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
}
}
When i run my app on the my device, below result is shown
When i click on the get location coordinates nothing happens. Also no errors or warnings are shown in logcat.
Update 1
I have moved all the code outside from the button click event
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
And then debugged it, and i got the below result.
I don't know why the coordinates are not showing :(
Any help would be highly appreciated.
When your device is over Android 6.0 Marshmallow, you have to check, that the location permission is allowed in the application settings. You can turn it manually in the settings on or you use the runtime permission library. I've found a very useful library for that: https://github.com/ParkSangGwon/TedPermission
go to mobile settings-->location settings
check whether your mobile GPS service is on or off
and turn on if it is off.
hope this helps.

How to grant ACCESS_FINE_LOCATION permission in Lollipop?

I'm using the following code to check for and request permission for GPS:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION }, 1);
}
I have the following in the manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
I'm deploying the app to an Android 5.0.2 tablet using Android Studio.
I know the checkSelfPermission doesn't return PERMISSION_GRANTED and it executes the requestPermissions, but it doesn't show a dialog or grant the permission. How do I grant the app permission to use GPS?
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION }, 1);
This code requests runtime permissions on android 6.For lower versions i launch the settings intent for the user to turn on the preferred setting as below(in place of the above code)
Intent myIntent = new Intent(Settings.ACTION_SETTINGS);
startActivity(myIntent);
Add these lines in manifest:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
and these too:
<!-- Below permissions are used to detect required hardware or service providers for the application -->
<uses-feature
android:name="android.hardware.location"
android:required="true" />
<uses-feature
android:name="android.hardware.location.gps"
android:required="true" />
You can use the below code. With the below code it will ask to turn the GPS on .
public class Activity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private Location mLastLocation;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
// boolean flag to toggle periodic location updates
private boolean mRequestingLocationUpdates = false;
private LocationRequest mLocationRequest;
// Location updates intervals in sec
private static int UPDATE_INTERVAL = 600000; // 10 min
private static int FATEST_INTERVAL = 600000; // 10 min
private static int DISPLACEMENT = 5; // 5 meters
PendingResult<LocationSettingsResult> result;
AlertDialog.Builder alertDialogBuilder;
LinearLayout parent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
alertDialogBuilder = new AlertDialog.Builder(Activity.this);
parent = new LinearLayout(ActivitySetting.this);
parent.setGravity(Gravity.CENTER);
parent.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
alertDialogBuilder.setTitle("name");
// First we need to check availability of play services
if (checkPlayServices()) {
// Building the GoogleApi client
buildGoogleApiClient();
createLocationRequest();
}
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY));
result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates locationSettingsStates = result.getLocationSettingsStates();
// final LocationSettingsStates locationSettingsStates = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
alertDialogBuilder.setMessage("Turn On GPS");
alertDialogBuilder.setView(parent);
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(ActivitySetting.this, 1000);
} catch (IntentSender.SendIntentException e) {
// check error.
}
}
});
alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
try {
// Show the dialog by calling startResolutionForResult(),
finish();
} catch (Exception e) {
// check error.
}
}
});
alertDialogBuilder.create();
alertDialogBuilder.show();
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// you can do here what ever you want.
break;
}
}
});
}
#Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
#Override
protected void onResume() {
super.onResume();
checkPlayServices();
// Resuming the periodic location updates
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
}
/**
* Creating google api client object
*/
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode) {
case 1000:
switch (resultCode) {
case Activity.RESULT_OK:
// If user has active gps you will get it here
break;
case Activity.RESULT_CANCELED:
// The user was asked to change settings, but chose not to turn on
break;
default:
break;
}
break;
}
}
/**
* Method to verify google play services on the device
*/
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Toast.makeText(getApplicationContext(),
"This device is not supported.", Toast.LENGTH_LONG)
.show();
finish();
}
return false;
}
return true;
}
/**
* Google api callback methods
*/
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i("fsAil", "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
#Override
public void onConnected(Bundle arg0) {
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
}
}
Here API <= 21 gps permission will be granted automatically(if you have defined permission on manifest) and for marshmallow and above you need to ask for runtime permission(also add permission in manifest) but to turn on GPS after permission granted you can use the above code.
With this code one alertbox comes up and ask to turn on the GPS(if not active). So you can directly turn on GPS with the above code.
Hope this help you.
Cheers!!

Android Marshmallow getLastLocation / LocationListeners not working

I have an app which gets the users current location and then loads a Google Map and plots markers of interest in their area. It works flawlessly on everything below Marshmallow. I've added the run-time permissions check, and they are being set as I do get the prompt, and after I hit accept I see the Permission listed in the app details from the settings of the phone. However, I can not for the life of me figure out why I'm getting no location back.
I am using the example as seen here https://developer.android.com/training/location/retrieve-current.html
I have all the permissions set with the tag in the manifest. I even have my Fragment implementing the LocationListener. However, the onLocationChanged method never gets called. I am calling it within the onConnected method of the Google API Client like below..
#Override
public void onConnected(#Nullable Bundle bundle) {
try {
Log.d("MYAPPTAG","isConnected: " + mGoogleApiClient.isConnected());
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
myLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
} catch (SecurityException ex) {
myLocation = null;
}
}
the onConnected method DOES get called because I get my Log to the console. myLocation is always null though. I get a message in the console everytime I call getLastLocation that says
No Location to return for getLastLocation()
GoogleSignatureVerifier: com.myappname.android signature not valid. Found: LONG KEY HERE
Is there something special I need to do in Marshmallow?
my OnLocationChanged method
#Override
public void onLocationChanged(Location location) {
myLocation = location;
Log.d("MYAPPTAG", "LocatinChngListner, loc: " + location.getLatitude() + "," + location.getLongitude());
}
AndroidManifest.xml - permissions section (above node)
<!--- App permissions -->
<permission android:name="com.myappname.android.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<uses-permission android:name="com.myappname.android.permission.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.myappname.android.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.myappname.android.permission.C2D_MESSAGE"/>
onCreate Method snippet
createLocationRequest();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
createLocationRequest method
private void createLocationRequest(){
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(1000);
}
onStart() onStop() methods
#Override
public void onStart() {
if (!mGoogleApiClient.isConnected()) mGoogleApiClient.connect();
super.onStart();
}
#Override
public void onStop() {
if (mGoogleApiClient.isConnected()) mGoogleApiClient.disconnect();
super.onStop();
}
I call this code below right after the Fragment onCreate method
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1 && (ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }, REQUEST_PERMISSION_USER_LOCATION);
} else {
googleMapsLocationPermissionContainer.setVisibility(View.GONE);
getUserLocationAndInitializeMap();
}
googleMapsLocationPermissionContainer is just a layout I overlay on the map until the permissions are granted.
getUserLocationAndInitializeMap()
try {
MapsInitializer.initialize(getActivity());
// Set reference for map object
if (map == null) {
mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
// Here I set the map to invisible then after I plot all the markers I set it to visible again
mapFragment.getView().setVisibility(View.INVISIBLE);
}
} catch (Exception e) {
// Show the google maps alert dialog
showGoogleMapsErrorDialog();
}
My approach for this is the following:
#Override
public void onResume() {
super.onResume();
initGpsTracker();
}
public synchronized void initGpsTracker() {
if (mMap != null) {
try {
checkIfPermissionAllowedForLocation();
} catch (SecurityException secex) {
Toast.makeText(getActivity(), "not enabled in manifest", Toast.LENGTH_SHORT).show();
}
}
}
/**
* rule is the following. First we check if the permissions are there. If not, we check if we can enable or not.
* If the permissions are check if gps is enabled.
*/
private void checkIfPermissionAllowedForLocation() {
//if permissions are set then we go to else, check for gps
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Request missing location permission.
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)) {
askIfToRequestPermissions();
} else {
requestPermissions();
}
} else {
// Location permission has been granted, continue as usual.
if (!isGpsProviderEnabled()) {
askToEnableGPS();
} else {
mMap.setMyLocationEnabled(true);
}
}
}
private void askToEnableGPS() {
CustomFragmentDialog customFragmentDialog = CustomFragmentDialog.newInstance(getString(R.string.enable_gps_title),
getString(R.string.enable_gps_message),
getString(R.string.ok),
getString(R.string.cancel),
callback);
customFragmentDialog.show(getFragmentManager(), CUSTOM_TAG);
}
private void requestPermissions() {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_LOCATION);
}
private void enableGPS() {
if (enableLocationService != null) {
enableLocationService.askToEnableGps(locationCallback);
}
}
private GoogleAskToEnableLocationService.GpsCallback locationCallback = new GoogleAskToEnableLocationService.GpsCallback() {
#Override
public void onSuccess() {
initGpsTracker();
}
#Override
public void onResolutionRequired(Status status) {
try {
status.startResolutionForResult(getActivity(), CONNECTION_RESOLUTION_CODE);
} catch (IntentSender.SendIntentException setex) {
Toast.makeText(getActivity(), "Exception in sending intent:", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onError() {
Toast.makeText(getActivity(), "Location services unavailable!", Toast.LENGTH_SHORT).show();
}
};
private void askIfToRequestPermissions() {
CustomFragmentDialog customFragmentDialog = CustomFragmentDialog.newInstance(getString(R.string.enable_gps_title),
getString(R.string.enable_permissions_message),
getString(R.string.ok),
getString(R.string.cancel),
callback_permissions);
customFragmentDialog.show(getFragmentManager(), CUSTOM_TAG);
}
private CustomFragmentDialog.Callback callback = new CustomFragmentDialog.Callback() {
#Override
public void onPositiveButtonClicked(Bundle bundle) {
enableGPS();
}
#Override
public void onNegativeButtonClicked(Bundle bundle) {
}
};
private CustomFragmentDialog.Callback callback_permissions = new CustomFragmentDialog.Callback() {
#Override
public void onPositiveButtonClicked(Bundle bundle) {
requestPermissions();
}
#Override
public void onNegativeButtonClicked(Bundle bundle) {
}
};
private boolean isGpsProviderEnabled() {
return googleUtils.isGpsProviderEnabled();
}
//inside it is a normal check if locationManager can access
//the gps provider
if (locationManager.getProvider(provider) == null) {
return false;
}
Now, for request permission there are some callbacks:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case CONNECTION_RESOLUTION_CODE:
switch (resultCode) {
case Activity.RESULT_OK:
initGpsTracker();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(getContext(), "Gps not enabled:", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
break;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_CODE_LOCATION) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initGpsTracker();
} else {
Toast.makeText(getActivity(), "Manifest permission, not enabled", Toast.LENGTH_SHORT).show();
}
}
}
Now, finally the class where you deal with the request for the location so you do not have to go to settings:
public void askToEnableGps(final GpsCallback callback) {
if (locationClient == null) {
return;
}
mLocationRequestHighAccuracy = LocationRequest.create();
mLocationRequestHighAccuracy.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequestHighAccuracy.setInterval(30 * 1000);
mLocationRequestHighAccuracy.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequestHighAccuracy);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(locationClient, builder.build());
result.setResultCallback(getResultCallback(callback));
}
private ResultCallback<LocationSettingsResult> getResultCallback(final GpsCallback callback) {
return new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
if (result != null) {
final Status status = result.getStatus();
if (callback != null) {
//final LocationSettingsStates statesResult = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
callback.onSuccess();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
callback.onResolutionRequired(status);
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
callback.onError();
break;
}
}
}
}
};
}
public interface GpsCallback {
/**
* callback method for when the result it is a success.
*/
void onSuccess();
/**
* callback for when user interaction it is required.
*
* #param status the result from the service needed for the resolution.
*/
void onResolutionRequired(Status status);
/**
* Callback for when the change it is not possible.
*/
void onError();
}

Run time permission not working access fine location Marshmallow

I am working on project where i need to access user's gps location. Due to android 6, I need run time permissions. I tried to do it , first time it asked for gps location on activity starts, but without giving me location. I am still not getting any location coordinates. Hope someone can help ?
public class benzinpriser_akt extends AppCompatActivity implements OnItemClickListener {
public static final int MY_PERMISSION_REQUEST_GPS_LOCATION = 1 ;
LocationManager locationManager;
LocationListener locationListener;
Location currentLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
currentLocation = location;
System.out.println("Current Location "+ currentLocation );
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
};
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSION_REQUEST_GPS_LOCATION);
}
}
// Some other code regarding listview and fetching data from database
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSION_REQUEST_GPS_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
System.out.println("Permission Granted");
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
First of all add theese two lines to your build.gradle:
compile 'com.google.android.gms:play-services-maps:8.4.0'
compile 'com.google.android.gms:play-services-location:8.4.0'
Then in your activity you must implement like that :
public class benzinpriser_akt extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,LocationListener, android.location.LocationListener {
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private int UPDATE_INTERVAL = 20000; // 20 sec
private int FASTEST_INTERVAL = 10000; // 10 sec
private int DISPLACEMENT = 50; // get location per 50 meter change
protected final String TAG = "Location Service";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(yourlayout);
//build google api client
buildGoogleApiClient();
} //oncreate end
protected synchronized void buildGoogleApiClient() {
Log.v(TAG, "google client building");
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
mGoogleApiClient = new GoogleApiClient.Builder(thisService)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
startListenLocation();
} else {
Log.e(TAG, "unable to connect to google play services.");
}
}
public void createLocationRequestWithDialog(final Activity activity){
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
//**************************
builder.setAlwaysShow(true); //this is the key ingredient
//**************************
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
activity, 1000);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
public void checkGpsPermission(Activity activity) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_ACCESS_GPS);
}
else
{
createLocationRequestWithDialog(activity);
}
}
protected void startListenLocation() {
if (ActivityCompat.checkSelfPermission(thisService, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//no permission , create a notification and want permission
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
Notification n = new Notification.Builder(thisService)
.setContentTitle(" notification")
.setContentText("there is no permission about using gps services, please give location permissions")
.setSmallIcon(R.drawable.logo)
.setAutoCancel(true)
.build();
notificationManager.notify((int)System.currentTimeMillis(), n);
} else {
// permission has been granted, continue as usual
if(mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (mGoogleApiClient.isConnected() && mLastLocation != null) {
createLocationRequestWithDialog();
startListenLocation();
}
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
//TODO add other override methods , onresume, onproviderenabled etc...
}//class end
Battery drain :
/*
Priority update interval Battery drain per hour (%) Accuracy
HIGH_ACCURACY 5 seconds 7.25% ~10 meters
BALANCED_POWER 20 seconds 0.6% ~40 meters
NO_POWER N/A small ~1 mile
*/

Call requires permissions that may be rejected by user

I am trying to make an application that sends location updates of a user after every five minutes. I suppose my code is working just fine but i get an error regarding the permissions that are being used by the application. I am pretty sure that i have added the permissions in the manifest file. Can someone tell me what's wrong? Here is my code.
MainActivity.java
LocationManager locationManager ;
String provider;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Getting LocationManager object
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
// Creating an empty criteria object
Criteria criteria = new Criteria();
// Getting the name of the provider that meets the criteria
provider = locationManager.getBestProvider(criteria, false);
if(provider!=null && !provider.equals("")){
// Get the location from the given provider
Location location = locationManager.getLastKnownLocation(provider);
locationManager.requestLocationUpdates(provider,5*60*1000,0,this);
if(location!=null)
onLocationChanged(location);
else
Toast.makeText(getBaseContext(), "Location can't be retrieved", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getBaseContext(), "No Provider Found", Toast.LENGTH_SHORT).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onLocationChanged(Location location) {
// Getting reference to TextView tv_longitude
TextView tvLongitude = (TextView)findViewById(R.id.tv_longitude);
// Getting reference to TextView tv_latitude
TextView tvLatitude = (TextView)findViewById(R.id.tv_latitude);
// Setting Current Longitude
tvLongitude.setText("Longitude:" + location.getLongitude());
// Setting Current Latitude
tvLatitude.setText("Latitude:" + location.getLatitude() );
}
#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
}
}
I am getting an error as Call requires permission which may be rejected by user in these lines-
Location location = locationManager.getLastKnownLocation(provider);
locationManager.requestLocationUpdates(provider,5*60*1000,0,this);
My AndroidManifest is like this
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Which SDK do you use?
If you use Marshmallow, then you need to check that the user has granted permission for every location call.
Take a look Here.
You should do something like this:
if (ContextCompat.checkSelfPermission( this,android.Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED )
{
ActivityCompat.requestPermissions(
this,
new String [] { android.Manifest.permission.ACCESS_COARSE_LOCATION },
LocationService.MY_PERMISSION_ACCESS_COURSE_LOCATION
);
}
request permission if you dont have it already.
check the link above for more info.
Try my code:
public class MainActivity extends AppCompatActivity {
/* GPS Constant Permission */
private static final int MY_PERMISSION_ACCESS_COARSE_LOCATION = 11;
private static final int MY_PERMISSION_ACCESS_FINE_LOCATION = 12;
/* Position */
private static final int MINIMUM_TIME = 10000; // 10s
private static final int MINIMUM_DISTANCE = 50; // 50m
/* GPS */
private String mProviderName;
private LocationManager mLocationManager;
private LocationListener mLocationListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Get the best provider between gps, network and passive
Criteria criteria = new Criteria();
mProviderName = mLocationManager.getBestProvider(criteria, true);
// API 23: we have to check if ACCESS_FINE_LOCATION and/or ACCESS_COARSE_LOCATION permission are granted
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
// No one provider activated: prompt GPS
if (mProviderName == null || mProviderName.equals("")) {
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
// At least one provider activated. Get the coordinates
switch (mProviderName) {
case "passive":
mLocationManager.requestLocationUpdates(mProviderName, MINIMUM_TIME, MINIMUM_DISTANCE, this);
Location location = mLocationManager.getLastKnownLocation(mProviderName);
break;
case "network":
break;
case "gps":
break;
}
// One or both permissions are denied.
} else {
// The ACCESS_COARSE_LOCATION is denied, then I request it and manage the result in
// onRequestPermissionsResult() using the constant MY_PERMISSION_ACCESS_FINE_LOCATION
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSION_ACCESS_COARSE_LOCATION);
}
// The ACCESS_FINE_LOCATION is denied, then I request it and manage the result in
// onRequestPermissionsResult() using the constant MY_PERMISSION_ACCESS_FINE_LOCATION
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(this,
new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
MY_PERMISSION_ACCESS_FINE_LOCATION);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSION_ACCESS_COARSE_LOCATION: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
} else {
// permission denied
}
break;
case MY_PERMISSION_ACCESS_FINE_LOCATION: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
} else {
// permission denied
}
break;
}
}
}
}
Source: LINK
This worked for me
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(YourService.this, "First enable LOCATION ACCESS in settings.", Toast.LENGTH_LONG).show();
return;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 1, listener);
Here are the bunch of steps you need to perform to fix this
Main Activity .java
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates
(locationManager.requestLocationUpdates(provider,5*60*1000,0,this);
}//end of if
Now you also need to update your build.gradle
dependencies{
------------- //your pre-generated code
compile 'com.android.support:support-v4:23.0.1'
}
this is what Android.Developers say about it.
And don't forget to give permissions from application settings if you're using an emulator because it may not prompt for such

Categories

Resources