Marshmallow - Google Maps Runtime permission issue - android

I'm using the Google location API to show the users location on the map.
When the app loads for the first time, rationale dialog is displayed explaining why user needs to enable access to location. Then, runtime permission dialog is shown, and users clicks “Allow” to enable location access. The Map then loads fine without any crashes.
However, when the app resumes (after going into background), no rationale dialog appears since user has already granted location access. In this scenario, only the runtime permission dialog appears. Now if the user clicks “Deny”, the app crashes. This code works fine in Android versions below M (Lollipop, Jellybean, KitKat etc.)
Is there a way to handle the runtime exception at this stage?
The error is :
java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION
permission to request PRIORITY_HIGH_ACCURACY locations.
I'm using the standard Sample MyLocation demo app without any 3rd party library:
GoogleMaps MapDemo on Github
I've also tried using the PermissionsDispatcher Library, but the same errors persist.
PermissionDispatcher Android-Google-Maps-Demo
private void enableMyLocation() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Permission to access the location is missing.
PermissionUtils.requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE,
Manifest.permission.ACCESS_FINE_LOCATION, true);
} else if (mMap != null) {
// Access to the location has been granted to the app.
mMap.setMyLocationEnabled(true);
}
}
Any help is highly appreciated.

Make sure about that you have add right permission in your Manifest files about what permission you are asking and needed exactly
And may be problem with your code.
Try this library: RuntimePermission Library
To ask permission manually.

Related

Requesting app runtime permissions (Android)

I want to write a simple app which accesses the device's location. Only I will ever use the app. This is my first attempt in about 10 years to write an Android app, so it is the first time I've had to deal with runtime permissions.
My first question is, given that the app is solely for my use, is it possible to by-pass the need for runtime permission code?
Failing that, is there any simple example code that fills in the numerous gaps in the Android documentation?
To take one example: the doc includes the following:
when {
ContextCompat.checkSelfPermission(
CONTEXT,
Manifest.permission.REQUESTED_PERMISSION
) == PackageManager.PERMISSION_GRANTED -> {
// You can use the API that requires the permission.
performAction(...)
What does this mean? What "API that requires the permission"? What replaces the "..."?
There are several other similar gaps on the page.
You have mentioned that app is solely for your use then you don't have to write the code for the runtime permission you can skip it...
How to do this... ?
Step 1 : Just put all the permission you need inside the app manifest file and install the app
Step 2 : Go to the app settings or app info in the phone and check for app permissions all the permission that you mentioned will be displayed there just toogle them manually
That's it now write code to access the things which you supposed to write after getting permission
If you want to avoid run time permission request you can build your app with Android SDK version below 23 (Android 6 Marshmellow)
For Android API Level 23 or above (after adding permission in your manifest file):
First, add your permission to AndroidManifest.xml file:
<uses-permission android:name="android.permission.THE_PERMISSION" />
Then in your Activity:
Check Permission:
fun checkPermission(permission: String): Boolean {
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
}
Get Permission:
fun getPermission(permission: String) {
ActivityCompat.requestPermissions(this, arrayOf(permission), REQ_CODE_PERMISSION)
}
Get Permission Result:
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (requestCode == REQ_CODE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
...
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
If you are using Fragments:
A fragment contains a method for requesting permission and getting the result back to its onRequestPermissionsResult:
fun getPermission(permission: String) {
requestPermissions(arrayOf(permission), REQ_CODE_PERMISSION)
}
REQ_CODE_PERMISSION: is some random number like 123 you use to identify your request with.
is it possible to by-pass the need for runtime permission code?
You still need the <uses-permission> element. But you could manually grant the permission to your app via the Settings app.
The point of runtime permission code is to request the permission from the user and defend against cases where that permission has not been granted. In your case, if your app crashes because you revoked the permission, you can yell the developer. You, as the developer, in turn, can yell at you, as the user, for failing to manually grant the permission. Since you will be yelling at yourself, it is recommended to do this in a private location, or perhaps have a Bluetooth headset in your ear as cover. :-)
What does this mean?
We request runtime permissions because we want to use some Android API that is defended by such a permission. We usually do not request runtime permissions because we woke up one morning and decided that requesting runtime permissions sounds like a really fun thing to do.
What "API that requires the permission"? What replaces the "..."?
In your case, it would appear to be either methods on LocationManager or stuff using the fused location API from Google Play Services.
is there any simple example code that fills in the numerous gaps in the Android documentation?
The problem is that "example code" is 5% permission-related and 95% whatever it is that you are using that requires the permission. Any sample code that only shows permissions is going to have the same hand-wavy stuff that you don't like from the documentation. In your case, any up-to-date examples of using location APIs should also show the runtime permission elements.
FWIW, this directory contains several sample projects from this book that show getting the location. They are a bit old but do show requesting runtime permissions (mostly contained in an AbstractPermissionActivity). This sample is newer and in Kotlin, but it is for file-access permissions, not for locations (and is covered in this other book).

Permission dialog not appearing in fragment [duplicate]

Facebook, Evernote, Pocket - all apps get this permission on Android 6.0 automatically, even though they are targeting 23 (targetSdkVersion=23).
There has been a lot of documentation regarding the new Marshmallow permission model. One of them is SYSTEM_ALERT_WINDOW been 'promoted' to 'above dangerous' permission class thus requiring a special user intervention in order for apps to be granted with those. If the app has targetSdkVersion 22 or lower, app gets this permission automatically (if requested in the manifest).
However, I've noticed some apps that get this permission, without needing to send the user to the setting special page of Draw over other apps permission. I saw Facebook, Evernote, Pocket - and perhaps there are more.
Anyone knows how an app can be granted this permission without the user go through Settings -> Apps -> Draw over other apps?
Thanks
It is a new behaviour introduced in Marshmallow 6.0.1.
Every app that requests the SYSTEM_ALERT_WINDOW permission and that is installed through the Play Store (version 6.0.5 or higher is required), will have granted the permission automatically.
If instead the app is sideloaded, the permission is not automatically granted. You can try to download and install the Evernote APK from apkmirror.com. As you can see you need to manually grant the permission in Settings -> Apps -> Draw over other apps.
These are the commits [1] [2] that allow the Play Store to give the automatic grant of the SYSTEM_ALERT_WINDOW permission.
Yeh After Marshmallow come Android make security level more stick, But For SYSTEM_ALERT_WINDOW you can show floating action and anything You can Force user to give permission for it By Following Codes in your onCreate() method.
Put this code after setContentView:
// Check if Android M or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Show alert dialog to the user saying a separate permission is needed
// Launch the settings activity if the user prefers
Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(myIntent);
}
The action ACTION_MANAGE_OVERLAY_PERMISSION directly launches the 'Draw over other apps' permission screen.
Edit:
My Above Code works 100% Correct
But I just found that many guys are still searching that how can allow ACTION_MANAGE_OVERLAY_PERMISSION permanently like If user has allow Permission Once then don't ask it every time he open application so here is a solution for you:
Check if device has API 23+
if 23+ API then check if user has permit or not
if had permit once don't drive him to Settings.ACTION_MANAGE_OVERLAY_PERMISSION and if has not permit yet then ask for runtime permission check
Put below line in your onCreate() method. Put this after setContentView:
checkPermission();
Now put below code in onActivityResult:
#TargetApi(Build.VERSION_CODES.M)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (!Settings.canDrawOverlays(this)) {
// You don't have permission
checkPermission();
} else {
// Do as per your logic
}
}
}
Now finally the checkPermission method code:
public void checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}
}
}
And don't forget to declare this public variable in your class:
public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 5469;
Now(2019) that Google offers an alternative API to SYSTEM_ALERT_WINDOW in the form of Bubbles in Android Q, Google has decided to eventually deprecate SYSTEM_ALERT_WINDOW in a future Android release.
And Android Go devices will no longer grant this permission
i.e Settings.canDrawOverlays() == false
For those who want to get this permission automatically when the app is downloaded from the Play Store, besides the SYSTEM_ALERT_WINDOW in the Manifest, you should go to this link and request this from Google.
You have to provide some additional information why you need this permission and Google will review and give you the automatically permission.
Bear in mind that before you ask for this, you have to:
Have the SYSTEM_ALERT_WINDOW permission in the Manifest
Prompt the user to grant the SYSTEM_ALERT_WINDOW permission within your app, when not already granted
If I miss something feel free to update the answer
If the app targets API 22 or lower, then Play Store will give the SYSTEM_ALERT_WINDOW permission and others when the user clicks to install (showing an alert) even if its device is Android 6.0
Otherwise, if the app targets API 23 or above, so that permission will be request to grant in run time.

Handle "dont ask again " Location Permissions Xamarin Forms

I got this dilemma. I am using TK-TORBEN-Maps ,Xamarin Forms. I did implement all the runtime permissions . however, if an user clicks "dont ask me again" what can I do to stop the app from crashing.
I need to let them pass even if they didnt accept and the first page is the map. is there anyway I could still display the map with those permission being denied?
It seems that you could not use the map without the permission.
I think you could explain to your users why the app needs the permission. For example, you could use ShouldShowRequestPermissionRationale.
string permission = Manifest.Permission.AccessFineLocation;
if (ShouldShowRequestPermissionRationale(permission))
{
//Explain to the user why we need to read the contacts
Snackbar.Make(layout, "Location access is required for some reason ", Snackbar.LengthIndefinite)
.SetAction("OK", v => RequestPermissions(PermissionsLocation, RequestLocationId))
.Show();
return;
}
You could refer to this blog for more information.
If you want the app not crash, you could try to navigate to another page after user denies the request.

SYSTEM_ALERT_WINDOW - How to get this permission automatically on Android 6.0 and targetSdkVersion 23

Facebook, Evernote, Pocket - all apps get this permission on Android 6.0 automatically, even though they are targeting 23 (targetSdkVersion=23).
There has been a lot of documentation regarding the new Marshmallow permission model. One of them is SYSTEM_ALERT_WINDOW been 'promoted' to 'above dangerous' permission class thus requiring a special user intervention in order for apps to be granted with those. If the app has targetSdkVersion 22 or lower, app gets this permission automatically (if requested in the manifest).
However, I've noticed some apps that get this permission, without needing to send the user to the setting special page of Draw over other apps permission. I saw Facebook, Evernote, Pocket - and perhaps there are more.
Anyone knows how an app can be granted this permission without the user go through Settings -> Apps -> Draw over other apps?
Thanks
It is a new behaviour introduced in Marshmallow 6.0.1.
Every app that requests the SYSTEM_ALERT_WINDOW permission and that is installed through the Play Store (version 6.0.5 or higher is required), will have granted the permission automatically.
If instead the app is sideloaded, the permission is not automatically granted. You can try to download and install the Evernote APK from apkmirror.com. As you can see you need to manually grant the permission in Settings -> Apps -> Draw over other apps.
These are the commits [1] [2] that allow the Play Store to give the automatic grant of the SYSTEM_ALERT_WINDOW permission.
Yeh After Marshmallow come Android make security level more stick, But For SYSTEM_ALERT_WINDOW you can show floating action and anything You can Force user to give permission for it By Following Codes in your onCreate() method.
Put this code after setContentView:
// Check if Android M or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Show alert dialog to the user saying a separate permission is needed
// Launch the settings activity if the user prefers
Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(myIntent);
}
The action ACTION_MANAGE_OVERLAY_PERMISSION directly launches the 'Draw over other apps' permission screen.
Edit:
My Above Code works 100% Correct
But I just found that many guys are still searching that how can allow ACTION_MANAGE_OVERLAY_PERMISSION permanently like If user has allow Permission Once then don't ask it every time he open application so here is a solution for you:
Check if device has API 23+
if 23+ API then check if user has permit or not
if had permit once don't drive him to Settings.ACTION_MANAGE_OVERLAY_PERMISSION and if has not permit yet then ask for runtime permission check
Put below line in your onCreate() method. Put this after setContentView:
checkPermission();
Now put below code in onActivityResult:
#TargetApi(Build.VERSION_CODES.M)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (!Settings.canDrawOverlays(this)) {
// You don't have permission
checkPermission();
} else {
// Do as per your logic
}
}
}
Now finally the checkPermission method code:
public void checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}
}
}
And don't forget to declare this public variable in your class:
public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 5469;
Now(2019) that Google offers an alternative API to SYSTEM_ALERT_WINDOW in the form of Bubbles in Android Q, Google has decided to eventually deprecate SYSTEM_ALERT_WINDOW in a future Android release.
And Android Go devices will no longer grant this permission
i.e Settings.canDrawOverlays() == false
For those who want to get this permission automatically when the app is downloaded from the Play Store, besides the SYSTEM_ALERT_WINDOW in the Manifest, you should go to this link and request this from Google.
You have to provide some additional information why you need this permission and Google will review and give you the automatically permission.
Bear in mind that before you ask for this, you have to:
Have the SYSTEM_ALERT_WINDOW permission in the Manifest
Prompt the user to grant the SYSTEM_ALERT_WINDOW permission within your app, when not already granted
If I miss something feel free to update the answer
If the app targets API 22 or lower, then Play Store will give the SYSTEM_ALERT_WINDOW permission and others when the user clicks to install (showing an alert) even if its device is Android 6.0
Otherwise, if the app targets API 23 or above, so that permission will be request to grant in run time.

Why is `hasEnrolledFingerprints` giving error that it requires a permission only in my Fragment but not in the Activity in Google's Example?

I am trying to implement the Google's Fingerprint API in my app (in my Fragment specifically). Google has given an example but it's implemented inside an Activity here.
My specific question is that the code below to check if there are enrolled fingerprints already, it is giving me an error (screenshot below):
Question --> What change do I need to do to make it work in my Fragment (as opposed to an activity like Google has)?
if (!mFingerprintManager.hasEnrolledFingerprints()) {
purchaseButton.setEnabled(false);
// This happens when no fingerprints are registered.
Toast.makeText(getActivity(),
"Go to 'Settings -> Security -> Fingerprint' and register at least one fingerprint",
Toast.LENGTH_LONG).show();
return;
}
Android 6.0 must 'ask' for permission at run time. https://developer.android.com/training/permissions/requesting.html
Dangerous permissions can give the app access to the user's
confidential data. If your app lists a normal permission in its
manifest, the system grants the permission automatically. If you list
a dangerous permission, the user has to explicitly give approval to
your app.
Even if you have <uses-permission android:name="android.permission.USE_FINGERPRINT"/> in your manifest, My understanding is that you must ask for the permission. So it looks like the error is because your app doesn't have -run time- permission to use the fingerprint manager.
(only like 90% sure of this, since I'm sticking with 5.0 for now, sorry)
Update: http://developer.android.com/reference/android/Manifest.permission.html#USE_FINGERPRINT
public static final String USE_FINGERPRINT ---------- Added in API level 23
Allows an app to use fingerprint hardware.
Protection level: normal
So it appears you shouldn't need this permission at run time.
1) Do you have the permission in your manifest?
2) You should put the following code in yours to check to see if permission is revoked/not given for some reason.
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.USE_FINGERPRINT) // this might need massaged to 'android.permission.USE_FINGERPRINT'
!= PackageManager.PERMISSION_GRANTED) {
Log.d ("TEST", "You don't have permission");
}
(or something close to this) like the example from https://developer.android.com/training/permissions/requesting.html

Categories

Resources