I can't access GPS using Android 10 (API 29) - android

I use a code that worked fine with Android 4.1. But this code doesn't work any more with Android 10. The code is as follows :
LocationManager Objgps = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Objlistener = new GPSlistener();
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// Activity#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 Activity#requestPermissions for more details.
return;
}
Objgps.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, Objlistener);
and :
private class GPSlistener implements LocationListener {
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onLocationChanged(Location location) {
Latitude.setText(CoordHrzSoleil.DDecToDMS(location.getLatitude()));
}
}
and within the manifest :
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
It seems that it misses some extra permissions, but I don't know what they are and how to apply them.
Thank you for your help.
Pierre.

Well, finally, I found the (or a) solution ; it's the same kind of gymnastics as for writing / reading files:
In the manifest you must :
<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_BACKGROUND_LOCATION"/>"
Then, in the code :
if (Build.VERSION.SDK_INT >= 23) {
if (checkPermission()) {
} else {
requestPermission(); // Code for permission
}
}
...
private boolean checkPermission() {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
private void requestPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION)
&& ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.ACCESS_COARSE_LOCATION)) {
Toast.makeText(MainActivity.this, "Access fine and coarse location allows us to use GPS. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}, GPS_PERMISSION_REQUEST);
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}, GPS_PERMISSION_REQUEST);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case GPS_PERMISSION_REQUEST:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("value", "Permission Granted, Now you can use GPS .");
} else {
Log.e("value", "Permission Denied, You cannot use GPS .");
}
break;
}
}
I haven't granted permission for "ACCESS_BACKGROUND_LOCATION". I'll have to check if it's necessary.
Cordially.
Pierre.

Related

Accessing GPS coordinates in same application session in which permission was provided by the user via popup window

I'd like for a user who starts the application for the first time on a device to be able to access GPS data in that session. Currently, the user must close and then restart the application after providing location permission for the location data to show in the application.
I have tried a variety of methods to resolve this. Most recently, I have moved requestPermission into Fragment1 which is also where locationManager is located.
public class Fragment1 extends Fragment {
public static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.data_capture, container, false);
requestPermission(v);
permissionAssessment(v);
...
return (v);
}
public void requestPermission(View v) {//This works, only poulates after restart...
int permissionCheck = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION);
//conditional here so that if conditionals granted do below, if refused, go away...
}else{
mGpsLocationListener = new GpsLocationListener();
lm = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);
mGpsStatus = lm.getGpsStatus(mGpsStatus);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, mGpsLocationListener);
}
}
In addition, I took the caveman approach, and created "permissionAssessment()" that would run immediately following requestPermission() assuming that perhaps since permissions were likely granted by the user in requestPermission(), I could run checkSelfPermission and force location services to start that way. No cigar. See below.
public void permissionAssessment(View v){
int permissionCheck = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
mGpsLocationListener = new GpsLocationListener();
lm = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);
mGpsStatus = lm.getGpsStatus(mGpsStatus);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, mGpsLocationListener);
}
}
Note that permissionAssessment() works fine if the device already has ACCESS_FINE_LOCATION permissions granted. It just does not work following the newly installed permissions from requestPermission() when that is used and there were no pre-existing permissions on the device.
Furthermore, fyi this application starts on the tab associated with Fragment1 and has constantly updated gps satellite time displayed. Satellite/GPS data shows fine AFTER the application has been restarted following the session where the user granted location permissions. I'd strongly prefer that the GPS "go-live" in the session where the user sets permissions. Constructive suggestions would be appreciated. Thanks in advance.
Update, 5/14/2021: This is what ended up working for me,
public class MainActivity extends AppCompatActivity {
...
private boolean requestPermissions() {
int iExtStorage = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
int iCoarseLocation = ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION);
int iFineLocation = ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (iExtStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (iFineLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
}
if (iCoarseLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (!listPermissionsNeeded.isEmpty())
{
ActivityCompat.requestPermissions(this,listPermissionsNeeded.toArray
(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
getLocation();
return true;
}
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
getLocation();
}
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
}
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
}
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}
}
}
...
}
Update #2, 5/14/2021: Per Sasaki's additional comment. This is from the fragment.
public class dataCapture extends Fragment {
...
private boolean requestPermission(View v) {
int iExtStorage = ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
int iCoarseLocation = ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION);
int iFineLocation = ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (iExtStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (iFineLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
}
if (iCoarseLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (!listPermissionsNeeded.isEmpty())
{
requestPermissions(listPermissionsNeeded.toArray
(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
getLocation();
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
getLocation();
}
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
}
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
}
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}
}
}
...
}
In addition, I took the caveman approach, and created "permissionAssessment()" that would run immediately following requestPermission() assuming that perhaps since permissions were likely granted by the user in requestPermission().
This approach will not work the first time when the permissions are granted by user.
This is because a prompt is shown to user for requesting permission using ActivityCompat.requestPermissions(...).
The actual granting/denial of permission would be done on a later stage when the user interacts with the prompt.
This means that the function permissionAssessment(...) which is being immediately run after the ActivityCompat.requestPermission(...) will not have the permissions hence wont run successfully for the first time and will require a Fragment "reload".
To ensure a successful run, you'll have to call the permissionAssessment(...) in the "success" callback of ActivityCompat.requestPermission(...). This is done using the function onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults).
Here's my implementation :-
public class Fragment1 extends Fragment {
public static final int REQUEST_FINE_LOCATION_CODE = 1;
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.data_capture, container, false);
permissionAssessment(v);
...
return (v);
}
public void permissionAssessment(View v){
int permissionCheck = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
// Permission is granted, proceed to get location.
getLocation()
} else {
// Permission is not granted, request permissions.
// Only the prompt is shown here, nothing else will happen.
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION_CODE);
}
}
/**
* This Function is responsible for handling what happens when permissions are granted by the user.
*/
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_FINE_LOCATION_CODE) {
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permissions Granted!
// Get Location as soon as the permissions are granted.
getLocation();
}
} else {
// Permission Denied by the user
// Show a prompt or do nothing as per your use case.
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
public void getLocation() {
mGpsLocationListener = new GpsLocationListener();
lm = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);
mGpsStatus = lm.getGpsStatus(mGpsStatus);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, mGpsLocationListener);
}
Please refer to this
https://developer.android.com/guide/topics/permissions/overview and
https://developer.android.com/training/permissions/requesting

Google map location permission does not show up for Android version 8+ Android developement

Google maps permission does not pop up for Android version 8+. For Android 5, it works fine.
The permission should pop up like the following picture, but it doesn't show on Android version 8+
Now, I know it has something to do with run-time permission. I added related code, but the app stops after I grant the permission.
What have I done wrong?
These are all the permissions granted.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
This is the code in onCreate()
if (!checkPermission()) {
requestPermission();
}
These are code related to permission checking and granting
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION);
int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_COARSE_LOCATION);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE);
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0) {
boolean fineLocationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean coarseLocationAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
if (!(fineLocationAccepted && coarseLocationAccepted)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
showMessageOKCancel("You need to allow access to both the permissions",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION},
PERMISSION_REQUEST_CODE);
}
}
});
return;
}
}
}
}
break;
}
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
But the app crashes after I click on "allow".
Error messages
2019-05-01 23:46:17.257 4519-16175/? E/PhenotypeFlagCommitter: Retrieving snapshot for com.google.android.gms.playlog.uploader failed
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1063)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1352)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:278)
at asip.a(:com.google.android.gms#16091022#16.0.91 (040700-244116403):27)
at alhm.a(:com.google.android.gms#16091022#16.0.91 (040700-244116403):2)
at alhm.a(:com.google.android.gms#16091022#16.0.91 (040700-244116403):19)
at alhm.a(:com.google.android.gms#16091022#16.0.91 (040700-244116403):29)
at com.google.android.gms.clearcut.uploader.QosUploaderChimeraService.d(:com.google.android.gms#16091022#16.0.91 (040700-244116403):3)
at com.google.android.gms.clearcut.uploader.QosUploaderChimeraService.a(:com.google.android.gms#16091022#16.0.91 (040700-244116403):14)
at com.google.android.gms.clearcut.uploader.QosUploaderChimeraService.a(:com.google.android.gms#16091022#16.0.91 (040700-244116403):6)
at zse.run(:com.google.android.gms#16091022#16.0.91 (040700-244116403):5)
at rrt.b(:com.google.android.gms#16091022#16.0.91 (040700-244116403):32)
at rrt.run(:com.google.android.gms#16091022#16.0.91 (040700-244116403):21)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at rxx.run(Unknown Source:7)
at java.lang.Thread.run(Thread.java:764)
Here is what I did
private void askForPermission(String permission, Integer requestCode) {
if (ContextCompat.checkSelfPermission(Main2Activity.this, permission) != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(Main2Activity.this, permission)) {
//This is called if user has denied the permission before
//In this case I am just asking the permission again
ActivityCompat.requestPermissions(Main2Activity.this, new String[]{permission}, requestCode);
} else {
deviceSetting(getApplicationContext());
ActivityCompat.requestPermissions(Main2Activity.this, new String[]{permission}, requestCode);
}
} else {
deviceSetting(getApplicationContext());
Toast.makeText(this, "" + permission + " is already granted.", Toast.LENGTH_SHORT).show();
}
}
private void deviceSetting(Context context) {
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(10000 / 2);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
Log.e("tag", "All location settings are satisfied.");
startLocationUpdates();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.e("tag", "Location settings are not satisfied. Show the user a dialog to upgrade location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
status.startResolutionForResult(Main2Activity.this, REQUEST_PERMISSIONS_LOCATION_SETTINGS_REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
Log.e("tag", "PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.e(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog not created.");
break;
}
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
deviceSetting(getApplicationContext());
} else {
saveData(latitude, longitude, "no");
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("onActivityResult()", Integer.toString(resultCode));
//final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode) {
case REQUEST_PERMISSIONS_LOCATION_SETTINGS_REQUEST_CODE:
switch (resultCode) {
case Activity.RESULT_OK: {
// All required changes were successfully made
Toast.makeText(getApplicationContext(), "Location enabled by user!", Toast.LENGTH_LONG).show();
startLocationUpdates();
break;
}
case Activity.RESULT_CANCELED: {
// The user was asked to change settings, but chose not to
Toast.makeText(getApplicationContext(), "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
break;
}
default: {
break;
}
}
break;
}
}
protected void startLocationUpdates() {
Log.e("inside", "startlocationupdate");
// Create the location request to start receiving updates
mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// mLocationRequest.setInterval(UPDATE_INTERVAL);
/// mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
// Create LocationSettingsRequest object using location request
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
LocationSettingsRequest locationSettingsRequest = builder.build();
Log.e("locationsettingsreuqest", String.valueOf(locationSettingsRequest));
// Check whether location settings are satisfied
// https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient
SettingsClient settingsClient = LocationServices.getSettingsClient(Main2Activity.this);
settingsClient.checkLocationSettings(locationSettingsRequest);
Log.e("locationsettingsreuqest", String.valueOf(settingsClient));
// new Google API SDK v11 uses getFusedLocationProviderClient(this)
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.getFusedLocationProviderClient(getApplicationContext()).requestLocationUpdates(mLocationRequest, new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
onLocationChanged(locationResult.getLastLocation());
}
},
Looper.myLooper());
}
public void onLocationChanged(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
I hope it works otherwise let me know

How to Re-Check Permissions on Resume

My application crashes if users enable the location permission through the app, then head to their phone's settings and disable the permission there. I have tried fixing this by checking the permissions through onResume but can't seem to get it right. Other solutions on StackOverflow haven't worked.
The following code runs within my onCreate() and checks for location permissions:
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else {
//check which API users are running.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//location permission dialog
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_FINE_LOCATION);
}
}
My onRequestPermissionsResult():
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case MY_PERMISSION_FINE_LOCATION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
}
} else {
Toast.makeText(getContext(), "The app requires location permissions", Toast.LENGTH_LONG).show();
getActivity().finish();
}
break;
}
}
Here is my onResume() code within the same fragment:
#Override
public void onResume() {
super.onResume();
updatePermissions();
if (googleApiClient.isConnected()) {
requestLocationUpdates();
}
}
public void updatePermissions(){
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
// mMap.setMyLocationEnabled(true);
} else {
//check which API users are running.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//location permission dialog
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_FINE_LOCATION);
}
}
}
The app crashes with the error:
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0 at fluo.tuki10.fragments.MapFragment.onRequestPermissionsResult(MapFragment.java:232)
which is the line
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
I feel like the solution is to implement a better onResume() that checks for permissions after users modify them outside the app. Unfortunately my code falls short
An advice, before comparing it with a head that is not without elements:
if (grantResults.length> 0)

cannot fetch location in marshmallow after giving permission request

I am developing an location app which is working fine in all devices except in Marshmallow.I have requested permission during runtime and when I grant permission longitude and latitude is not fetched,if i go to settings and change the location from high accuracy to battery saving,location is fetched and the app works.I want location to be fetched at high accuracy.
ActivityCompat.requestPermissions(this,
new String[]{
Manifest.permission.CAMERA,
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.INTERNET,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WAKE_LOCK,
},
1);
try this
step 1 :- add this permission in manifiesr file
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
step 2 : ask runtime permission
String permission = android.Manifest.permission.ACCESS_FINE_LOCATION;
if (ActivityCompat.checkSelfPermission(SearchCityClass.this, permission)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.
checkSelfPermission(SearchCityClass.this, android.Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(SearchCityClass.this, new String[]
{permission}, PERMISSION_GPS_CODE);
}
step 3: handle permsiion result
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_GPS_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, location_permission_granted_msg, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, location_permission_not_granted_msg, Toast.LENGTH_SHORT).show();
}
}
}
You have to give run time permission for android 6 like this
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) {
// Permission already Granted
//Do your work here
//Perform operations here only which requires permission
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
}
and if permission is not already granted override onRequestPermission Results like this
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == 1) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Permission Granted
//Do your work here
//Perform operations here only which requires permission
}
}
}
Add this code your Activity class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_images);
requestLocationPermission();
//your other codes
}
private void requestLocationPermission() {
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) {
} else {
ActivityCompat.requestPermissions(this, new String[]
{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//Checking the request code of our request
//If permission is granted
if (requestCode == 1) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Displaying a toast
Toast.makeText(this, "Permission granted now you can get the location", Toast.LENGTH_LONG).show();
} else {
//Displaying another toast if permission is not granted
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
}
}
Add this on your Mainfest XML
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

location.getSpeed() not coming for Marshmallow, using Fused Location API

I'm using Fused Location API in my app ( getLatitude(), getLongitude(), getSpeed(), getElevation(), and distanceTo() ). It was working fine until I updated my phone (Moto X2 2014) to Marshmallow.
Now I don't receive speed in the location object in my app, rest methods are responding normally. However, if I run navigation on google maps in the background, I seem to receive speed inside my app as well.
Also, my app seems to work without any issues on Nexus 5X (Marshmallow) and other below API 23 phones.
What could be the problem? Has anyone faced something similar before?
On devices running Android 6.0 (API level 23) and higher, you need to validate the permission programmatically.
Youd could be something like this:
public class YourActivity extends AppCompatActivity implements
LocationListener, ActivityCompat.OnRequestPermissionsResultCallback{
private static final int REQUEST_LOCATION = 0;
private static final String[] PERMISSION_LOCATION = {Manifest.permission.ACCESS_FINE_LOCATION};
private LocationManager locManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
//Check if the Location permission is already available.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//Permission not granted.
requestLocationPermission();
} else {
//Permission granted.
initLocManager();
}
}
}
/**
* Requests the permission.
*/
private void requestLocationPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
//Permission has been previously denied.
//Show message...
} else {
//Permission has not been granted yet. It is requested directly.
ActivityCompat.requestPermissions(this, PERMISSION_LOCATION, REQUEST_LOCATION);
}
}
/**
* Callback.
*/
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == REQUEST_LOCATION) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Permission granted.
initLocManager();
} else {
//Permission not granted.
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
public void initLocManager(){
//Sample code...
map.setMyLocationEnabled(true);
locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
if(locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) ||
locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission("android.permission.ACCESS_FINE_LOCATION") == PackageManager.PERMISSION_GRANTED) {
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
}else{
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
} else{
Toast.makeText(this, "No location services", Toast.LENGTH_LONG).show();
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
#Override
public void onLocationChanged(Location location) {
map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),
location.getLongitude()), 16));
removeUpdatesLocListener();
}
private void removeUpdatesLocListener(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission("android.permission.ACCESS_FINE_LOCATION") == PackageManager.PERMISSION_GRANTED) {
if(locManager!=null)
locManager.removeUpdates(this);
}
}else{
if(locManager!=null)
locManager.removeUpdates(this);
}
}
#Override
protected void onStop() {
super.onStop();
removeUpdatesLocListener();
}
}
Good luck!
And if you need more information, look this

Categories

Resources