I have an Android application which need the permissions: READ_PHONE_STATE & CALL_PHONE. I've declared these permissions in the Manifest and it works fine for SDK < 23.
Now in Android 6 (SDK 23) I'm asking the user to grant this permission in runtime.
In the documentation, they say the if the user has granted one of the above permission, he actually granted all the permissions that are found in the same group permissions, in this case all the permission that are related to the phone group permissions.
But I'm facing with a problem, when I'm using telephony manager to get the deviceid, I'm getting a security exceptions that says that I don't have any access, even though the user has granted the "call phone" permission, why is that?
Update:
I'm requesting multiple permissions
In Manifest.xml
<uses-permission android:name="android.permission.CALL_PHONE">
<uses-permission android:name="android.permission.READ_PHONE_STATE">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE">
In Activity:
ActivityCompat.requestPermissions(this,new String[]
{
Manifest.permission.CALL_PHONE,
Manifest.permission.READ_EXTERNAL_STORAGE
},
permissionRequestcode);
Related
My question is similar to Android 10 request permission for ACTIVITY_RECOGNITION in a way that I also do not have a permission dialog showing on a device, but conditions are different.
My app is targeting API 29.
In manifest I have
<uses-permission android:name="android.permission.BODY_SENSORS"/> <- for test purposes
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
Requesting permission Manifest.permission.ACTIVITY_RECOGNITION as usual:
fragment.requestPermissions(permissions, GOOGLE_FIT_ANDROID_PERMISSIONS_REQUEST_CODE)
On a device with Android 9 (API28) I do not receive a permission dialog for ACTIVITY_RECOGNITION and when I check a permission status, it is always denied.
I know that permission logic is working, as when I've added BODY_SENSORS permission, I do get a permission dialog for BODY_SENSORS, but not for ACTIVITY_RECOGNITION. As a result, a permission for BODY_SENSORS is granted, but for ACTIVITY_RECOGNITION - not:
permissions array:
android.permission.BODY_SENSORS;android.permission.ACTIVITY_RECOGNITION
grantResults array:
0;-1
Answering my own question. Please don't treat it as a source of truth, it is based on my own tests. Maybe someone from GoogleFit team can comment on this.
Preconditions: your app is targeting API29 or above.
Regardless of Android version, installed on a device, you should add permissions to Manifest file according to documentation. Side note: I was able to query GoogleFit HistoryApi even without those permissions on device with Android 9, but Android 10 will not work.
<uses-permission android:name="android.permission.BODY_SENSORS"/>
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
For devices with Android 10 or above: all is simple, you should request runtime permissions, same which you've added to Manifest.
For devices with Android version 9 or below: you don't have to request runtime permissions. This is the part which was not clear from the documentation.
You may, of course, request those permissions, but for android.permission. ACTIVITY_RECOGNITION you will not receive a permission dialog and as a result permission will not be granted.
I'm working on a Cordova app that needs the permissions INTERNET, WRITE_EXTERNAL_STORAGE, ACCESS_WIFI_STATE, and CHANGE_WIFI_MULTICAST_STATE. I have requested these permissions in the manifest like so
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
INTERNET, ACCESS_WIFI_STATE, and CHANGE_WIFI_MULTICAST_STATE are considered normal permissions and according to the docs they will be automatically accepted by Android at install time and the user can't revoke them.
Now in the MainActivity created by Cordova I added this code within an if block that checks to make sure we are on 6.0 or above:
if (checkSelfPermission(Manifest.permission.ACCESS_WIFI_STATE) == PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(Manifest.permission.CHANGE_WIFI_MULTICAST_STATE) == PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "has permission");
}
else {
Log.d(TAG, "no permission");
requestPermissions(new String[] { Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
}
The problem is that on an Android device running 5.1.1 this works and I see all 4 permissions when I go to the permission settings of the app. However on a device running 7.0 and 7.1.1 I get a dialog asking to approve the WRITE_EXTERNAL_STORAGE and all other permissions, since they are normal, do not get asked for approval. They are automatically approved. The issue is that even though I have permission, on the newer devices I can't do things related to these permissions and if I go to the app settings for permissions all I see is permission Storage granted. Nothing for INTERNET, ACCESS_WIFI_STATE, or CHANGE_WIFI_MULTICAST_STATE. I have not tested specifically on a 6.0 device but I think I would have the same issue.
Why are the permissions not showing in the permission settings, and why cant I perform operations that need these permissions, even though Android says I have permission?
The documentation you linked to contains the following statement:
"The system doesn't prompt the user to grant normal permissions, and users cannot revoke these permissions. "
So all permissions except for WRITE_EXTERNAL_STORAGE will always be granted. The only permission you have to ask for is the one which can be revoked.
Why are the permissions not showing in the permission settings
Well, depending on the android version they may be a little hard to find. For example on my emulator running android 7.0, I found a list of all the permissions under Apps -> MyApp -> Permissions, and then clicking "All permissions" in the overflow menu.
I have a problem with bluetooth permission. I've declared in the manifest following lines:
<permission android:name="android.permission.BLUETOOTH" android:label="BLUETOOTH" />
<permission android:name="android.permission.BLUETOOTH_ADMIN" />
What is weird that in app settings instead of bluetooth I've got a right to add permission for Location and Storage. But ok, lets say android doesn't provide specific perms for bluetooth and these are the same as BT. Weird thing is that even when I don't give any permission to the app (not for memory, not for localization), by using following code:
int permissionCheck = ContextCompat.checkSelfPermission(this,
Manifest.permission.BLUETOOTH_ADMIN);
if(permissionCheck == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this, "granted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "not granted :(", Toast.LENGTH_SHORT).show();
}
I still get message that permission are granted. What the heck? Should I check specifically for a EXTERNAL_STORAGE and Location permissions? And why bluetooth isn't displayed in app permision configurations?
There are two types of permissions in Android:
Dangerous permissions: These permissions are required to ask on run time if targetSdkVersion is 23 or above.
Normal Permissions: If you define these permissions in Manifest that is enough.
For more details check this link given below:
https://developer.android.com/guide/topics/permissions/requesting.html#normal-dangerous
in my app i need the android internet permission.
I have insert the permission in the file AndroidManifest.xml (with others permissions)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
the build.gradle defaul config have the correct api level:
defaultConfig {
applicationId "com.mytry"
minSdkVersion 23
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
and the activity with the internet call is this:
public class ActivityLoginScreen extends Activity{
final int REQUEST_INTERNET = 1;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.INTERNET)) {
//permesso giĆ richiesto in precedenza. Negato dall'utente
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.INTERNET}, REQUEST_INTERNET);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_INTERNET: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "GRANTED", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "NO GRANTED", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
But when i launch my app and go to the activity nothing appare.
If i go in the app settings emulator, i can see only 2 permissions.
Possible solution for this problem? Where i am in wrong?
I have use this type of request in other apps without problems
Thank you.
EDIT:
For all the comments type this:
"no necessary the request because: If an app declares that it needs a normal permission, the system automatically grants the permission to the app"
this is correct.
sorry for this stupid question.
I knew the matter of default permission but my appa did not work anyway because it gave error in Internet permission.
I created a new emulator and now seems to be going.
Not all permission need to be granted by user. According to Android 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.
You only need to check for permission if the permission is belong to dangerous permission category (Ex: Location, Storage, Camera etc)
Internet permission are granted by default.
It does not require user to grant it, so you already have internet permission just enable your internet.
Normal permissions cover areas where your app needs to access data or
resources outside the app's sandbox, but where there's very little
risk to the user's privacy or the operation of other apps. For
example, permission to set the time zone is a normal permission. If an
app declares that it needs a normal permission, the system
automatically grants the permission to the app. For a full listing of
the current normal permissions, see Normal permissions.
As of API level 23, the following permissions are classified as PROTECTION_NORMAL:
For these no dailog will shown to user system will automatically grant the permission.
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
GET_PACKAGE_SIZE
INSTALL_SHORTCUT
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
REQUEST_INSTALL_PACKAGES
SET_ALARM
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
UNINSTALL_SHORTCUT
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
All dangerous Android system permissions belong to permission groups.
If the device is running Android 6.0 (API level 23)
PROTECTION_DANGEROUS permissions :
These permissions will show dialog to users.Sample Code
READ_CALENDAR
WRITE_CALENDAR
CAMERA
READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
RECORD_AUDIO
READ_PHONE_STATE
CALL_PHONE
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
BODY_SENSORS
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
This code worked my phone.But it didnt worked from my friend phone. I have permission too . I get This error ;
Neither user 10109 nor current process has android.permission.READ_PHONE_STATE.
Permission ;
<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" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
This is my Code ;
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
IMEI= telephonyManager.getDeviceId();
This is probably due to your friend running on Android 6.0 (API level 23). You need to add permissions at Runtime as well as the ones in the Manifest.
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.
Refer here for more information. Maybe take a look at this question to see how to implement runtime permissions, although it's explained in the first link as well.
As per new marshmallow os you need to configure runtime permission for "READ_SMS"
like this :
String permission = Manifest.permission.READ_SMS;
if (ContextCompat.checkSelfPermission(getContext(), permission) != PackageManager.PERMISSION_GRANTED){
permissionList.add(permission);
if (!ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), permission)){
requestPermissions(new String[]{permission}), SMS_PERMISSION);
}
}