Android 使用obb扩展App

jobb Tools

制作成OBB(Opaque Binary Blob)格式文件的一种工具,在Android SDK中, %ANDROID——HOME/tools%中,在tools/bin下有jobb

命令:

jobb -d [目录名称的完整路径] -o [输出目标文件的完整路径] -pn [软件包名] -pv [包版本]

EG:
源文件目录 D:contents 目标文件夹: D:\obb\output.obb 软件包名 com.my.test 包版本 1

jobb -d D:\contents -o D:\obb\output.obb -pn com.my.test -pv 1

  • 注意:
    • jobb -d,-o 需要指定完整路径。如果指定相对路径,%ANDROID_HOME%/tools/将作为相对路径
    • JOBB工具如果不能输出有一定容量的.obb的文件的话,出现错误提示

在Application中使用

OnObbStateChangeListener listener = new OnObbStateChangeListener() {
  @Override
  public void onObbStateChange(String path, int state) {
    // state == 1 (OnObbStateChangeListener.MOUNTED) 安装成功
  }
};
StorageManager storageManager = ((StorageManager) context.getSystemService(Context.STORAGE_SERVICE));
String path = "path/to/obbFile"; // .obb文件的完整路径
storageManager.mountObb(path, null, listener); // 如果在创建obb时,指定了一个键,则指定为第二个参数
  • 注意:
    如果与创建时指定的包名称不同时,onObbStateChange的状态为25(OnObbStateChangeListener.ERROR_PERMISSION_DENIED)

用于Google Play Expansion Files

  • OBB 文件需要使用以下命名规则

[main|patch].<expansion-version>.<package-name>.obb

  • 注意:
    • 上传APK时,OBB会另外上传,不能只更新OBB文件
    • 下载应用程序时,OBB文件下载到%external storage%/Android/obb/package name目录。

读取Obb文件中的图片资源

1.步骤

  1. 获取obb文件路径
  2. 挂载Obb文件
  3. 获取挂载后的路径
  4. 读取obb中的文件.

2.代码示例

public class MainActivity extends AppCompatActivity {

    private TextView tv;
    private ImageView iv;
    private StorageManager mStorageManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.tv);
        iv = (ImageView) findViewById(R.id.iv);
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                doAnimation();
            }
        });
    }

    private void doAnimation() {
        //获取main文件的路径
        String apkObbMainFile = getAPKObbMainFile(MainActivity.this, 1);
        if (apkObbMainFile == null)
            return;
        //初始化StorageManager
        mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
        //挂载OBB文件
        mStorageManager.mountObb(apkObbMainFile, null, new OnObbStateChangeListener() {
            @Override
            public void onObbStateChange(String path, int state) {
                super.onObbStateChange(path, state);
                Log.e("onObbMounted", path + ":" + state);
                if (state == 1) {
                    //获取挂载后路径
                    String mountedObbPath = mStorageManager.getMountedObbPath(path);
                    Log.e("mountedObbPath", mountedObbPath == null ? "null" : mountedObbPath);
                    //读取动画图片
                    AnimationDrawable animationDrawable = new AnimationDrawable();
                    for (int i = 0; i < 45; i++) {
                        if (i < 10) {
                            Drawable drawable = Drawable.createFromPath(mountedObbPath + "/anims/oshirase_1_houzyo_000" + i + ".png");
                            animationDrawable.addFrame(drawable, 100);
                        } else {
                            Drawable drawable = Drawable.createFromPath(mountedObbPath + "/anims/oshirase_1_houzyo_00" + i + ".png");
                            animationDrawable.addFrame(drawable, 100);
                        }
                    }
                    iv.setImageDrawable(animationDrawable);
                    animationDrawable.start();
                }
            }
        });
    }

    private static final String EXP_PATH = "/Android/obb/";

    private String getAPKObbMainFile(Context ctx, int mainVersion) {
        String packageName = ctx.getPackageName();
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File root = Environment.getExternalStorageDirectory();
            File expPath = new File(root.toString() + EXP_PATH + packageName);

            if (expPath.exists() && mainVersion > 0) {
                String strMainPath = expPath + File.separator + "main." + mainVersion + "." +packageName + ".obb";
                File main = new File(strMainPath);
                if (main.isFile()) {
                    Log.e("MainFile", strMainPath);
                    return strMainPath;
                }
            }
        }
        return null;
    }
}

应该注意的问题(some questions)

  1. 文件有一个最大(512),最小限制4M
  2. 需要将要存储的文件放置到一个文件夹中,例如:

    \data\
        1.png
        ...
        n.png

    在此情况下打包源目录设置为data时,会发生错误

    de.waldheinz.fs.fat.DirectoryFullException: directory is full
    
    Exception in thread "main" java.lang.RuntimeException: Error adding file with name

    更改目录结构为如下:

    \data\anim\
        1.png
        ...
        n.png

    在此时将源目录再次设置为data打包就会成功。

### Oyolov11 OBB 文件格式及用途 OBB 文件是一种特定于 Android 平台的大容量附加资源文件,通常用于存储大型应用程序或游戏所需的数据包。对于 oyolov11 而言,其 OBB 文件主要用于提供额外的模型权重和其他必要的运行时数据。 #### OBB 文件结构与路径 当涉及到像 oyolov11 这样的应用时,OBB 文件会被放置在一个指定的目录下以便程序能够访问这些扩展资源。具体来说,如果下载的是 OBB 文件,则需依据提示文件路径自行在 `Android/obb` 或者其他相应文件夹内创建对应的子目录来保存该文件[^1]。 #### 使用场景说明 - **初始化设置**:首次启动 oyolov11 应用前,确保已正确安装并配置好相应的 OBB 数据包。 - **离线支持**:通过预先打包好的 OBB 文件实现更快速的应用响应以及减少网络流量消耗。 - **高效管理大尺寸资产**:避免将过大的 APK 安装包上传至 Google Play Store,转而利用 OBB 来分发体积较大的媒体资源或其他依赖项。 #### 技术细节补充 为了使 oyolov11 正常运作,所使用OBB 文件应当保持未压缩状态,并且内部路径要匹配实际需求;否则就需要先将其解压到持久化存储区域再供应用读取[^4]。此外,考虑到性能因素,不建议尝试实时解压操作因为这可能会带来较高的 CPU 开销。 ```python import os def check_obb_path(app_package_name, obb_filename): base_dir = f"/sdcard/Android/obb/{app_package_name}/" full_path = os.path.join(base_dir, obb_filename) if not os.path.exists(full_path): print(f"{full_path} does not exist.") return False print(f"Found {full_path}. Ready to use with oyolov11.") return True ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值