完善通话获取权限的逻辑

This commit is contained in:
田岩
2025-12-12 18:03:26 +08:00
parent 9f2ff43103
commit 04da7192e2
7 changed files with 431 additions and 68 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
"version" : "1.0",
"configurations" : [
{
"playground" : "standard",
"playground" : "custom",
"type" : "uni-app:app-android"
},
{
+306
View File
@@ -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);
}
}
+90 -45
View File
@@ -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
}
+12 -12
View File
@@ -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" : {},
+1 -1
View File
@@ -68,7 +68,7 @@
<view class="points-title">{{ detailedInfo.badgeName }}</view>
<view class="points-div select-institution-div">
<view class="points-remark">{{ detailedInfo.remark }}</view>
<view class="points-time">{{ detailedInfo.obtainTm }}</view>
<view class="points-time">获得时间{{ detailedInfo.obtainTm }}</view>
</view>
<view class="points-button-div">
<uv-button
+10 -7
View File
@@ -247,14 +247,17 @@
const toTalking = async () => {
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,
+11 -2
View File
@@ -23,6 +23,7 @@
<script setup>
import common from '@/common/common';
import permision from '@/common/permission'
import {
get_base_url
} from '../../api/request';
@@ -34,8 +35,16 @@
const bbbb = () => {
}
const aaaa = () => {
common.navigateTo('/pages/test/testChat')
const aaaa = async() => {
await permision.judgeIosPermission('camera')
// var result = await permision.requestAndroidPermission('android.permission.CAMERA')
// console.log('result', result);
// const permResult = await permission.requestAndroidPermission(
// 'android.permission.RECORD_AUDIO');
// common.navigateTo('/pages/test/testChat')
}
</script>