1 はじめに
Android APP Bundle (aab) が登場する前は、Google Play にリストされているプロジェクトは APK にパッケージ化されてアップロードされていました。ただし、Google では APK サイズに制限があります。当初は 50M でしたが、後に 100M に拡張されました。ただし、一部の APK にはさらに多くのリソースが含まれていますこの状況を踏まえ、Google では追加の拡張子ファイルのアップロードを許可しています。このファイルは、今日詳しく説明する .obb ファイルです。Google Play Console を使用して APK をアップロードするときは常に、1 つまたは 2 つの拡張ファイルを APK に追加するオプションがあります。各ファイルのサイズは 2 GB に制限されており、任意の形式を選択できます。ただし、ダウンロード時に帯域幅を節約するために、圧縮ファイルを使用することをお勧めします。概念的には、各拡張ファイルは異なる役割を果たします。
- メイン拡張ファイルは、アプリケーションに必要な追加リソースが配置されるメイン拡張ファイルです。
- パッチ拡張ファイルはオプションであり、メイン拡張ファイルに小さな更新を提供するために使用されます。
これら 2 つの拡張ファイルは必要に応じて使用できますが、次のように使用することをお勧めします: メイン拡張ファイルは主要なリソースを提供するため、更新はできるだけ少なくする必要があります。パッチ拡張ファイルはサイズを小さくし、次のように使用する必要があります。 「パッチキャリア」メジャーリリースごと、または必要に応じて更新します。
ただし、アプリの更新に新しいパッチ拡張ファイルのみが必要な場合でも、新しい APK をアップロードし、マニフェスト内の versionCodeを更新する必要があります。(Play Console では、拡張ファイルを既存の APK にアップロードすることはできません。)
2..obbを生成する
通常、アップグレード用の APP または APK 内のいくつかの大きなリソースを zip にパッケージ化します (名前は MYOBB.zip など)。次に、パッケージ化された ZIP の名前を main.versionCode.Package name.obb に変更します。 : main.22070479.cool.obb.android.obb
3. Obb ファイルを APK とともに Google Play Console にアップロードします。
Google コンソール バックエンドを開き、対応するプロジェクトを見つけます: https://play.google.com/console/u/0/developers
APKをアップロードする
APK をアップロードした後、「その他」をクリックして拡張ファイル (.obb) のアップロードを選択します。
このようにして、APK ファイルと obb ファイルが一緒に Google Play にアップロードされます。内部テスト ユーザーはダウンロードしてインストールできます。テストが OK になったら、正式なオンライン環境にリリースできます。ユーザーが APK をダウンロードすると、obb ファイルが私たちがアップロードしたものは同時にあなたの携帯電話にもダウンロードされます
4. APK をダウンロードするときに、対応する obb ファイルをダウンロードします。
APK をダウンロードすると、以前にアップロードした obb ファイルも同時にダウンロードされ、Google Play が拡張ファイルをデバイスにダウンロードすると、システムの共有ストレージの場所に保存されます。アプリケーションを適切に動作させるために、拡張ファイルを削除、移動、または名前変更しないでください。アプリ自体を Google Play からダウンロードする必要がある場合は、ファイルを同じ場所に保存する必要があります。
ダウンロードが保存される場所:
ルート ディレクトリ: getExternalStorageDirectory() + /Android/obb/ <パッケージ名>/XXX.obb
例えば:
String obb_filename = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/obb/" + getPackageName() + "/main.22070479.cool.obb.android.obb";
このとき、アプリを開いた後、obbファイルを解凍して使用し始めます。
5. OBB 内のファイルを解凍して使用します。
まず、APP には、obb ファイルを操作するための読み取りおよび書き込み権限が必要です。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
読み取りおよび書き込み権限を取得したら、obb の解凍を開始します。
public void unZipObb(String srcFilePath, String dstFolderPath) {
Log.d("MainActivity", "unZipObb : srcFilePath=" + srcFilePath + ", dstFolderPath=" + dstFolderPath);
try {
String obbFilePath = srcFilePath;
if (obbFilePath == null) {
Log.d("MainActivity", "unZipObb error : obbFilePath == null");
return;
} else {
File obbFile = new File(obbFilePath);
if (!obbFile.exists()) {
//下载obb文件
Log.d("MainActivity", "unZipObb error : !obbFile.exists()");
} else {
File outputFolder = new File(dstFolderPath);
if (!outputFolder.exists()) {
//目录未创建 没有解压过
outputFolder.mkdirs();
unZip(obbFile, outputFolder.getAbsolutePath());
} else {
//目录已创建 判断是否解压过
if (outputFolder.listFiles() == null) {
//解压过的文件被删除
unZip(obbFile, outputFolder.getAbsolutePath());
} else {
//此处可添加文件对比逻辑
Log.d("MainActivity", "unZipObb error : outputFolder.listFiles() != null");
}
}
}
}
} catch (Exception e) {
Log.d("MainActivity", "unZipObb error : Exception");
e.printStackTrace();
}
}
public void createDirectoryIfNeeded(String folderPath) {
File folder = new File(folderPath);
if (!folder.exists() || !folder.isDirectory()) {
folder.mkdirs();
}
}
public void unZip(File zipFile, String outPathString) {
Log.d("MainActivity", "unZip " + zipFile.getName() + " to " + outPathString);
try {
createDirectoryIfNeeded(outPathString);
ZipInputStream inZip = new ZipInputStream(new FileInputStream(zipFile));
ZipEntry zipEntry;
String szName;
while ((zipEntry = inZip.getNextEntry()) != null) {
szName = zipEntry.getName();
if (zipEntry.isDirectory()) {
szName = szName.substring(0, szName.length() - 1);
File folder = new File(outPathString + File.separator + szName);
folder.mkdirs();
} else {
File file = new File(outPathString + File.separator + szName);
createDirectoryIfNeeded(file.getParent());
file.createNewFile();
FileOutputStream out = new FileOutputStream(file);
int len;
byte[] buffer = new byte[1024];
while ((len = inZip.read(buffer)) != -1) {
out.write(buffer, 0, len);
out.flush();
}
out.close();
}
}
inZip.close();
} catch (Exception e) {
e.printStackTrace();
}
}
6. OBB にファイルを取得したら、解凍されたファイルを使用できます。
String srcPNG1 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhOOB/MYOBB/11.png";
String srcPNG2 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhOOB/MYOBB/12.png";
String srcPNG3 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhOOB/MYOBB/13.png";
String srcPNG4 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhOOB/MYOBB/14.png";
mChangeBTN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = mCount % 4;
switch (position) {
case 0:
Glide.with(MainActivity.this).load(srcPNG1).into(mShowImageView);
break;
case 1:
Glide.with(MainActivity.this).load(srcPNG2).into(mShowImageView);
break;
case 2:
Glide.with(MainActivity.this).load(srcPNG3).into(mShowImageView);
break;
case 3:
Glide.with(MainActivity.this).load(srcPNG4).into(mShowImageView);
break;
}
mCount++;
}
});
概要: OBB の生成 -----> Google Play へのアップロード ----> ユーザーによる OBB のダウンロードと同期 -----> OBB の解凍 -----> まで、OBB のライフサイクル全体が詳細に紹介されています。 OBB ドキュメントを使用する
参考ドキュメント: https://developer.android.com/google/play/expansion-files#Overview
OBB デモ GitHub : https://github.com/JasonZhangHG/OBBDemo.git