I stucked on new permission model in the Android 6.
I defined following permissions in the manifest:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application...
But if i launched the app in the emulator and opened the app detail i saw the following :
It says that app does not require any permission.
How can i solve it please?
Many thanks for any advice.
It says that app does not require any permission.
That is correct. That portion of your app's page lists dangerous permissions. None of yours have a protectionLevel of dangerous.
How can i solve it please?
There is nothing wrong, and so there is nothing to solve.
Until Android 6.0, There are some permissions that will be automatically granted at install time and will not be able to revoke. We call it Normal Permission (PROTECTION_NORMAL). Here is the full list of them:
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT
Just simply declare those permissions in AndroidManifest.xml and it will work just fine. No need to check for the permission listed above since it couldn't be revoked.
as #Saini said, Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.
But if you choose targetSdkVersion lower than 23, your application will be treated like before and will ask user to grant permission to the app when they want to install application. you could read more from here
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app. It also gives the user more control over the app's functionality; for example, a user could choose to give a camera app access to the camera but not to the device location. The user can revoke the permissions at any time, by going to the app's Settings screen.
For more info: https://developer.android.com/training/permissions/requesting.html
https://developer.android.com/training/permissions/declaring.html
https://developer.android.com/training/permissions/best-practices.html
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
In addition to https://stackoverflow.com/a/42697645/984471
Here is the protection_normal permissions link:
https://developer.android.com/guide/topics/permissions/overview#normal_permissions
And the comparison between old and new, normals
Related
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)
I'd like to know why my permission are not asked when I'm launching my app, here's my manifest permissions :
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
And when I go through the param of my phone, I only have the "position" permission (and it's disabled).
If by permission not asked you mean that the user isn't being prompted to allow internet permission then that is normal. Internet is in the normal permissions list so it is auto granted. For more information about normal permissions take a look at: https://developer.android.com/guide/topics/permissions/normal-permissions.html
Also, adding permissions is a two step process; once you have declared the permission you need in your manifest, you will also have to do some setup in your java file. Take a look at https://developer.android.com/training/permissions/requesting
Additionally, if you are looking for easier ways to deal with permissions then there are libraries out there for that too such as RxPermissions: https://github.com/tbruyelle/RxPermissions
Hopefully this helps!
You should ask for a Runtime Permission
Please see the documentation:
Request App Permissions
If you are targeting SDK 26+, then you need to check for permissions in code like this:
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
MY_PERMISSIONS_ACCESS_FINE_LOCATION)
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
// Permission has already been granted - or running on old Android
}
It is described in Request App Permissions
for marshmallow(API 23) and above you should get permission for location, phone states and other dangerous permissions not only in your manifest but in your code (Run Time Permission).for other permissions, manifest is enough.
see this video
also you can find your solution in this Q&A
In my android application (minSdkVersion 15), i have to create directory and write files into it. In my AppManifest i am using :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Before creating directory or file, i am checking if permission is allowed or deny, as
boolean isAllow = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
But it is always returning true or PERMISSION_GRANTED, even when someone set deny permission from Settings -> Apps -> Permissions
Why checkSelfPermission is always returning PERMISSION_GRANTED ? Is there any way to check if permission is denied ?
To invoke permission i have used :
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
But its not showing permission Dialogue??
In the new permission model permissions with protection level dangerous are runtime permissions. For apps targeting M and above the user may not grant such permissions or revoke them at any time. For apps targeting API lower than Marshmallow(<23) these permissions are always granted as such apps do not expect permission revocations and would crash. Therefore, when the user disables a permission for a legacy app in the UI the platform disables the APIs guarded by this permission making them a no-op which is doing nothing or returning an empty result or default error.
for more information visit PermissionChecker
For those who develop with Xamarin make sure that you explicitly set the targetSDK version >= 23 in your manifest.
Don't use automatic for your targetSDK!!!
if your targetSdkVersion is minimum 23 then your problem can be solved by code as below:
int permissionCheck = PermissionChecker.checkSelfPermission(getReactApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
I want to provide a functionality in my App for which I need the permission INTERNET.
However, not all user may want to use this functionality and since this is a very strong permission I don't want to force everyone to give it to the App if they want to use it, only if they want to use this functionality.
So I have to ask for that permission at run-time. the minimum sdk for the App is 15 and I don't want to set it higher.
The method requestPermissions(String[],int), which I can call in my Activity is only available with API 23, but I can callActivityCompat.requestPermissions(this,new String[]{Manifest.permission.INTERNET},0);, but it doesn't no dialog is shown.
And yes, I have checked if the permission is already granted:
if(ContextCompat.checkSelfPermission(this,Manifest.permission.INTERNET)!=
PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.INTERNET},0);
What am I doing wrong?
android.permission.INTERNET persmission comes under automatically granted persmission therefore there is no need to ask for it.
Here is the list of automatically granted permission list. These permissions will be automatically granted at install time and will not be able to revoke.
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT
refer this for more
android.permission.INTERNET permission is a normal permission. So it automatically granted without any dialog. See more details here.
What targetSDKVersion did you set? You have to set it to 23, otherwise permissions policy will be from older platforms.
Android defines a set of permissions that third-party apps can request. Permissions are categorized by sensitivity; most permissions are either "normal" or "dangerous". Normal permissions are granted automatically, without prompting the user; dangerous permissions are presented to the user when the app is installed and the user is asked to consent to granting them.
Question: For any particular Android permission I have in mind, how can I tell whether it is a normal permission or a dangerous permission? Is there a list of dangerous permissions and a list of normal permissions?
(I know that third-party apps can declare their own permissions. I'm only asking about standard permissions. I know it may not be possible to get a 100%-complete list. I'm only looking for best-effort; something is better than nothing.)
For a related but different question, see also Where can I get a list of Android permissions (however, that's a different question; it doesn't at the normal vs dangerous distinction, and I don't necessarily need a complete list).
For more simplicity, below are list of Normal permissions taken from official docs:
As of API level 23, the following permissions are classified as PROTECTION_NORMAL:
ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
FLASHLIGHT
GET_PACKAGE_SIZE
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_INSTALL_PACKAGES
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
SET_ALARM
INSTALL_SHORTCUT
UNINSTALL_SHORTCUT
And here is list of Dangerous permissions and permission groups:
CALENDAR : READ_CALENDAR, WRITE_CALENDAR
CAMERA : CAMERA
CONTACTS : READ_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTS
LOCATION : ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION
MICROPHONE : RECORD_AUDIO
PHONE : READ_PHONE_STATE, CALL_PHONE, READ_CALL_LOG, WRITE_CALL_LOG, ADD_VOICEMAIL, USE_SIP, PROCESS_OUTGOING_CALLS
SENSORS : BODY_SENSORS
SMS : SEND_SMS, RECEIVE_SMS, READ_SMS, RECEIVE_WAP_PUSH, RECEIVE_MMS
STORAGE : READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE
Normal permissions are granted automatically, without prompting the user
AFAIK, the documentation is wrong here.
dangerous permissions are presented to the user when the app is installed and the user is asked to consent to granting them
AFAIK, all permissions have this behavior.
What this may have morphed into is that dangerous permissions are always displayed and normal permissions are ones that might be "below the fold" if there are enough dangerous ones.
For any particular Android permission I have in mind, how can I tell whether it is a normal permission or a dangerous permission? Is there a list of dangerous permissions and a list of normal permissions?
You can look at the source code.
I found this blogpost listing the "default" permissions by protection level. I think, this is the kind of list you were looking for.
The list might have changed in the meantime though, as the post is 10 months old. It provides sample code to recompile the list by yourself.
From android M permissions will be granted at runtime. User consent is not required for Normal permissions but for Dangerous permissions user is required to grant the permission to application.
Normal permissions: https://developer.android.com/guide/topics/security/normal-permissions.html
Dangerous permissions: Dangerous permissions cover areas where the app wants data or resources that involve the user's private information https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
Here is a good article which describes every thing about run time permissions ,
Normal permissions
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT
Dangerous permissions
in Android Studio,you can open your AndroidManifest.xml and press F1 on every permission you used then you can see if it is dangerous which the doc may shows.
New permissions are added as new Android versions are released, so any list included in your code will go out of date.
If you need a future-proof approach, it's possible to determine at runtime whether a permission is dangerous.
fun Context.isDangerousPermission(permissionName: String): Boolean {
val permissionInfo: PermissionInfo = try {
packageManager.getPermissionInfo(permissionName, 0);
} catch (ex: PackageManager.NameNotFoundException) {
return false
}
return if (Build.VERSION.SDK_INT >= 28) {
permissionInfo.protection == PermissionInfo.PROTECTION_DANGEROUS
} else {
permissionInfo.protectionLevel and PermissionInfo.PROTECTION_DANGEROUS != 0
}
}
This extension function returns true if a permission is dangerous.
For example:
activity.isDangerousPermission("android.permission.CAMERA") // true
activity.isDangerousPermission("android.permission.INTERNET") // false