判断iOS设备的PUSH通知设置状态(打开。。。/关闭)

本文详细解析了iOS设备中的远程通知类型及其如何反映用户在通知设置中的偏好。通过枚举不同类型的定义与组合,读者能清晰地了解用户如何自定义接收通知的方式。
typedef NS_OPTIONS(NSUInteger, UIRemoteNotificationType) {
    UIRemoteNotificationTypeNone    = 0,
    UIRemoteNotificationTypeBadge   = 1 << 0,
    UIRemoteNotificationTypeSound   = 1 << 1,
    UIRemoteNotificationTypeAlert   = 1 << 2,
    UIRemoteNotificationTypeNewsstandContentAvailability = 1 << 3,
} NS_ENUM_AVAILABLE_IOS(3_0);


UIRemoteNotificationTypeNone = 0,

UIRemoteNotificationTypeBadge = 1,

UIRemoteNotificationTypeSound = 2,

UIRemoteNotificationTypeAlert = 4,

UIRemoteNotificationTypeNewsstandContentAvailability = 8


通过 UIRemoteNotificationType type = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];可以得知type的值,根据type的值可以判断出用户在通知设置中是如何设置的。

比如:type = 3,那么用户打开的是UIRemoteNotificationTypeBadge和UIRemoteNotificationTypeSound;

    type = 6,那么用户打开的是UIRemoteNotificationTypeSound和UIRemoteNotificationTypeAlert,

以此类推即可~


这是我的权限弹窗组件, 里面加一个手机通知栏的权限 怎么加 <template> <!-- 权限申请弹窗组件 --> <view v-if="showPopup" class="uni-popup" :style="{top:isNativeHead?'':StatusBar}"> <view :class="[type, ani, animation ? 'ani' : '']" class="uni-custom uni-popup__wrapper" @click.stop="close(true)"> <view class="uni-popup__wrapper-box"> <view class="title">{{currentPermissionData.title}}</view> <view class="content">{{currentPermissionData.content}}</view> <!-- 操作按钮区域 --> <view class="action-buttons"> <button class="btn cancel" @click.stop="handleLater">稍后再说</button> <button class="btn confirm" @click.stop="handleAuthorize">立即授权</button> </view> </view> </view> </view> </template> <script> // 权限状态常量 const IOS_PERMISSION_STATUS = { NOT_DETERMINED: 0, // 未决定 RESTRICTED: 1, // 受限制 DENIED: 2, // 拒绝 AUTHORIZED: 3, // 授权 LIMITED: 4 // 有限授权(仅照片) }; // 权限信息配置 - 集中管理 const PERMISSION_DATA = { // 'WRITE_EXTERNAL_STORAGE': { // title: "霍小帮对存储空间/照片权限申请说明", // content: "便于您使用该功能上传您的照片/图片/视频及用于更换头像、意见反馈、保存相册、发布商品/分享、下载与客服沟通等场景中读取和写入相册和文件内容。" // }, // 'ACCESS_FINE_LOCATION': { // title: "霍小帮对地理位置权限申请说明", // content: "便于应用程序可以提供基于位置的服务、定位导航、附近搜索等功能。APP收集WIFI扫描结果的目的为提供定位服务,仅在首页获取定位的城市的时候需要使用到,只收集周围可用WIFI网络的名称和信号强度等信息,不收集WIFI密码等敏感信息!为同城配送功能会获取骑手当前位置,不储存任何隐私信息!" }, // 'CAMERA':{ // title: "霍小帮对相机/摄像头权限申请说明", // content: "便于您使用该功能拍照上传您的照片/视频及用于更换头像、意见反馈、保存相册、发布商品/动态、下载与客服沟通等场景中使用" // }, // 'RECORD_AUDIO':{ // title: "霍小帮对麦克风权限申请说明", // content: "便于您使用该功能进行录音、语音通话、发布语音、与客服语音沟通等场景中使用" // }, // 'READ_PHONE_STATE':{ // title: "霍小帮对获取设备信息申请说明", // content: "首次或切换设备请允许此权限,便于您收到APP的系统通知或APP内平台公告/好友消息通知的场景中使用,不会泄露任何个人信息,我们只保存您的设备ID用于发送消息通知" // }, // 'CALL_PHONE': { // title: "霍小帮对拨打/管理电话权限申请说明", // content: "便于您使用该功能联系买家、骑手或者客服、业务经理与联系等场景下使用" // } WRITE_EXTERNAL_STORAGE: { title: "存储空间/照片权限说明", content: "用于上传照片/图片/视频、更换头像、意见反馈、保存相册等功能", iosPermission: "PHPhotoLibrary" // iOS 对应的权限 }, ACCESS_FINE_LOCATION: { title: "地理位置权限说明", content: "用于提供定位服务、附近搜索等功能,保护您的隐私安全", iosPermission: "CLLocationManager" }, CAMERA: { title: "相机/摄像头权限说明", content: "用于拍照上传照片/视频、更换头像、发布商品等功能", iosPermission: "AVCaptureDevice" }, RECORD_AUDIO: { title: "麦克风权限说明", content: "用于语音通话、语音消息、客服沟通等功能", iosPermission: "AVAudioSession" }, READ_PHONE_STATE: { title: "设备信息权限说明", content: "用于系统通知、消息推送功能,保护您的个人信息安全", iosPermission: "CNContactStore" }, CALL_PHONE: { title: "电话权限说明", content: "用于联系买家、骑手或客服等功能", iosPermission: "CNContactStore" } }; export default { name: 'YkAuthPopup', props: { animation: { type: Boolean, default: true }, type: { type: String, default: 'top' }, show: { type: Boolean, default: true }, isNativeHead: { type: Boolean, default: false }, permissionID: { type: [String, Number], required: true } }, data() { return { ani: '', showPopup: false, StatusBar: '', refuseNum: 0, // 拒绝次数 currentPermissionData: {}, // 当前权限数据 authList: PERMISSION_DATA // 权限配置映射 } }, watch: { permissionID: { immediate: true, handler(newVal) { // 更新当前权限数据 this.currentPermissionData = this.authList[newVal] || {}; } } }, created() { // #ifdef APP-PLUS this.getSystemInfo(); // #endif }, methods: { // 获取状态栏高度 getSystemInfo() { uni.getSystemInfo({ success: (e) => { this.StatusBar = e.statusBarHeight + 'px'; } }) }, open() { this.$nextTick(() => { setTimeout(() => { this.ani = 'uni-' + this.type; // 延迟后自动检查权限 setTimeout(() => { this.checkPermissions(); }, 300); }, 30); }); }, close() { this.ani = ''; this.$nextTick(() => { setTimeout(() => { this.showPopup = false; }, 300); }); }, // 稍后再说处理 handleLater() { this.close(); this.refuseNum++; // 如果拒绝超过3次,显示引导提示 if (this.refuseNum >= 3) { this.$emit('permission-denied', this.permissionID); } }, // 立即授权处理 handleAuthorize() { this.close(); this.requestPermissions(); }, // 统一权限检查方法 async checkPermissions() { var _this = this const platform = plus.os.name; // Android 权限检查 if (platform === 'Android') { try { const permissionStr = 'android.permission.' + this.permissionID; const result = await new Promise((resolve) => { plus.android.checkPermission(permissionStr, resolve); }); if (result?.checkResult === -1) { // 未授权:显示弹窗(已显示) this.showPopup = true; return; } // 已授权,通知父组件 this.$emit('changeAuth'); } catch (error) { console.error('权限检查失败:', error); } }else if (platform === 'iOS') { // try { // const granted = await this.checkIOSPermission(); // if (granted) { // // 已授权,通知父组件 // this.$emit('changeAuth'); // } // } catch (error) { // console.error('iOS权限检查失败:', error); // } //IOS不需要添加自定义弹框来描述权限目的,因为在配置文件的隐私信息访问的许可描述里可添加 //正常可以直接调用uni的API调起权限询问弹框使用各种权限,下面的判断使用场景主要是在IOS禁用某权限后,这个可以判断有无权限,进而引导用户跳转设置开启,仅列出了位置、相册、通讯录、相机、录音等权限,其他IOS权限可具体参考 https://ext.dcloud.net.cn/plugin?id=15787 let result = 0; let permissionID = this.permissionID console.log(permissionID,'permissionID'); if (permissionID == 'ACCESS_FINE_LOCATION') { //IOS检测位置权限 let cLLocationManager = plus.ios.importClass("CLLocationManager"), authStatus = cLLocationManager.authorizationStatus(), enable = cLLocationManager.locationServicesEnabled(); if (enable && authStatus != 2) { result = 1; } else { result = 0; } plus.ios.deleteObject(cLLocationManager); } else if (permissionID == 'WRITE_EXTERNAL_STORAGE') { //IOS检测相册权限 let PHPhotoLibrary = plus.ios.importClass("PHPhotoLibrary"), authStatus = PHPhotoLibrary.authorizationStatus(); if (authStatus === 3) { result = 1; } else { result = 0; } plus.ios.deleteObject(PHPhotoLibrary); } else if (permissionID == 'CAMERA') { //IOS检测相机/摄像头权限 let avCaptureDevice = plus.ios.importClass("AVCaptureDevice"), authStatus = avCaptureDevice.authorizationStatusForMediaType("vide"); if (authStatus === 3) { result = 1; } else { result = 0; } plus.ios.deleteObject(avCaptureDevice); } else if (permissionID == 'CALL_PHONE') { //IOS检测通讯录权限 let contactStore = plus.ios.importClass("CNContactStore"), authStatus = contactStore.authorizationStatusForEntityType(0); // console.log(authStatus,'authStatus'); if (authStatus === 3) { result = 1; } else { result = 0; } plus.ios.deleteObject(contactStore); }else if(permissionID == 'RECORD_AUDIO'){ //IOS检测麦克风权限 let aVAudioSession = plus.ios.importClass("AVAudioSession"), aVAudio = aVAudioSession.sharedInstance(), authStatus = aVAudio.recordPermission(); if ([1684369017, 1970168948].includes(authStatus)) { result = 0; } else { result = 1; } plus.ios.deleteObject(aVAudioSession); } console.log(result,'result'); if (result) { //当前查询权限已授权,此时可以通知页面执行接下来的操作 _this.$emit('changeAuth') } else { this.showPopup = true; // //当前查询的权限已禁用,引导用户跳转手机系统设置去开启 // if(permissionID == 'READ_PHONE_STATE'){ // }else{ // console.log(this.currentPermissionData,'this.currentPermissionData'); // this.$util.showModal({ // title: '温馨提示【'+permissionID+'】', // content: '请再设置打开此权限,更好使用此页面功能~',//是否立刻前往?' // // cancelText: "取消", // confirmText: "我知道了", // showCancel: true, // confirmColor: '#000', // cancelColor: '#666', // success: (res) => { // if (res.confirm) { // // _this.goSetting(); // } // } // }) // } } } }, // 修复后的 iOS 权限检查方法 async checkIOSPermission() { try { // 特殊处理不需要权限检查的情况 if (this.permissionID === 'READ_PHONE_STATE') { // iOS 设备信息不需要额外权限 return true; } // 获取对应的权限名 const permissionClass = this.currentPermissionData?.iosPermission; if (!permissionClass) { console.error(`未配置权限: ${this.permissionID}`); return false; } // 安全导入 iOS let manager; try { manager = plus.ios.importClass(permissionClass); if (!manager) { console.warn(`无法导入iOS: ${permissionClass}`); return false; } } catch (importError) { console.error(`导入iOS失败: ${permissionClass}`, importError); return false; } // 统一权限状态检查 let granted = false; switch (this.permissionID) { case 'ACCESS_FINE_LOCATION': // 位置权限检查 const authStatus = manager.authorizationStatus?.(); const enabled = manager.locationServicesEnabled?.(); granted = !!enabled && authStatus !== 2; break; case 'WRITE_EXTERNAL_STORAGE': // 存储权限检查 granted = manager.authorizationStatus?.() === 3; break; case 'CAMERA': // 相机权限检查 granted = manager.authorizationStatusForMediaType?.("vide") === 3; break; case 'CALL_PHONE': case 'READ_PHONE_STATE': // 电话权限检查 // iOS 14+ 需要使用 CNContactStore 检查通讯录权限 const authStatusPhone = manager.authorizationStatusForEntityType?.(0); granted = authStatusPhone === 3; break; case 'RECORD_AUDIO': // 麦克风权限检查 const session = manager.sharedInstance?.(); const status = session?.recordPermission?.(); // 使用更安全的状态检查方式 const deniedStatuses = [1684369017, 1970168948]; granted = !deniedStatuses.includes(status); break; default: console.warn(`未处理的权限型: ${this.permissionID}`); granted = false; } return granted; } catch (error) { console.error(`iOS权限检查失败: ${this.permissionID}`, error); return false; } finally { // 确保释放原生对象 if (manager) { try { plus.ios.deleteObject(manager); } catch (deleteError) { console.warn(`释放iOS对象失败:`, deleteError); } } } }, // 请求权限的统一方法 async requestPermissions() { const platform = plus.os.name; if (platform === 'Android') { await this.requestAndroidPermission(); } else if (platform === 'iOS') { await this.requestIOSPermission(); } }, // Android 请求权限 requestAndroidPermission() { return new Promise((resolve) => { const permissionStr = 'android.permission.' + this.permissionID; plus.android.requestPermissions([permissionStr], (e) => { if (e.granted.length > 0) { this.$emit('changeAuth'); } else if (e.deniedAlways.length > 0) { this.showSettingGuide(); } resolve(); }); }); }, // iOS权限检查与请求方法 async requestIOSPermission() { // 特殊处理不需要请求的权限 if (this.permissionID === 'READ_PHONE_STATE') { console.log('iOS设备信息权限不需要请求'); this.$emit('changeAuth'); return true; } try { // 1. 获取原生权限管理器 const { manager, checkMethod, requestMethod } = this.getIOSPermissionManager(); if (!manager || !checkMethod) { console.warn(`不支持此权限型: ${this.permissionID}`); return false; } // 2. 检查当前权限状态 const status = await this.checkIOSPermissionStatus(manager, checkMethod); console.log(`权限 ${this.permissionID} 当前状态:`, status); if (status === IOS_PERMISSION_STATUS.AUTHORIZED) { console.log('权限已授权'); this.$emit('changeAuth'); return true; } if (status === IOS_PERMISSION_STATUS.DENIED) { console.log('权限已永久拒绝'); this.showSettingGuide(); return false; } // 3. 请求权限 if (status === IOS_PERMISSION_STATUS.NOT_DETERMINED) { console.log('准备请求权限:', this.permissionID); const granted = await this.requestIOSPermissionNative(manager, requestMethod); // 检查最终状态 const finalStatus = await this.checkIOSPermissionStatus(manager, checkMethod); if (finalStatus === IOS_PERMISSION_STATUS.AUTHORIZED) { console.log('授权成功'); this.$emit('changeAuth'); return true; } console.log('最终权限状态:', finalStatus); if (finalStatus === IOS_PERMISSION_STATUS.DENIED) { this.showSettingGuide(); } return false; } return false; } catch (error) { console.error('iOS权限处理异常:', error); return false; } }, // 获取iOS原生权限管理器 getIOSPermissionManager() { const permissionMap = { 'ACCESS_FINE_LOCATION': { class: 'CLLocationManager', checkMethod: 'authorizationStatus', requestMethod: 'requestWhenInUseAuthorization' }, 'WRITE_EXTERNAL_STORAGE': { class: 'PHPhotoLibrary', checkMethod: 'authorizationStatus', requestMethod: 'requestAuthorization' }, 'CAMERA': { class: 'AVCaptureDevice', checkMethod: (manager) => manager.authorizationStatusForMediaType('vide'), requestMethod: 'requestAccessForMediaType:completionHandler:' }, 'RECORD_AUDIO': { class: 'AVAudioSession', checkMethod: 'recordPermission', requestMethod: 'requestRecordPermission:' }, 'CALL_PHONE': { class: 'CNContactStore', checkMethod: (manager) => manager.authorizationStatusForEntityType(0), requestMethod: 'requestAccessForEntityType:completionHandler:' } }; const config = permissionMap[this.permissionID]; if (!config) { console.warn(`未定义的权限型: ${this.permissionID}`); return {}; } try { const manager = plus.ios.importClass(config.class); return { manager: manager, checkMethod: config.checkMethod, requestMethod: config.requestMethod }; } catch (error) { console.error(`导入iOS失败: ${config.class}`, error); return {}; } }, // 检查iOS权限状态 checkIOSPermissionStatus(manager, checkMethod) { return new Promise((resolve) => { try { // 方法型处理 let status; if (typeof checkMethod === 'function') { status = checkMethod(manager); } else if (typeof manager[checkMethod] === 'function') { status = manager[checkMethod](); } else { console.warn('不支持的状态检查方法'); resolve(IOS_PERMISSION_STATUS.NOT_DETERMINED); return; } // 特殊处理麦克风权限 if (this.permissionID === 'RECORD_AUDIO') { // 麦克风权限状态码特殊处理 const AVAudioSessionRecordPermission = { Undetermined: 1970168948, // 'undt' Denied: 1684369017, // 'deny' Granted: 1735552628 // 'grnt' }; if (status === AVAudioSessionRecordPermission.Granted) { resolve(IOS_PERMISSION_STATUS.AUTHORIZED); } else if (status === AVAudioSessionRecordPermission.Denied) { resolve(IOS_PERMISSION_STATUS.DENIED); } else { resolve(IOS_PERMISSION_STATUS.NOT_DETERMINED); } return; } // 通用状态解析 resolve(status); } catch (error) { console.error('权限状态检查失败:', error); resolve(IOS_PERMISSION_STATUS.NOT_DETERMINED); } }); }, // 请求iOS权限(原生方式) requestIOSPermissionNative(manager, requestMethod) { return new Promise((resolve) => { try { // 处理不同的请求方法 switch (this.permissionID) { case 'ACCESS_FINE_LOCATION': // 位置权限 const locationManager = manager.new(); if (locationManager[requestMethod]) { locationManager[requestMethod](); // 设置代理监听状态变化 const delegate = plus.ios.implements('CLLocationManagerDelegate', { 'locationManager:didChangeAuthorizationStatus:': (mgr, status) => { if (status === 3 || status === 4) { resolve(true); } else if (status === 2) { resolve(false); } plus.ios.deleteObject(locationManager); } }); locationManager.delegate = delegate; } else { resolve(false); } break; case 'WRITE_EXTERNAL_STORAGE': // 存储权限 manager[requestMethod](function(status) { resolve(status === 3); }); break; case 'CAMERA': // 相机权限 manager[requestMethod]('vide', function(granted) { resolve(granted); }); break; case 'RECORD_AUDIO': // 麦克风权限 const audioSession = manager.sharedInstance(); audioSession[requestMethod](function(granted) { resolve(granted); }); break; case 'CALL_PHONE': // 电话权限 const contactStore = manager.new(); contactStore[requestMethod](0, function(granted, error) { resolve(!error && granted); }); break; default: resolve(false); } } catch (error) { console.error('权限请求失败:', error); resolve(false); } }); }, // 获取 iOS 对应的 scope getIOSScope() { const mapping = { 'ACCESS_FINE_LOCATION': 'scope.userLocation', 'WRITE_EXTERNAL_STORAGE': 'scope.writePhotosAlbum', 'CAMERA': 'scope.camera', 'RECORD_AUDIO': 'scope.record', 'READ_PHONE_STATE': 'scope.notification', 'CALL_PHONE': 'scope.addressBook' }; return mapping[this.permissionID] || ''; }, // 显示设置引导 showSettingGuide() { this.$util.showModal({ title: '温馨提示', content: '请前往系统设置开启权限,以获得完整功能体验', cancelText: "取消", confirmText: "前往设置", showCancel: true, confirmColor: '#000', cancelColor: '#666', success: (res) => { if (res.confirm) { this.goSetting(); } } }); }, // 跳转系统设置 goSetting() { // Android if (plus.os.name === "Android") { const Intent = plus.android.importClass("android.content.Intent"); const Settings = plus.android.importClass("android.provider.Settings"); const Uri = plus.android.importClass("android.net.Uri"); const mainActivity = plus.android.runtimeMainActivity(); const intent = new Intent(); intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); const uri = Uri.fromParts("package", mainActivity.getPackageName(), null); intent.setData(uri); mainActivity.startActivity(intent); } // iOS else { const UIApplication = plus.ios.import("UIApplication"); const application = UIApplication.sharedApplication(); const NSURL = plus.ios.import("NSURL"); try { // 优先使用官方设置URL const settingsURL = NSURL.URLWithString(UIApplicationOpenSettingsURLString); if (application.canOpenURL(settingsURL)) { const iosVersion = parseFloat(plus.os.version); if (iosVersion >= 10.0) { application.openURLOptionsCompletionHandler(settingsURL, {}, null); } else { application.openURL(settingsURL); } return; } } catch (e) { console.warn("使用官方设置URL失败,尝试备选方案"); } // 备选方案 const settingsURL = NSURL.URLWithString("app-settings:"); application.openURL(settingsURL); } } } } </script> <style lang="scss"> .uni-popup { position: fixed; top: 0; bottom: 0; left: 0; right: 0; z-index: 99999; background-color: rgba(0, 0, 0, 0.5); display: flex; align-items: flex-start; justify-content: center; &__wrapper { position: relative; margin-top: 100rpx; &.ani { transition: all 0.3s ease-out; } &.top { animation: slideDown 0.3s forwards; } &-box { width: 650rpx; background: #fff; border-radius: 20rpx; overflow: hidden; box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.15); .title { padding: 30rpx 30rpx 10rpx; font-size: 34rpx; font-weight: bold; color: #333; text-align: center; } .content { padding: 20rpx 40rpx; font-size: 28rpx; color: #666; line-height: 1.6; text-align: center; } } } } .action-buttons { display: flex; border-top: 1rpx solid #eee; margin-top: 20rpx; .btn { flex: 1; height: 90rpx; line-height: 90rpx; font-size: 32rpx; border-radius: 0; background: none; position: relative; margin: 0; &::after { border: none; } &.cancel { color: #999; border-right: 1rpx solid #eee; } &.confirm { color: #007AFF; font-weight: 500; } } } @keyframes slideDown { from { transform: translateY(-100px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } </style>
最新发布
11-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值