首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Ionic/Cordova Android 權限崩潰:華為設備動態權限申請缺失導致相冊讀取失敗

     編輯:程式設計疑難解答

現象

  • $cordovaImagePicker 選擇系統相冊,安裝時已聲明權限。
  • 大多數手機正常,華為 6 Plus 崩潰:無讀寫權限。
  • 手動授權後恢復正常。

根因:Android 6.0+ (API 23) 動態權限機制

  • AndroidManifest.xml 聲明僅是安裝時聲明。
  • 危險權限(存儲、相機、定位等)運行時必須彈窗請求用戶授權。
  • 華為 EMUI 對權限管控更嚴格,未動態申請直接調用 API 直接拋 SecurityException 崩潰。

修復方案:運行時請求權限

1. Manifest 確保聲明(基礎)

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

2. Ionic/Cordova 端動態申請(核心)

// TypeScript / JavaScript
import { AndroidPermissions } from '@ionic-native/android-permissions/ngx';

constructor(private androidPermissions: AndroidPermissions) {}

async pickImage() {
    const permission = this.androidPermissions.PERMISSION.READ_EXTERNAL_STORAGE;
    const result = await this.androidPermissions.checkPermission(permission);
    
    if (!result.hasPermission) {
        const requestResult = await this.androidPermissions.requestPermission(permission);
        if (!requestResult.hasPermission) {
            alert('需要存儲權限才能選擇圖片');
            return;
        }
    }
    // 權限已授予,調用 ImagePicker
    this.imagePicker.getPictures(options).then(...);
}

3. 原生 Android 代碼參考(插件開發/調試)

// Activity/Fragment 中
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
        REQUEST_CODE_READ_STORAGE);
} else {
    launchImagePicker();
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_CODE_READ_STORAGE && grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        launchImagePicker();
    } else {
        Toast.makeText(this, "權限被拒絕", Toast.LENGTH_SHORT).show();
    }
}

華為設備特殊處理提示

  • EMUI 可能彈出「僅允許一次」選項,需引導用戶選擇「允許」。
  • 部分機型需在「設置 → 應用 → 權限」中手動開啟「存儲」。
  • 測試時務必覆蓋華為/小米/OPPO/vivo 等國產 ROM,行為差異極大。

最佳實踐清單

  1. 所有危險權限使用前檢查 + 請求,不要假設已授權。
  2. 封裝 PermissionUtil.request(permission, rationale, callback) 統一入口。
  3. Cordova 插件選擇 cordova-plugin-android-permissions 官方維護版。
  4. 發布前跑兼容性測試矩陣:API 23-33、主流國產 ROM、無 SD 卡設備。

「Manifest 聲明 ≠ 運行時擁有」 —— 動態權限是 Android 6+ 的鐵律,華為等廠商更是嚴格執行者,補上運行時請求,崩潰即刻消失。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved