scanPermission.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import { permission } from '@/js_sdk/wa-permission/permission.js'
  2. function isAppPlus() {
  3. return typeof plus !== 'undefined' && !!plus?.os?.name
  4. }
  5. export function isIosApp() {
  6. if (!isAppPlus()) return false
  7. const name = String(plus.os.name || '')
  8. return name === 'iOS' || name.includes('iPhone')
  9. }
  10. function normalizeIosStatus(status) {
  11. if (status === null || status === undefined) return -1
  12. const num = Number(status)
  13. return Number.isNaN(num) ? -1 : num
  14. }
  15. function getUniAuthorizeSetting() {
  16. try {
  17. if (typeof uni.getAppAuthorizeSetting === 'function') {
  18. return uni.getAppAuthorizeSetting()
  19. }
  20. } catch (e) {
  21. console.error('getUniAuthorizeSetting error', e)
  22. }
  23. return null
  24. }
  25. function getUniCameraAuth() {
  26. const setting = getUniAuthorizeSetting()
  27. return setting?.cameraAuthorized || null
  28. }
  29. function getUniAlbumAuth() {
  30. const setting = getUniAuthorizeSetting()
  31. return setting?.albumAuthorized || null
  32. }
  33. function getIosAuthStatus(type) {
  34. if (!isIosApp()) return -1
  35. try {
  36. if (type === 'camera') {
  37. const AVCaptureDevice = plus.ios.importClass('AVCaptureDevice')
  38. const status = AVCaptureDevice.authorizationStatusForMediaType('video')
  39. return normalizeIosStatus(status)
  40. }
  41. if (type === 'album') {
  42. const PHPhotoLibrary = plus.ios.importClass('PHPhotoLibrary')
  43. const status = PHPhotoLibrary.authorizationStatus()
  44. return normalizeIosStatus(status)
  45. }
  46. } catch (e) {
  47. console.error('getIosAuthStatus error', e)
  48. }
  49. return -1
  50. }
  51. function isIosCameraGranted() {
  52. const uniAuth = getUniCameraAuth()
  53. if (uniAuth === 'authorized') return true
  54. if (uniAuth === 'denied' || uniAuth === 'config error') return false
  55. const status = getIosAuthStatus('camera')
  56. if (status === 3) return true
  57. try {
  58. return permission.judgeIosPermission('camera') === true
  59. } catch {
  60. return false
  61. }
  62. }
  63. function isIosAlbumGranted() {
  64. const uniAuth = getUniAlbumAuth()
  65. if (uniAuth === 'authorized' || uniAuth === 'limited') return true
  66. if (uniAuth === 'denied' || uniAuth === 'config error') return false
  67. const status = getIosAuthStatus('album')
  68. return status === 3 || status === 4
  69. }
  70. function isIosCameraDenied() {
  71. const uniAuth = getUniCameraAuth()
  72. if (uniAuth === 'denied' || uniAuth === 'config error') return true
  73. const status = getIosAuthStatus('camera')
  74. return status === 1 || status === 2
  75. }
  76. function isIosAlbumDenied() {
  77. const uniAuth = getUniAlbumAuth()
  78. if (uniAuth === 'denied' || uniAuth === 'config error') return true
  79. const status = getIosAuthStatus('album')
  80. return status === 1 || status === 2
  81. }
  82. function requestIosCameraPermission() {
  83. return new Promise((resolve) => {
  84. let settled = false
  85. const done = (granted) => {
  86. if (settled) return
  87. settled = true
  88. resolve(!!granted)
  89. }
  90. setTimeout(() => done(false), 15000)
  91. try {
  92. const AVCaptureDevice = plus.ios.importClass('AVCaptureDevice')
  93. AVCaptureDevice.requestAccessForMediaTypecompletionHandler('video', (granted) => {
  94. done(granted)
  95. })
  96. } catch (e) {
  97. console.error('requestIosCameraPermission error', e)
  98. done(false)
  99. }
  100. })
  101. }
  102. function requestIosAlbumPermission() {
  103. return new Promise((resolve) => {
  104. let settled = false
  105. const done = (status) => {
  106. if (settled) return
  107. settled = true
  108. resolve(normalizeIosStatus(status))
  109. }
  110. setTimeout(() => done(-1), 15000)
  111. try {
  112. const PHPhotoLibrary = plus.ios.importClass('PHPhotoLibrary')
  113. PHPhotoLibrary.requestAuthorization((status) => {
  114. done(status)
  115. })
  116. } catch (e) {
  117. console.error('requestIosAlbumPermission error', e)
  118. done(-1)
  119. }
  120. })
  121. }
  122. async function ensureIosCameraPermission() {
  123. if (isIosCameraGranted()) {
  124. return 'granted'
  125. }
  126. if (isIosCameraDenied()) {
  127. return 'denied'
  128. }
  129. const granted = await requestIosCameraPermission()
  130. if (granted || isIosCameraGranted()) {
  131. return 'granted'
  132. }
  133. return 'denied'
  134. }
  135. async function ensureIosAlbumPermission() {
  136. if (isIosAlbumGranted()) {
  137. return 'granted'
  138. }
  139. if (isIosAlbumDenied()) {
  140. return 'denied'
  141. }
  142. const status = await requestIosAlbumPermission()
  143. if (status === 3 || status === 4 || isIosAlbumGranted()) {
  144. return 'granted'
  145. }
  146. return 'denied'
  147. }
  148. function getAndroidAlbumPermission() {
  149. const Build = plus.android.importClass('android.os.Build')
  150. return Build.VERSION.SDK_INT >= 33
  151. ? 'android.permission.READ_MEDIA_IMAGES'
  152. : 'android.permission.READ_EXTERNAL_STORAGE'
  153. }
  154. async function ensureAndroidPermission(permissionID) {
  155. const granted = await permission.checkAndroidPermission(permissionID)
  156. if (granted === 1) return 'granted'
  157. const result = await permission.requestAndroidPermission(permissionID)
  158. if (result === 1) return 'granted'
  159. if (result === -1) return 'denied_always'
  160. return 'denied'
  161. }
  162. export async function ensureScanCameraPermission() {
  163. if (!isAppPlus()) return 'granted'
  164. if (isIosApp()) return ensureIosCameraPermission()
  165. return ensureAndroidPermission('android.permission.CAMERA')
  166. }
  167. export async function ensureScanAlbumPermission() {
  168. if (!isAppPlus()) return 'granted'
  169. if (isIosApp()) return ensureIosAlbumPermission()
  170. return ensureAndroidPermission(getAndroidAlbumPermission())
  171. }
  172. export function isIosPermissionDenied(type) {
  173. if (!isIosApp()) return false
  174. return type === 'camera' ? isIosCameraDenied() : isIosAlbumDenied()
  175. }
  176. export function isPermissionError(error) {
  177. const msg = String(error?.errMsg || error?.message || error).toLowerCase()
  178. return (
  179. error?._permissionDenied === true
  180. || msg.includes('permission')
  181. || msg.includes('authorize')
  182. || msg.includes('auth deny')
  183. || msg.includes('auth')
  184. || msg.includes('权限')
  185. || msg.includes('no permission')
  186. || msg.includes('denied')
  187. || msg.includes('拒绝')
  188. || msg.includes('未授权')
  189. )
  190. }
  191. export function shouldGuideToSettings(state) {
  192. if (state === 'denied_always') return true
  193. if (state === 'denied' && isIosApp()) return true
  194. return false
  195. }
  196. export function openAppPermissionSetting() {
  197. if (!isAppPlus()) return
  198. if (typeof uni.openAppAuthorizeSetting === 'function') {
  199. uni.openAppAuthorizeSetting({})
  200. return
  201. }
  202. permission.gotoAppPermissionSetting()
  203. }