Permission application in Android development

1. Dynamic application for permissions

        We all know that starting from Android 6.0, some dangerous permissions need to be dynamically applied while registering in xml.

1. Need to dynamically apply for permission

Manifest.permission.CONTACTS //联系人
Manifest.permission.PHONE //电话
Manifest.permission.CALENDAR //日历
Manifest.permission.CAMERA //相机
Manifest.permission.SENSORS //传感器
Manifest.permission.LOCATION //位置
Manifest.permission.STORAGE //存储
Manifest.permission.MICROPHONE //麦克风
Manifest.permission.CONTACTS //短信

        The permissions that need to be dynamically applied are mainly divided into these 9 categories. Of course, there may be more than one permission in each category, but as long as one is dynamically applied, the permission of the entire category will be obtained by default.

2. Apply for a single permission

//常量,用于回调
int MY_PERMISSION_APPLY = 1;
//要使用的相机权限
int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
//判断是否有相机权限
if (permission == PackageManager.PERMISSION_GRANTED) {
    //有权限直接执行            
} else { 
    //没有权限,提示获取权限
    String[] perms = {"android.permission.CAMERA"};
    ActivityCompat.requestPermissions(this, perms, MY_PERMISSION_APPLY);
}

        After the permission application pops up, the user's selection result needs to be processed, and executed in the callback method:

public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
    switch(permsRequestCode){
        case MY_PERMISSION_APPLY:
            boolean albumAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
            if(!albumAccepted){
                //用户拒绝了权限
            }else{
                //用户同意了权限
            }
            break;
    }
}

 3. Apply for multiple permissions at the same time

//常量,用于回调
int MY_PERMISSION_APPLY = 1;
//要使用的相机和存储权限
String[] permissions = new String[]{
            Manifest.permission.CAMERA,
            Manifest.permission.STORAGE
    };
//用于存放未同意的权限
List<String> mPermissionList = new ArrayList<>();
 
//清空未同意权限
mPermissionList.clear();
//循环得到未同意权限
for (int i = 0; i < permissions.length; i++) {
    if (ContextCompat.checkSelfPermission(mContext, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
        mPermissionList.add(permissions[i]);
    }
}
 
//判断是否有未同意权限
if (mPermissionList.isEmpty()) {
    //都有权限直接执行  
} else {
    //将List转为数组
    String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);
    ActivityCompat.requestPermissions(this, permissions, MY_PERMISSION_APPLY);
}

        Then, also add the above callback method to handle the user's selection result. 

2. Change of read and write permissions of local files

        Requirements: Android 11.0 version, sdk 32, use local Download to download files, after applying for dynamic permissions, it still prompts lack of permissions.

1、Manifest.xml

        We all know that Android needs to add corresponding permissions in Manifest.xml when developing certain functions (file reading and writing). In order to process pictures, files and other content in the Android phone. Add read and write permissions in Manifest.xml as follows:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

2. Dynamic permissions

        In Android 6.0, while adding permissions in Manifest.xml, you also need to dynamically apply for permissions during use. You should be familiar with this. Here, only the permission application code is displayed. As for the user’s rejection, no prompts, and other operations and callbacks, the callback will not be displayed.

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M
        && context.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {//请求权限
    ((Activity)context).requestPermissions(new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}

3. Scope storage

        Android 10.0 has enabled scoped storage. Even after adding permissions in the above Manifest.xml and dynamically applying for permissions in the code, when accessing folders other than the package name, it still prompts that the permissions are insufficient. At this time, we add properties in Manifest.xml to close scoped storage, which is a temporary solution officially provided by Google.

<application
    android:requestLegacyExternalStorage="true">

</application>

4. External storage permissions

        Starting from Android 11.0, scoped storage is forced to be enabled, and the above closing method does not work. At this time, if you still need to access external folders, you need to manually enable a dangerous permission—external storage permission.

Manifest.xml adds external storage permissions

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />

Manual settings open

        This permission is a special permission and needs to be opened manually by the user in the settings. Use Environment.isExternalStorageManager() to determine whether it is enabled. If it is not enabled, jump to the setting to open the interface.

public static boolean checkStorageManagerPermission(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
        context.startActivity(intent);
        return false;
    }
    return true;
}

        After opening, you can normally access the shared directory such as Download.

3. Dangerous permission pop-up window processing

1. Demand analysis

1) The system application directly grants permission

2) Use the specified signature third-party application to directly grant permissions

3) Use the normal signature third-party application to prompt normally

2. Implementation plan analysis

System APP

        System APP can directly modify the grantDefaultSystemHandlerPermissions() method in DefaultPermissionGrantPolicy.java to directly configure default permissions for system applications.

Restrictions: The system source code needs to be modified, so third-party applications cannot implement it

File location: frameworks/base/services/core/java/com/android/server/pm/permission/

Modify permission attributes

1) Directly modify the permission level Change the dangerous (dangerous) permission to normal (normal) permission in frameworks/base/core/res/AndroidManifest.xml, and all applications will directly obtain the permission, which does not apply to the above requirements.

2) Modify the dangerous (dangerous) permission to Signature (signature) permission, so that the specified signature APP can obtain the permission, but other third-party signed APPs cannot obtain the permission.

        ps: Is it possible to set permissions with the same name: for example, if you set permissions with the same name and level of the camera, the same signature automatically has permissions, and other third-party apps apply for the default dangerous camera permissions, and a pop-up prompt will appear.

        It needs to be verified, and it feels that it is not feasible.

Specify APP permission

        Add the specified package name to the grantPermissionsLpw of PackageManagerService.java. This method can be found in many materials on the Internet, but the file is found in the current source code, but the method is not found.

        ps: Whether it is possible to change the above judging package name into a judging signature remains to be verified.

Permission whitelist (optimal)

1. Add package name whitelist to /frameworks/base/core/res/res/values/config.xml

2. Declare whitelist variables in /frameworks/base/core/res/res/values/symbols.xml

3. Judging the permission whitelist in the grantPermissions method in frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java

 Reference: Android 9.0 Setting Whitelist to Grant App Permissions - Power of Two - Blog Garden

        This method also needs to modify the configuration file to add the whitelist, so the third-party specified signature file cannot directly obtain the permission. All permissions passed also do not apply.

        However, through the logic of the source code, it is found that the following code should be the method for judging the signature of the APP system:

if(bp.isSignature()){
    allowedSig = grantSignaturePermission(perm, pkge, bp, origPermissions);
}

        Therefore, the above judgment white list can be changed to judge signature approval authority, namely:

if(bp.isRuntime()){

    else{
        allowedSig = grantSignaturePermission(perm, pkge, bp, origPermissions);
        if(allowedSig){
            grant = GRANT_INSTALL;
        }
    }

}

        In this way, both the specified signature APP and the system APP can skip the permission verification.

Handle tooltips directly

        Judgment and processing are performed directly in GrantPermissionsActivity, but signature verification is also required according to requirements.

Feasible plan forecast (to be verified)

1. Customize a new permission in AndroidManifest.xml, the level is Signature;

2. Add the newly defined permissions to the permission group in DefaultPermissionGrantPolicy.java;

        In this way, the application with the specified signature directly obtains the new permission, and because only one permission of the same group permission is passed, other permissions are not verified and passed directly.

        Apps that need to be passed directly need to use the specified signature, and also need to apply for our custom new permissions.

Guess you like

Origin blog.csdn.net/c19344881x/article/details/128920179