You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

华为P20 Android设备OBB挂载失败,调用getFile方法触发重启求助

华为P20 OBB挂载失败(状态码21)及重启问题的解决方案

我之前处理华为设备OBB挂载问题时,刚好遇到过P20机型的类似状况,结合你的代码和问题描述,整理了几个关键的排查方向和修复建议:

1. 先明确状态码21的含义

状态码21对应OBB_ERROR_PERMISSION_DENIED(权限被拒绝),但华为P20的权限限制比常规机型更严格,不一定只是基础存储权限问题,还要检查你的调用参数是否符合系统要求。

2. 修复OBB路径的错误处理

你的代码里有一段多余的路径处理逻辑:

if (strMainPath != null && strMainPath.startsWith("/")) {
    strMainPath = strMainPath.substring(1);
}

这会把正确的绝对路径(比如/storage/emulated/0/Android/obb/com.your.package/main.44.com.your.package.obb)改成相对路径,导致系统找不到OBB文件,进而触发权限错误。直接删除这段代码即可,Environment.getExternalStorageDirectory()返回的是标准外部存储根路径,拼接后的绝对路径完全符合系统要求。

3. 修正OBB挂载的密码参数

在mount()方法中,你传入了"AppName"作为密码:

storageManager.mountObb(strMainPath, "AppName", mListener);

如果你的OBB文件没有加密,这里必须传null而不是任意字符串!华为设备对OBB加密验证的逻辑更严格,错误的密码参数会直接导致挂载失败,甚至触发系统服务异常引发重启。修改后代码:

storageManager.mountObb(strMainPath, null, mListener);

4. 完善权限适配逻辑

华为P20的隐私权限体系有特殊处理,除了常规的READ_EXTERNAL_STORAGE动态权限:

  • 如果你的App目标SDK≥30(Android 11+),还需要申请MANAGE_EXTERNAL_STORAGE权限(即“访问所有文件”权限),否则无法正常访问OBB目录。
  • 在调用mount()之前,一定要先检查权限是否已获取,避免无权限情况下调用系统服务导致异常。示例代码:
public void mount() {
    // 检查基础存储权限
    if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        Log.w(TAG, "缺少存储权限,无法挂载OBB");
        // 这里需要在Activity中处理权限请求,建议通过回调或通知触发
        return;
    }
    // Android 11+ 额外检查全文件访问权限
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
        Log.w(TAG, "需要获取访问所有文件权限");
        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
        intent.setData(Uri.parse("package:" + ctx.getPackageName()));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        ctx.startActivity(intent);
        return;
    }

    final StorageManager storageManager = (StorageManager) ctx.getSystemService(Context.STORAGE_SERVICE);
    String packageName = ctx.getPackageName();
    File root = Environment.getExternalStorageDirectory();
    File expPath = new File(root.toString() + EXP_PATH + packageName);
    String strMainPath = expPath + File.separator + "main." + version + "." + packageName + ".obb";
    
    // 先检查是否已挂载,避免重复请求
    if (storageManager.isObbMounted(strMainPath)) {
        Log.i(TAG, "OBB已挂载,无需重复操作");
        return;
    }
    
    storageManager.mountObb(strMainPath, null, mListener);
}

5. 避免触发系统重启的循环操作

你的getFile()方法在OBB未挂载时会调用mount(),但如果挂载失败(比如权限问题),后续的调用会重复触发挂载请求,频繁调用系统服务可能导致华为P20的ROM触发崩溃重启。建议在ObbStateChangeListener中处理失败状态,避免重复请求:

private OnObbStateChangeListener mListener = new OnObbStateChangeListener() {
    @Override
    public void onObbStateChange(String path, int state) {
        super.onObbStateChange(path, state);
        if (state == MOUNTED) {
            Intent intent = new Intent();
            intent.setAction(ACTION_MOUNT);
            LocalBroadcastManager.getInstance(ctx).sendBroadcast(intent);
        } else {
            Log.e(TAG, "OBB挂载失败,状态码:" + state);
            // 根据状态码给出用户提示,比如状态21提示权限问题
            if (state == OBB_ERROR_PERMISSION_DENIED) {
                // 触发权限申请逻辑
            }
        }
    }
};

总结

华为P20的定制ROM在OBB挂载的参数校验和权限控制上比其他机型更严格,优先修复路径处理和密码参数这两个明显的代码问题,再完善权限检查逻辑,应该就能解决挂载失败和设备重启的问题。

内容的提问来源于stack exchange,提问作者SamSB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:18:24