If gmaps needs this permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
should I ask for each one to the user with requestPermissions ?
I checked some times and it only crash saying that the user didnt give permissions for android.permission.ACCESS_FINE_LOCATIONbut not the others, why?
should I ask for each one to the user with requestPermissions ?
First when to use requestPermission ?
requestPermission is only call after checkSelfPermission when this method doesn't return PERMISSION_GRANTED.
You can find a list of permission that android M requires during the runtime. Each of these Permissions are part of a Permission group. WRITE_EXTERNAL_PERMISSION is from android.permission-group.STORAGE and ACCESS_COARSE_LOCATION / ACCESS_FINE_LOCATION are from android.permission-group.LOCATION.
If the user allows the access to a permission -for example ACCESS_COARSE_LOCATION-, then android will automatically grant the access of this permission group -i.e. permission-group.LOCATION-. So if you later checkSelfPermission for ACCESS_FINE_LOCATION, you should receive PackageManager.PERMISSION_GRANTED.
If you app crashes, it means that you tried to call, for example LocationServices.FusedLocationApi.requestLocationUpdates before requesting from the user the permission-group Location.
Edit:
Do not forget that requestPermission is asynchronous. So do not call a method that requires a permission right after requestPermission. To call a method that requires a permission, you should override onRequestPermissionsResult that give you a list of permission and their state -granted/denied-.
You should only need to request permission for the LOCATION and STORAGE groups. I'm also pretty sure Fine location includes permission for Coarse, so you don't need to include that line in your manifest.
Related
My app needs location, it works well in Android 9. But in Android 10, the ACTION_LOCATION_SOURCE_SETTINGS doesn't grant the permission, only turn on the GPS.
#RequiresApi(api = Build.VERSION_CODES.M)
private void goToSettings() {
Intent myAppSettings = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myAppSettings);
}
In manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
If I tried to use startActivityForResult, no matter what action the user does, it always returns RESULT_CANCELED
[https://developer.android.com/about/versions/10/privacy/changes]
Android 10 introduces the
ACCESS_BACKGROUND_LOCATION permission.
Unlike the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION
permissions, the ACCESS_BACKGROUND_LOCATION permission only affects an
app's access to location when it runs in the background. An app is
considered to be accessing location in the background unless one of
the following conditions is satisfied:
An activity belonging to the app is visible. The app is running a
foreground service that has declared a foreground service type of
location.
Perhaps you need to request the ACCESS_BACKGROUND_LOCATION permission.
Also, I found this in the documentation
ACTION_SECURITY_SETTINGS
Activity Action: Show settings to allow configuration of security and location privacy.
Which might be the activity you need.
I am creating an Android application that reads a user's SMS messages. I first check whether the user has granted permission for me to read the SMS messages with the if conditional. I have verified that my test phone has not granted access to the app to read the SMS messages, as the print statement is executed. However, the requestPermissions method is not triggered (there is no popup asking to grant permission to read the SMS messages). I suspect I might be using the wrong permission code or the wrong method to begin with. I have included the following permission in my Manifest.xml file:
<uses-permission android:name="android.permission.SEND_SMS"/>
Below is my Kotlin code:
// See if the user has not granted permission to read his or her text messages
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED) {
// Request the user to grant permission to read SMS messages
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_SMS), 2);
System.out.println("Permission Denied")
}
In AndroidManifest.xml add READ_SMS
permission.
Use
<uses-permission android:name="android.permission.READ_SMS"/>
Instead of
<uses-permission android:name="android.permission.SEND_SMS"/>
As it is mentioned in comments, You have declared SEND_SMS permission in Manifest.xml file and requesting READ_SMS permission dynamically(runtime).
Also it is not recommended to use this permission unless app acts as default messaging app. Please go through documentation Manifest.permission.READ_SMS which states following
This is a hard restricted permission which cannot be held by an app
until the installer on record whitelists the permission. For more
details see
PackageInstaller.SessionParams.setWhitelistedRestrictedPermissions(Set)
In later versions of Android (like 8.0.0), can we still declare normal level permissions in the manifest, like INTERNET permission and expect it to be granted at installation time?
<uses-permission android:name="android.permission.INTERNET" />
or do we need to explicitly request them through the code?
If the second, do we need to ask for it on every single activity?
can we still declare normal level permissions in the manifest, like INTERNET permission and expect it to be granted at installation time?
Yes. Only dangerous ones need to be requested at runtime.
Yes, you can declare normal level permissions in the manifest. But in 6.0 and above you have to check that permission is granted or not by user at runtime.
I have switched my app to target API 27 and now it can't be granted WRITE_EXTERNAL_STORAGE permission -- grantResult is always -1.
My app needs this permission since it doesn't use apps private external storage space (which doesn't require WRITE_EXTERNAL_STORAGE starting from API 19).
I know that in API 26 there have been behavior changes for permissions. However this doesn't explain my problem.
I'm requesting both READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions in a standard way:
ActivityCompat.requestPermissions(activity, new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, requestCode);
(both permissions are declared via <uses-permission in manifest).
The dialog appears and I click "Allow":
However inside onRequestPermissionsResult callback I'm getting a -1(denied) for WRITE_EXTERNAL_STORAGE (and 0 (granted) for READ_EXTERNAL_STORAGE).
Shouldn't the result be 0 for both since I have requested and, presumably, granted both?
I have tried to request WRITE_EXTERNAL_STORAGE alone, but in this case the dialog doesn't appear at all.
One more detail: I have just checked the merged manifest in build/intermediates/manifests/full/debug and noticed that WRITE_EXTERNAL_STORAGE permission has attribute android:maxSdkVersion="18" (there is no such attribute in my manifest). This could be happening because my app has minApiVersion=21, but I'm not sure.
Somewhere along the line, you are picking up that android:maxSdkVersion="18" attribute. My guess is that it is coming from a library. Check the "Merged Manifest" tab in Android Studio, when you are editing your own manifest. It will have details of what is contributing the various elements and attributes.
android:maxSdkVersion has the effect of removing your <uses-permission> element on higher Android SDK versions, at least in terms of how runtime permissions work.
Since you need this permission for all versions, adding tools:remove="android:maxSdkVersion" on the <uses-permission> element should revert the android:maxSdkVersion="18" and give you what you expect.
I noticed a space in my permission in manifest, it was <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE "/> and I changed it to <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> and problem solved.
I'm trying to access ACCESS_FINE_LOCATION and if it cannot be found access ACCESS_COARSE_LOCATION. So I request for those 2 permission, but they give me the same dialog asking for location permission. I know those are both in the same group but Google says:
Note: Your app still needs to explicitly request every permission it needs, even if the user has already granted another permission in the same group. In addition, the grouping of permissions into groups may change in future Android releases. Your code should not rely on the assumption that particular permissions are or are not in the same group.
This means I ask for those 2 permissions within a second, which results in 2 dialog in a row. THis does not seem very user friendly to me. Is there a better way?
You do not need ACCESS_COARSE_LOCATION permission when you define ACCESS_FINE_LOCATION permission.
From Android Documentation:
Requesting User Permissions
In order to receive location updates from NETWORK_PROVIDER or
GPS_PROVIDER, you must request user permission by declaring either the
ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission,
respectively, in your Android manifest file. For example:
<manifest>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
.......
</manifest>
Without these permissions, your application will fail at runtime when
requesting location updates.
Note: If you are using both NETWORK_PROVIDER and GPS_PROVIDER, then
you need to request only the ACCESS_FINE_LOCATION permission, because
it includes permission for both providers. (Permission for
ACCESS_COARSE_LOCATION includes permission only for NETWORK_PROVIDER.)
Please look at https://developer.android.com/guide/topics/location/strategies.html
I have resolved the same problem.Try to give it runtime permission and Firstly check the manifest SDK version and if your version is greater than 6.0 or equal to 6.0 then you need to check permissions for your permission and pass permission Fine location only in request location then definitely it will work.
if you got stuck in code then you may ask for code I will update you but firstly go through these steps.
if you got success to perform your task then rate it.