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

Flutter中如何在Android/obb目录创建文件夹并复制文件?

Flutter中如何在Android/obb目录创建文件夹并复制文件?

我完全懂你现在的困惑——明明已经拿到了MANAGE_EXTERNAL_STORAGE权限,却还是没法在Android/obb目录下创建文件夹,而第三方应用商店却能轻松搞定APP+OBB的安装,这确实让人摸不着头脑。下面我分两种场景给你拆解解决方案:

场景1:操作自身应用的OBB目录

这是最常规的需求,Android系统本身就给应用提供了合法访问自身OBB目录的API,根本不需要依赖MANAGE_EXTERNAL_STORAGE这种宽泛的权限。你可以通过Flutter的MethodChannel调用Android原生代码来实现:

Flutter端代码

import 'package:flutter/services.dart';

class ObbManager {
  static const MethodChannel _channel = MethodChannel('obb_manager');

  // 创建自身应用的OBB子目录
  static Future<bool> createObbFolder(String folderName) async {
    try {
      return await _channel.invokeMethod('createObbFolder', {'folderName': folderName});
    } on PlatformException catch (e) {
      print('创建目录失败:${e.message}');
      return false;
    }
  }

  // 复制文件到OBB目录
  static Future<bool> copyFileToObb(String sourcePath, String destFileName) async {
    try {
      return await _channel.invokeMethod('copyFileToObb', {
        'sourcePath': sourcePath,
        'destFileName': destFileName,
      });
    } on PlatformException catch (e) {
      print('复制文件失败:${e.message}');
      return false;
    }
  }
}

Android端Kotlin代码

在MainActivity.kt中注册MethodChannel并实现逻辑:

import android.content.Context
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.nio.channels.FileChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "obb_manager"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "createObbFolder" -> {
                    val folderName = call.argument<String>("folderName") ?: ""
                    val success = createObbFolder(folderName)
                    result.success(success)
                }
                "copyFileToObb" -> {
                    val sourcePath = call.argument<String>("sourcePath") ?: ""
                    val destFileName = call.argument<String>("destFileName") ?: ""
                    val success = copyFileToObb(sourcePath, destFileName)
                    result.success(success)
                }
                else -> result.notImplemented()
            }
        }
    }

    // 创建自身应用的OBB子目录
    private fun createObbFolder(folderName: String): Boolean {
        // 获取自身应用的OBB根目录
        val obbDir = getObbDir() ?: return false
        val targetFolder = File(obbDir, folderName)
        return if (!targetFolder.exists()) {
            targetFolder.mkdirs()
        } else {
            true
        }
    }

    // 复制文件到OBB目录
    private fun copyFileToObb(sourcePath: String, destFileName: String): Boolean {
        val sourceFile = File(sourcePath)
        if (!sourceFile.exists()) return false

        val obbDir = getObbDir() ?: return false
        val destFile = File(obbDir, destFileName)

        return try {
            FileInputStream(sourceFile).channel.use { sourceChannel ->
                FileOutputStream(destFile).channel.use { destChannel ->
                    destChannel.transferFrom(sourceChannel, 0, sourceChannel.size())
                }
            }
            true
        } catch (e: Exception) {
            e.printStackTrace()
            false
        }
    }
}

场景2:操作其他应用的OBB目录

这就是你疑惑第三方应用商店能做到的原因——它们拥有系统级的特殊权限(比如INSTALL_PACKAGES、WRITE_MEDIA_STORAGE),或者是通过系统签名认证的,普通开发者的应用根本无法获取这些权限。

对于普通应用来说,有几个折衷的方案:

  • 引导用户手动操作:提示用户打开系统文件管理器,手动将OBB文件复制到目标应用的OBB目录下(路径一般是Android/obb/[目标应用包名]);
  • 使用系统文件选择器:通过Intent调用系统文件选择器,让用户选择要复制的文件,再尝试写入,但这种方式在Android 11+上依然会受到Scoped Storage的限制,不一定能成功写入其他应用的OBB目录;
  • Root设备:如果用户的设备已经Root,你可以通过Root权限执行Shell命令来创建目录和复制文件,但这只适用于小众Root用户群体。

关键注意事项

  • 不要依赖MANAGE_EXTERNAL_STORAGE来操作OBB目录:这个权限主要是用于访问共享存储的其他区域,对系统预留的OBB目录的限制依然存在;
  • 自身应用的OBB目录是沙箱化的:其他应用无法访问你的应用的OBB目录,反之亦然,这是Android的安全机制;
  • 测试时注意OBB目录的实际路径:不同设备的OBB目录可能略有差异,但getObbDir()会自动返回正确的路径,不要硬编码路径。

备注:内容来源于stack exchange,提问作者Mojtaba Mahamed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 07:03:02