diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json
index e4668703..15f11888 100644
--- a/.hbuilderx/launch.json
+++ b/.hbuilderx/launch.json
@@ -2,7 +2,7 @@
"version" : "1.0",
"configurations" : [
{
- "playground" : "standard",
+ "playground" : "custom",
"type" : "uni-app:app-android"
},
{
diff --git a/src/common/app-permission.js b/src/common/app-permission.js
new file mode 100644
index 00000000..954263ce
--- /dev/null
+++ b/src/common/app-permission.js
@@ -0,0 +1,306 @@
+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.85
+ const viewContentPadding = 20 // 减小内边距
+ const viewContentWidth = parseInt(popupViewWidth - (viewContentPadding * 2))
+ const descriptionList = drawtext(content, viewContentWidth)
+ let popupViewHeight = 60 + 20 + 20 // 减小整体高度
+ let popupViewContentList = [{
+ tag: 'font',
+ id: 'title',
+ text: title,
+ textStyles: {
+ size: '18px',
+ color: "#333333",
+ weight: "bold",
+ whiteSpace: "normal"
+ },
+ position: {
+ top: '25px', // 调整标题位置
+ left: viewContentPadding + "px",
+ width: viewContentWidth + "px",
+ height: "25px",
+ }
+ }]
+
+ const textHeight = 24 // 调整行高
+ let contentTop = 60 // 调整内容起始位置
+
+ descriptionList.forEach((item, index) => {
+ if (index > 0) {
+ popupViewHeight += textHeight;
+ contentTop += textHeight;
+ }
+ popupViewContentList.push({
+ tag: 'font',
+ id: 'content' + index + 1,
+ text: item.content,
+ textStyles: {
+ size: '15px',
+ color: "#666666",
+ lineSpacing: "50%", // 调整行间距
+ align: "left"
+ },
+ position: {
+ top: contentTop + "px",
+ left: viewContentPadding + "px",
+ width: viewContentWidth + "px",
+ height: textHeight + "px",
+ }
+ });
+ if (item.type == "break") {
+ contentTop += 8; // 减小段落间距
+ popupViewHeight += 8;
+ }
+ })
+
+ popupView = new plus.nativeObj.View("popupView", {
+ tag: "rect",
+ top: "80px", // 固定在靠近顶部的位置
+ left: (screenWidth - popupViewWidth) / 2 + "px",
+ height: popupViewHeight + "px",
+ width: popupViewWidth + "px"
+ })
+
+ // 绘制主体背景
+ popupView.drawRect({
+ color: "#FFFFFF",
+ radius: "12px",
+ borderWidth: "1px",
+ borderColor: "#E5E5E5"
+ }, {
+ top: "0px",
+ height: popupViewHeight + "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
+ console.log(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 => {
+ console.log(granted)
+ if (granted.checkResult == 0) {
+ rev({
+ isSuc: true
+ })
+ }
+ if (granted.checkResult == -1) {
+ //还未授权当前查询的权限,打开权限申请目的自定义弹框
+ closeModal() // 先关闭再弹窗
+ showModal(info)
+ plus.android.requestPermissions([_permissionID],
+ (e) => {
+ console.log(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/src/common/permission.js b/src/common/permission.js
index 9a02fef4..70571bd5 100644
--- a/src/common/permission.js
+++ b/src/common/permission.js
@@ -2,6 +2,12 @@
* 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启
*/
+import common from '@/common/common.js'
+import {
+ getPhoneEnvBool
+} from '@/common/common.js'
+const IsAndEnv = getPhoneEnvBool('AND')
+
let isIos
// #ifdef APP-PLUS
isIos = (plus.os.name == "iOS")
@@ -63,51 +69,90 @@ function judgeIosPermissionLocation() {
// 判断麦克风权限是否开启
function judgeIosPermissionRecord() {
- var result = false;
- var avaudiosession = plus.ios.import("AVAudioSession");
- var avaudio = avaudiosession.sharedInstance();
- var permissionStatus = avaudio.recordPermission();
- console.log("permissionStatus:" + permissionStatus);
- if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
- console.log("麦克风权限没有开启");
- } else {
- result = true;
- console.log("麦克风权限已经开启");
- }
- plus.ios.deleteObject(avaudiosession);
- return result;
+ return new Promise(async (resolve, reject) => {
+ const authSetting = uni.getAppAuthorizeSetting();
+ const state = authSetting.microphoneAuthorized;
+ console.log('麦克风state', state);
+ switch (state) {
+ case 'authorized':
+ console.log("麦克风权限是否开启");
+ resolve()
+ break;
+ case 'denied': // ios拒绝,安卓拒绝或者未授权都是这个
+ if (IsAndEnv) { // 安卓二次判定
+ const result = await requestAndroidPermission('android.permission.RECORD_AUDIO')
+ if (result === 1) {
+ resolve()
+ break;
+ }
+ }
+ const resultT = await common.show(
+ '提示信息',
+ '当前页面需要使用录音权限,是否前往开启?'
+ )
+ if (resultT) {
+ // 前往权限设置页面
+ uni.openAppAuthorizeSetting();
+ }
+ reject()
+ break;
+ case 'not determined': // 表示尚未请求授权,仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关
+ resolve()
+ break;
+ case 'config error': // 只有在 App 端时返回
+ resolve()
+ break;
+ default:
+ resolve()
+ break;
+ }
+ })
}
+
// 判断相机权限是否开启
function judgeIosPermissionCamera() {
- const authSetting = uni.getAppAuthorizeSetting();
- const state = authSetting.cameraAuthorized;
- console.log('state', state);
- switch (state) {
- case 'authorized':
- console.log("相机权限已经开启");
- return 'authorized';
- case 'denied':
- return 'denied';
- case 'not determined':
- return 'undetermined';
- case 'config error':
- return 'undetermined';
- default:
- return 'undetermined';
- }
- // var result = false;
- // var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
- // var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
- // console.log("authStatus:" + authStatus);
- // if (authStatus == 3) {
- // result = true;
- // console.log("相机权限已经开启");
- // } else {
- // console.log("相机权限没有开启");
- // }
- // plus.ios.deleteObject(AVCaptureDevice);
- // return result;
+
+ return new Promise(async (resolve, reject) => {
+ const authSetting = uni.getAppAuthorizeSetting();
+ const state = authSetting.cameraAuthorized;
+ console.log('相机权限', state);
+ switch (state) {
+ case 'authorized':
+ console.log("相机权限已经开启");
+ resolve()
+ break;
+ case 'denied': // ios拒绝,安卓拒绝或者未授权都是这个
+ console.log('IsAndEnv', IsAndEnv);
+ if (IsAndEnv) { // 安卓二次判定
+ const result = await requestAndroidPermission('android.permission.CAMERA')
+ console.log('安卓二次判定', result);
+ if (result === 1) {
+ resolve()
+ break;
+ }
+ }
+ const resultT = await common.show(
+ '提示信息',
+ '当前页面需要使用相机权限,是否前往开启?'
+ )
+ if (resultT) {
+ // 前往权限设置页面
+ uni.openAppAuthorizeSetting();
+ }
+ reject()
+ break;
+ case 'not determined': // 表示尚未请求授权,仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关
+ resolve()
+ break;
+ case 'config error': // 只有在 App 端时返回
+ resolve()
+ break;
+ default:
+ resolve()
+ break;
+ }
+ })
}
// 判断相册权限是否开启
@@ -283,8 +328,8 @@ function checkSystemEnableLocation() {
export default {
- judgeIosPermission,
- requestAndroidPermission,
- checkSystemEnableLocation,
- gotoAppPermissionSetting
+ judgeIosPermission,
+ requestAndroidPermission,
+ checkSystemEnableLocation,
+ gotoAppPermissionSetting
}
\ No newline at end of file
diff --git a/src/manifest.json b/src/manifest.json
index 3a5e9a32..686c8548 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -33,8 +33,8 @@
/* 模块配置 */
"modules" : {
"Camera" : {
- "description": "用于访问摄像头进行实时预览"
- },
+ "description" : "用于访问摄像头进行实时预览"
+ },
"Barcode" : {},
"Record" : {},
"VideoPlayer" : {},
@@ -66,16 +66,16 @@
/* ios打包配置 */
"ios" : {
"dSYMs" : false,
- "deploymentTarget": "11.0",
- "privacyDescription": {
- "NSCameraUsageDescription": "此应用需要访问您的摄像头来进行视频录制和拍照功能",
- "NSMicrophoneUsageDescription": "此应用需要访问您的麦克风来录制音频"
- },
- "capabilities": {
- "entitlements": {
- "com.apple.developer.avfoundation.multitasking-camera-access": true
- }
- }
+ "deploymentTarget" : "11.0",
+ "privacyDescription" : {
+ "NSCameraUsageDescription" : "此应用需要访问您的摄像头来进行视频录制和拍照功能",
+ "NSMicrophoneUsageDescription" : "此应用需要访问您的麦克风来录制音频"
+ },
+ "capabilities" : {
+ "entitlements" : {
+ "com.apple.developer.avfoundation.multitasking-camera-access" : true
+ }
+ }
},
/* SDK配置 */
"sdkConfigs" : {},
diff --git a/src/pages/pointsAndRank/badge.vue b/src/pages/pointsAndRank/badge.vue
index cc0c9dc0..1ef23d38 100644
--- a/src/pages/pointsAndRank/badge.vue
+++ b/src/pages/pointsAndRank/badge.vue
@@ -68,7 +68,7 @@
{{ detailedInfo.badgeName }}
- {{ detailedInfo.obtainTm }}
+ 获得时间:{{ detailedInfo.obtainTm }}
{
try {
- //#ifdef APP-PLUS
- console.log('申请权限', getPhoneEnvBool('AND'));
- if (getPhoneEnvBool('AND')) {
- console.log('申请权限');
- await initRecord();
- }
- // console.log('水水水水水水水水', permissionApi.judgeIosPermission('camera'));
+ //#ifdef APP-PLUS
+ console.log('申请权限');
+ try {
+ // await initRecord();
+ await permissionApi.judgeIosPermission('record')
+ await permissionApi.judgeIosPermission('camera')
+ } catch(e) {
+ console.error('摄像头或者麦克风权限申请失败:', e);
+ return;
+ }
//#endif
common.setPageCache('tipMsgsceneDesc', {
ossAddr: detailInfo.value.ossAddr,
diff --git a/src/pages/test/index.vue b/src/pages/test/index.vue
index 85bfd026..14f7c9e9 100644
--- a/src/pages/test/index.vue
+++ b/src/pages/test/index.vue
@@ -23,6 +23,7 @@