For getting the IMEI i using from this code:
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1);
} else {
iMEI = tm.getDeviceId();
}
But when my app is running this dialog box coming up:
The program asks to grant permission To make and manage phone calls which can scary users from using app.
And now my question is:
Why READ_PHONE_STATE permission asked "make and manage phone call"? While I have not make phone call and manage phone call in my
app.
READ_PHONE_STATE permission is listed as Dangerous permission and provides access to read phone state. It comes under the Phone permission group. If dangerous permission is asked, the system shows dialog related to its group. in your case, Phone. and That is the reason- the user is asked for "make and manage phone call" permission. This is how the permissions are asked-
https://developer.android.com/training/permissions/requesting
To make it more clear, see
https://developer.android.com/guide/topics/permissions/overview
It says -
If the device is running Android 6.0 (API level 23) and the app's
targetSdkVersion is 23 or higher, the following system behavior
applies when your app requests a dangerous permission:
If the app doesn't currently have any permissions in the permission group, the system shows the permission request dialog to the user
describing the permission group that the app wants access to. The
dialog doesn't describe the specific permission within that group.
For example, if an app requests the READ_CONTACTS permission, the
system dialog just says the app needs access to the device's
contacts. If the user grants approval, the system gives the app just
the permission it requested.
If the app has already been granted another dangerous permission in the same permission group, the system immediately grants the
permission without any interaction with the user. For example, if an
app had previously requested and been granted the READ_CONTACTS
permission, and it then requests WRITE_CONTACTS, the system
immediately grants that permission without showing the permissions
dialog to the user.
There are a lot of better ways to get a unique identifier. For example-
String android_id = Settings.Secure.getString(getApplicationContext().getContentResolver(),
Settings.Secure.ANDROID_ID);
Why READ_PHONE_STATE permission asked "make and manage phone call"?
While I have not make phone call and manage phone call in my app.
After Marshmallow we need to explicitly call the permissions which come under Dangerous permission.
READ_PHONE_STATE comes under Permission Group Called Phone
Because google got lazy. It is the same with READ_EXTERNAL_STORAGE
Related
I am reading the documentation here for the Android Nearby Permission specially for Android 12. I want to check if the user has granted access to Nearby device permission programmatically. The following check is returning true for me all the time
ContextCompat.checkSelfPermission(context,Manifest.permission.BLUETOOTH_CONNECT) ==
PackageManager.PERMISSION_GRANTED
I manually revoked the nearby permission after granting it once in the app and also confirmed by going to the app settings which says nearby permission is not granted. Is there a way to check for this runtime and show the nearby device permission(system dialog) if not granted
I am making an EMM application. This application will only be installed in firm's devices only. Is there any way to grant below permissions programmatically through DevicePolicyManager.
android.permission.SYSTEM_ALERT_WINDOW (Display over other apps)
android.permission.BIND_ACCESSIBILITY_SERVICE (Accessibility service)
android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS (Ignore battery optimization)
I want to grant above permissions through DevicePolicyManager as my app is a system owner app. But, I can't grant them through devicePolicyManager.setPermissionGrantState. As I have also tried devicePolicyManager.setPermittedAccessibilityServices for granting ACCESSIBILY_SERVICE programmatically, but it also didn't work. So, is there is any way I can grant above all permissions programmatically without navigating to that screen and turn in on manually. Or Is there is a way so that user cannot be able to disable the above features anyway. Like when I enable location and other permissions through DevicePolicyManager user is unable to turn it off.
So reviewing: https://developers.google.com/android/work/requirements#4.2.-runtime-permission-grant-state-management_1
and https://developers.google.com/android/management/reference/rest/v1/enterprises.policies#permissionpolicy
seem to indicate at you can create a policy which will automatically grant permissions.
I do see:
PERMISSION_POLICY_AUTO_GRANT
Permission policy to always grant new permission requests for runtime permissions. Already granted or denied permissions are not affected by this.
and
PERMISSION_GRANT_STATE_GRANTED
Runtime permission state: The permission is granted to the app and the user cannot manage the permission through the UI.
which sounds like what you want.
I am developing a COSU/KIOSK application and I need to manually update the time on the device.
I am using AlertManager.setTime(Calendar) to do so, but I can't grant my application the SET_TIME permission that it is required.
The application is the device owner, and this allowed me to use many other system permissions, for example
android:name="android.permission.REBOOT"
android:name="android.permission.SHUTDOWN"
android:name="android.permission.WRITE_SETTINGS"
android:name="android.permission.INSTALL_PACKAGES"
android:name="android.permission.DELETE_PACKAGES"
All of these permissions were granted to my application, just by listing them in the manifest.xml
But SET_TIME does not work.
I also tried using the device policy manager
mDevicePolicyManager.setPermissionGrantState(mAdminComponentName, getPreferredPackageName(),
Manifest.permission.SET_TIME, DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
This function returned false meaning it couldn't grant permission.
How can I solve this problem without prompting the user to grant this permission to my application.
If you are targeting devices api 28+ (android 9 and higher) you can set it with setTime(ComponentName admin, long millis) function.
For lower android versions I had to rely on a device manufacturer api to set device time.
Manifest.permission.SET_TIME is proteced/system permission, sadly deviceOwner cannot grant any protected permissions with setPermissionGrantState() function.
There is very important word in its documentation:
Sets the grant state of a !runtime! permission for a specific application.
I have listed both the permissions of RECEIVE_SMS and READ_SMS in my app's Manifest file and both of them has different permission strings too.
to grant the respective permissions. However, I have noticed that on granting(by the user) any one of the permissions(READ_SMS or RECEIVE_SMS) we can perform both the tasks. My question is that if both of them performs different tasks:
1) READ_SMS: It allows the app to read all the SMS's(currently present) on the user's phone.
2) RECEIVE_SMS: It allows the app to listen to all the SMS's that are received on the user's phone while he/she is using the app.
Both of them shows the same dialog box on asking for permission and on rejecting one of the permission both the dialog boxes do not appear.
If both have the same permission granting scenario's then why are they separated in form of two permissions? If anyone of you could help me with understanding this, then it would be a great help to me.
According to Android documentation on Requesting Permissions:
Permission groups:
All dangerous Android system permissions belong to permission groups. If the device is running Android 6.0 (API level 23) and the app's targetSdkVersion is 23 or higher, the following system behavior applies when your app requests a dangerous permission:
If an app requests a dangerous permission listed in its manifest, and the app does not currently have any permissions in the permission group, the system shows a dialog box to the user describing the permission group that the app wants access to. The dialog box does not describe the specific permission within that group. For example, if an app requests the READ_CONTACTS permission, the system dialog box just says the app needs access to the device's contacts. If the user grants approval, the system gives the app just the permission it requested.
If an app requests a dangerous permission listed in its manifest, and the app already has another dangerous permission in the same permission group, the system immediately grants the permission without any interaction with the user. For example, if an app had previously requested and been granted the READ_CONTACTS permission, and it then requests WRITE_CONTACTS, the system immediately grants that permission.
Caution: Future versions of the Android SDK might move a particular permission from one group to another. Therefore, don't base your app's logic on the structure of these permission groups.
For example, if your app requests the READ_CONTACTS permission, then the WRITE_CONTACTS permission, you shouldn't assume that the system can automatically grant the WRITE_CONTACTS permission, even though it's in the same permission group as READ_CONTACTS as of Android 8.0 (API level 26).
All SMS related permissions comes under permission group SMS.
Here is the list of permissions under SMS permission group:
SEND_SMS
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
The application I am developing uses Bluetooth and Storage permissions, therefore my AndroidManifest.xml contains the following.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"></uses-permission>
However, when the app is installed, upon scanning for Bluetooth devices nothing is found until I manually switch on permission for Location in my device settings (Settings -> Apps -> [My App] -> Permissions). I have read somewhere that this permission is required for Android 6.0 (maybe 7.0) and above if you want to use the Bluetooth, but why is it not enabled upon installation with these permissions in the manifest file? Have I missed one out?
Location and Bluetooth are two different things.
You don't need to request permission to access Bluetooth as it is a normal permission, but you do need to request permission for Location as it is a dangerous permission.
You can find a list of all permissions that must be requested on runtime here.
From the official documentation.
System permissions are divided into two categories, normal and dangerous:
Normal permissions do not directly risk the user's privacy. If your app lists a normal permission in its manifest, the system grants the
permission automatically.
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.
And
If the device is running Android 5.1 or lower, or your app's target SDK is 22 or lower: If you list a dangerous permission in your
manifest, the user has to grant the permission when they install the
app; if they do not grant the permission, the system does not install
the app at all.
If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher: The app has to list the permissions in
the manifest, and it must request each dangerous permission it
needs while the app is running. The user can grant or deny each
permission, and the app can continue to run with limited
capabilities even if the user denies a permission request.
So, most likely you are testiong your app on device or emulator running API 23+ and have a request to location of the device.
Location permission is a dangerous one, so in Android 6.0 or higher user is forsed to allow location access manually. For this you have to add dangerous permissions programmatically. Take a look here for the good instruction for this.
P.S. To find out, which permissions are dangerous, and wich are normal, look here.
Certain permissions are classified as dangerous and they need to be asked for in runtime.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
Replace the READ_CONTACTS permission with location permission