diff --git a/js_sdk/yu-app-permission/package.json b/js_sdk/yu-app-permission/package.json new file mode 100644 index 0000000..f1296b3 --- /dev/null +++ b/js_sdk/yu-app-permission/package.json @@ -0,0 +1,20 @@ +{ + "id": "yu-app-permission", + "name": "解决APP未向用户告知权限申请目的,导致华为等上架被拒问题", + "displayName": "解决APP未向用户告知权限申请目的,导致华为等上架被拒问题", + "version": "0.0.1", + "description": "纯JS单个文件,解决安卓APP上架时未向用户告知权限申请目的等被拒问题", + "keywords": [ + "华为", + "上架", + "权限", + "上架被拒", + "app" + ], + "dcloudext": { + "category": [ + "JS SDK", + "通用 SDK" + ] + } +} \ No newline at end of file diff --git a/js_sdk/yu-app-permission/yu-app-permission.js b/js_sdk/yu-app-permission/yu-app-permission.js new file mode 100644 index 0000000..4f529c9 --- /dev/null +++ b/js_sdk/yu-app-permission/yu-app-permission.js @@ -0,0 +1,297 @@ +let popupView = null // 窗口实例 +export function showModal(info) { + const title = info && info.title ? info.title : '标题' + const content = info && info.content ? info.content : '请输入内容' + let screenWidth = plus.screen.resolutionWidth + let screenHeight = plus.screen.resolutionHeight + const popupViewWidth = screenWidth * 0.7 + const viewContentPadding = 20 + const viewContentWidth = parseInt(popupViewWidth - (viewContentPadding * 2)) + const descriptionList = drawtext(content, viewContentWidth) + let popupViewHeight = 80 + 20 + 20 + 20 + let popupViewContentList = [{ + tag: 'font', + id: 'title', + text: title, + textStyles: { + size: '18px', + color: "#333", + weight: "bold", + whiteSpace: "normal" + }, + position: { + top: '60px', + left: viewContentPadding + "px", + width: viewContentWidth + "px", + height: "30px", + } + }] + const textHeight = 18 + let contentTop = 110 + descriptionList.forEach((item, index) => { + if (index > 0) { + popupViewHeight += textHeight; + contentTop += textHeight; + } + popupViewContentList.push({ + tag: 'font', + id: 'content' + index + 1, + text: item.content, + textStyles: { + size: '14px', + color: "#666", + lineSpacing: "50%", + align: "center" + }, + position: { + top: contentTop + "px", + left: viewContentPadding + "px", + width: viewContentWidth + "px", + height: textHeight + "px", + } + }); + if (item.type == "break") { + contentTop += 10; + popupViewHeight += 10; + } + }) + popupView = new plus.nativeObj.View("popupView", { //创建底部图标菜单 + tag: "rect", + top: "50px", + left: '15%', + height: popupViewHeight + "px", + width: "70%" + }) + popupView.drawRect({ + color: "#FFFFFF", + radius: "8px", + borderWidth: "2px", + borderColor: "#ddd" + }, { + top: "40px", + height: popupViewHeight - 40 + "px", + }) + popupView.draw(popupViewContentList) + popupView.show() +} + + +function closeModal() { + // 在不再需要 popupView 时关闭它 + popupView && popupView.close(); + popupView = null; +} + +// 文字换行 +function drawtext(text, maxWidth) { + let textArr = text.split(""); + let len = textArr.length; + // 上个节点 + let previousNode = 0; + // 记录节点宽度 + let nodeWidth = 0; + // 文本换行数组 + let rowText = []; + // 如果是字母,侧保存长度 + let letterWidth = 0; + // 汉字宽度 + let chineseWidth = 14; + // otherFont宽度 + let otherWidth = 7; + for (let i = 0; i < len; i++) { + if (/[\u4e00-\u9fa5]|[\uFE30-\uFFA0]/g.test(textArr[i])) { + if (letterWidth > 0) { + if (nodeWidth + chineseWidth + letterWidth * otherWidth > maxWidth) { + rowText.push({ + type: "text", + content: text.substring(previousNode, i) + }); + previousNode = i + nodeWidth = chineseWidth + letterWidth = 0 + } else { + nodeWidth += chineseWidth + letterWidth * otherWidth + letterWidth = 0 + } + } else { + if (nodeWidth + chineseWidth > maxWidth) { + rowText.push({ + type: "text", + content: text.substring(previousNode, i) + }) + previousNode = i + nodeWidth = chineseWidth + } else { + nodeWidth += chineseWidth + } + } + } else { + if (/\n/g.test(textArr[i])) { + rowText.push({ + type: "break", + content: text.substring(previousNode, i) + }) + previousNode = i + 1 + nodeWidth = 0 + letterWidth = 0 + } else if (textArr[i] == "\\" && textArr[i + 1] == "n") { + rowText.push({ + type: "break", + content: text.substring(previousNode, i) + }) + previousNode = i + 2 + nodeWidth = 0 + letterWidth = 0 + } else if (/[a-zA-Z0-9]/g.test(textArr[i])) { + letterWidth += 1; + if (nodeWidth + letterWidth * otherWidth > maxWidth) { + rowText.push({ + type: "text", + content: text.substring(previousNode, i + 1 - letterWidth) + }) + previousNode = i + 1 - letterWidth + nodeWidth = letterWidth * otherWidth + letterWidth = 0 + } + } else { + if (nodeWidth + otherWidth > maxWidth) { + rowText.push({ + type: "text", + content: text.substring(previousNode, i) + }); + previousNode = i + nodeWidth = otherWidth + } else { + nodeWidth += otherWidth + } + } + } + } + if (previousNode < len) { + rowText.push({ + type: "text", + content: text.substring(previousNode, len) + }) + } + return rowText +} + + + +//权限检测 +export function requestPermissions(info) { + const permissionID = info.permissionID + return new Promise((rev, jec) => { + if (!permissionID) { + rev({ + isSuc: false, + msg: "缺少permissionID" + }) + return false + } + //判断安卓与ios设备 + if (plus.os.name == 'Android') { + let _permissionID = 'android.permission.' + permissionID; + plus.android.checkPermission(_permissionID, + granted => { + if (granted.checkResult == 0) { + rev({ + isSuc: true + }) + } + if (granted.checkResult == -1) { + //还未授权当前查询的权限,打开权限申请目的自定义弹框 + closeModal() // 先关闭再弹窗 + showModal(info) + plus.android.requestPermissions([_permissionID], + (e) => { + //关闭权限申请目的自定义弹框 + if (e.granted.length > 0) { + closeModal() + //当前查询权限已授权,此时可以通知页面执行接下来的操作 + rev({ + isSuc: true + }) + } + if (e.deniedPresent.length > 0) { + closeModal() + //当前查询权限已授权,此时可以通知页面执行接下来的操作 + rev({ + isSuc: false, + msg: "用户已拒绝" + }) + } + if (e.deniedAlways.length > 0) { + //当前查询权限已被永久禁用,此时需要引导用户跳转手机系统设置去开启 + uni.showModal({ + title: '温馨提示', + content: '还没有该权限,立即去设置开启?', + cancelText: "取消", + confirmText: "去设置", + showCancel: true, + confirmColor: '#000', + cancelColor: '#666', + success: (res) => { + if (res.confirm) { + goSetting(); + } + if (res.cancel) { + rev({ + isSuc: false, + msg: "取消前往权限设置页面" + }) + } + }, + fail(e) { + rev({ + isSuc: false, + msg: e.message || "弹窗失败" + }) + }, + complete() { + closeModal() + } + }) + } + }) + } + }, + error => { + rev({ + isSuc: false, + mes: error.message || '检查权限失败' + }) + } + ); + + } else { + //IOS不需要添加自定义弹框来描述权限目的,因为在配置文件的隐私信息访问的许可描述里可添加 + rev({ + isSuc: true + }) + } + }) +} +//跳转手机系统设置 +export function goSetting() { + if (plus.os.name == "iOS") { + var UIApplication = plus.ios.import("UIApplication"); + var application2 = UIApplication.sharedApplication(); + var NSURL2 = plus.ios.import("NSURL"); + var setting2 = NSURL2.URLWithString("app-settings:"); + application2.openURL(setting2); + plus.ios.deleteObject(setting2); + plus.ios.deleteObject(NSURL2); + plus.ios.deleteObject(application2); + } else { + var Intent = plus.android.importClass("android.content.Intent"); + var Settings = plus.android.importClass("android.provider.Settings"); + var Uri = plus.android.importClass("android.net.Uri"); + var mainActivity = plus.android.runtimeMainActivity(); + var intent = new Intent(); + intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + var uri = Uri.fromParts("package", mainActivity.getPackageName(), null); + intent.setData(uri); + mainActivity.startActivity(intent); + } +} \ No newline at end of file diff --git a/pages/index.vue b/pages/index.vue index e26e970..5b15525 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -551,6 +551,14 @@