Regarding the solution that requires simultaneous notification of usage permissions when listing on the Huawei App Market (applicable to uniapp, the same idea applies to native development), just copy and paste!

Preface

During the recent review of Huawei App Market, a new rule was added as follows:

您的应用在运行时,未同步告知权限申请的使用目的,向用户索取(存储、相机、位置信息)等权限,不符合华为应用市场审核标准。
测试步骤:点击在线聊-拍照/图片,申请存储、相机权限;点击首页-地图找房,申请位置信息权限。
修改建议:APP在调用终端敏感权限时,应同步说明权限申请的使用目的,包括但不限于申请权限的名称、服务的具体功能、用途;告知方式不限于弹窗、蒙层、浮窗、或者自定义操作系统权限弹框等。请排查应用内所有权限申请行为,确保均符合要求。
请参考《审核指南》第7.21相关审核要求:https://developer.huawei.com/consumer/cn/doc/app/50104-07#h3-1683701612940-2
APP常见个人信息保护问题FAQ请参考:https://developer.huawei.com/consumer/cn/doc/app/FAQ-faq-05#h1-1698326401789-0
测试环境:Wi-Fi联网、HonmonyOS 2.0(Nova5)、中文环境。

I will talk about a simple processing method in this blog. Others on the Internet have written too complicated methods. You can test it yourself online.

Look at the effect first

Insert image description here

Encapsulation permission judgment tool class

Create a new authorizeUtils.ts file and copy the following code without thinking:

const checkIsIos = async () => {
    
    
        return new Promise((resolve => {
    
    
                uni.getSystemInfo({
    
    
                        success: function (res) {
    
    
                                resolve(systemInfo.value.platform === "ios")
                        }
                });
        }))
}
export default class authorizeUtils {
    
    
        /**
         * 授权前告知用户使用意图
         * @param content 
         * @returns 
         */
        static showAuthTipModal = async (authorize: string) => {
    
    
                // #ifdef H5
                if (1 === 1) {
    
    
                        return true
                }
                // #endif
                // ios端在manifest.json配置权限使用说明,以下权限判断仅在安卓端可用
                let isIos = await checkIsIos()
                if (isIos) return true
                let compat: any = plus.android.importClass('androidx.core.content.ContextCompat')
                let context = plus.android.runtimeMainActivity()
                let result = compat.checkSelfPermission(context, authorize)
                console.log("result===", result);
                if (result === 0) return true
                // // 如果已经授权直接返回
                const contentData = {
    
    
                        ['android.permission.ACCESS_FINE_LOCATION']: {
    
    
                                title: "定位权限说明",
                                describe: "便于您使用该功能在地图找房中根据您的位置检索附近的房源,请您确认授权,否则无法使用该功能"
                        },
                        ["android.permission.READ_EXTERNAL_STORAGE"]: {
    
    
                                title: "相册权限说明",
                                describe: "便于您使用该功能上传您的照片/图片/视频及用户实名认证信息、发布房源时上传图片,请您确认授权,否则无法使用该功能"
                        },
                        ["android.permission.CAMERA"]: {
    
    
                                title: "拍摄权限说明",
                                describe: "便于您使用该功能拍摄身份证、房源、头像、房产证等信息,请您确认授权,否则无法使用该功能"
                        },
                        ["android.permission.CALL_PHONE"]: {
    
    
                                title: "拨打电话权限说明",
                                describe: "便于您使用该功能拨打房东、经纪人、管家、客服电话,请您确认授权,否则无法使用该功能"
                        },
                }
                return new Promise((resolve) => {
    
    
                        uni.showModal({
    
    
                                title: contentData[authorize].title,
                                content: contentData[authorize].describe,
                                success: (res) => {
    
    
                                        resolve(!!res.confirm)
                                },
                                fail: () => {
    
    

                                }
                        })
                })



        }
        /**
         * 用户拒绝授权提示手动授权
         */
        static showManualAuth = async (authorize: string) => {
    
    
                let isIos = await checkIsIos()
                if (isIos) return true
                const contentData = {
    
    
                        ['android.permission.ACCESS_FINE_LOCATION']: "获取定位权限失败,请手动打开授权或检查系统定位开关",
                        ["android.permission.READ_EXTERNAL_STORAGE"]: "获取相册权限失败,请手动打开授权",
                        ["android.permission.CAMERA"]: "获取拍摄权限失败,请手动打开授权",
                        ["android.permission.CALL_PHONE"]: "获取拨打电话权限失败,请手动打开授权",
                }
                uni.showModal({
    
    
                        title: '提示',
                        content: contentData[authorize],
                        confirmText: "去设置",
                        success: (res) => {
    
    
                                if (res.confirm) {
    
    
                                        uni.openAppAuthorizeSetting({
    
    
                                                success(res) {
    
    
                                                        console.log(res);
                                                }
                                        });
                                }
                                if (res.cancel) {
    
    
                                        console.log('用户点击取消');
                                }
                        }
                });
        }
}

Usage examples of tool classes

Example of making a call:

   // 检查是否授权拨打电话权限
        let flag = await authorizeUtils.showAuthTipModal("android.permission.CALL_PHONE")
        // 用户拒绝授权
        if (!flag) return
        uni.makePhoneCall({
    
    
            phoneNumber, fail: () => {
    
    
                // 权限开启失败提示用户手动打开权限
                authorizeUtils.showManualAuth("android.permission.CALL_PHONE")
            }
        });

Example of obtaining user location information:

    getUserLocation = async (): Promise<null | {
    
     longitude: number, latitude: number }> => {
    
    
        return new Promise(async (resolve) => {
    
    
            let authFlag = await authorizeUtils.showAuthTipModal("android.permission.ACCESS_FINE_LOCATION")
            if (!authFlag) return resolve(null)
            uni.getLocation({
    
    
                type: "wgs84",
                success: ({
    
     longitude, latitude }) => {
    
    
                    return resolve({
    
     longitude, latitude })
                },
                fail: (fail) => {
    
    
                    this.hideLoading()
                    authorizeUtils.showManualAuth("android.permission.ACCESS_FINE_LOCATION")
                    return resolve(null)
                }
            });
        })
    }

Notice

The image selection method chooseImage on the app side defaults to the pop-up option of taking a photo and selecting from the album. However, taking a photo and selecting from the album are two different permissions, so this pop-up option needs to be written manually. When the user chooses to take a photo, the camera permission is requested and the selection from the album is To request storage permission, I attach my code here for reference only:

const handleUpload = async (openType: "camera" | "album") => {
    
    
	if (props.disabled) return;
	// #ifdef APP-PLUS
	const permissionType = openType === "album" ? "android.permission.READ_EXTERNAL_STORAGE" : "android.permission.CAMERA";
	let authFlag = await authorizeUtils.showAuthTipModal(permissionType);
	if (!authFlag) return;
	// #endif

	uni.chooseImage({
    
    
		sourceType: [openType],
		count: props.limit,
		success: async (success) => {
    
    
		
		},
		fail: (fail) => {
    
    
			if ([0, 11, 12].includes(fail.code)) return;
			authorizeUtils.showManualAuth(permissionType);
		}
	});
};

Android permission list

// android.permission.ACCESS_FINE_LOCATION	位置权限
// android.permission.ACCESS_COARSE_LOCATION	模糊位置权限(蓝牙\ble依赖)
// android.permission.CAMERA	摄像头权限
// android.permission.READ_EXTERNAL_STORAGE	外部存储(含相册)读取权限
// android.permission.WRITE_EXTERNAL_STORAGE	外部存储(含相册)写入权限
// android.permission.RECORD_AUDIO	麦克风权限
// android.permission.READ_CONTACTS	通讯录读取权限
// android.permission.WRITE_CONTACTS	通讯录写入权限
// android.permission.READ_CALENDAR	日历读取权限
// android.permission.WRITE_CALENDAR	日历写入权限
// android.permission.READ_SMS	短信读取权限
// android.permission.SEND_SMS	短信发送权限
// android.permission.RECEIVE_SMS	接收新短信权限
// android.permission.READ_PHONE_STATE	获取手机识别码等信息的权限
// android.permission.CALL_PHONE	拨打电话权限
// android.permission.READ_CALL_LOG	获取通话记录权限

Summarize

Why is it so difficult to beat workers? It’s so difficult to beat workers! !

Guess you like

Origin blog.csdn.net/wz9608/article/details/135202285