Android 使用obb扩展App

    • jobb Tools
    • 在Application中使用
    • 用于Google Play Expansion Files
    • 读取Obb文件中的图片资源
      • 步骤
      • 代码示例
    • 应该注意的问题some questions

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]...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打包就会成功。

你可能感兴趣的:(Android开发系列)