5

Google Play Expansion APK メカニズムを使用して取得する最大 600 MB の大きな拡張ファイルがあります。また、実際に使用するには、このファイルを解凍する必要があります。したがって、アプリ全体とデータには、約 1.4 GB のストレージが必要です。

私が知る限り、Google Play は .obb を「内部」SD にダウンロードすることを主張しており、これを変更する方法はないようです。「外部」SD カードには多くの空き容量がありますが、内部 SD カードの容量は限られています。彼らは、アプリが非常に多くのスペースを占有していると叫んでいます。これについて何かできることはありますか?

現在、.obb ファイルを次のように展開しています。

getExternalStorageDirectory()/Android/データ

ユーザーにどこが欲しいか尋ねて、真の外部 SD カードを選択できると思います。ただし、それでも内部 SD カードに (ほとんど役に立たない) .obb ファイルが残り、Google Play はこれを削除できないと言います。

これを正しく処理する方法について何か提案はありますか?

4

3 に答える 3

2

拡張ファイルの保存場所のドキュメントによると、拡張ファイルは次の場所に保存されます。

<shared-storage>/Android/obb/<package-name>/

whereshared-storageは によって返されるものgetExternalStorageDirectory()で、SD カードを持っているユーザーの場合は SD カードにあるはずです。

残念ながら、同じページに記載されているように:

適切な動作を確保するために、拡張ファイルを削除、移動、または名前変更しないでください。

この段落に特に注意を払います。

拡張ファイルの内容を解凍する必要がある場合は、後で .obb 拡張ファイルを削除したり、解凍したデータを同じディレクトリに保存したりしないでください。アンパックしたファイルは、getExternalFilesDir()で指定されたディレクトリに保存する必要があります。ただし、可能であれば、データを展開するのではなく、ファイルから直接読み取ることができる拡張ファイル形式を使用することをお勧めします。たとえば、ZIP ファイルから直接データを読み取るAPK Expansion Zip Libraryというライブラリ プロジェクトを提供しています。

于 2013-03-09T00:10:20.743 に答える
1

OBB ファイルを別の場所に置くことの問題点は、ユーザーがアプリをアンインストールしたときに OBB ファイルが削除されないことです。ただし、メリットがコストを上回ると思われる場合は、OBB ファイルのダウンロードと検証を実行するためのソース コードが提供されているため、ストレージの場所を変更することを止める技術的な理由は何もありません。ニーズに合わせてその動作を変更するだけです。

たとえば、OBB ファイルが保存されるパスは、次のように提供されcom.google.android.vending.expansion.downloader.Helpersます。

static public String getSaveFilePath(Context c) {
    File root = Environment.getExternalStorageDirectory();
    String path = root.toString() + Constants.EXP_PATH + c.getPackageName();
    return path;
}

getFilesystemRoot(String path)( &も変更する必要がありますisFilenameValid(String filename))

Google の拡張 zipfile lib も使用している場合は、ルート ディレクトリとしてcom.android.vending.expansion.zipfile.APKExpansionSupport指定する3 つのメソッドも変更する必要があります。Environment.getExternalStorageDirectory()

これらの変更により、少なくとも半分は達成できるはずです。

また、外部 SD カードの問題は、速度が大きく異なることに注意してください。通常、内部 SD の速度は少なくとも適切です。おそらく、OBB を 2 つのファイルに分割し (更新ファイル機能が必要ないと仮定して)、そのうちの 1 つを外部 SD に移動できます。

于 2013-03-09T02:43:31.393 に答える
0

私は同じ問題を抱えていましたが、それを解決する方法を見つけました。

OBB を削除すると、dosFileExist (Helpers.java 内) は false を返します。ExpansionFilesDelivered をチェックする ExpDownloaderActivity で、この情報を使用して OBB を再ダウンロードします。

ブール値ではなく、次の意味を持つ整数を返すように、dosFileExist と ExpansionFilesDelivered を変更しました。

fileStatus == 0: OBB がありません (ダウンロードする必要があります)

fileStatus == 1: OBB が利用可能で、別の場所に解凍できます

fileStatus == 2: OBB のデータは既に別の場所に保存されています

ここでのトリック: OBB からお気に入りの場所にデータを解凍した後、元の OBB を、元の OBB のファイルサイズのみを文字列として含む同じ名前のファイルに置き換えます。これにより、sdcard の占有スペースが解放されます。

doesFileExist と ExpansionFilesDelivered をさらに呼び出すと、filestatus = 2 が返されます。これは、アクションが必要ないことを意味します。

Helpers.java での私の変更は次のとおりです。

static public int doesFileExist(Context c, String fileName, long fileSize,
        boolean deleteFileOnMismatch) {
    // the file may have been delivered by Market --- let's make sure
    // it's the size we expect


    File fileForNewFile = new File(Helpers.generateSaveFileName(c, fileName));
    if (fileForNewFile.exists()) {
        if (fileForNewFile.length() == fileSize) {
            return 1;
        } else if (fileForNewFile.length() < 100) {
            // Read the file and look for the file size inside
            String content = "";
            long isSize = 0;
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(fileForNewFile);
                char current;
                while (fis.available() > 0) {
                    current = (char) fis.read();
                    content = content + String.valueOf(current);
                }

            } catch (Exception e) {
                Log.d("ReadOBB", e.toString());
            } finally {
                if (fis != null)
                    try {
                        fis.close();
                    } catch (IOException ignored) {
                }
            }
            try {
                isSize = Long.parseLong(content);
            } catch(NumberFormatException nfe) {
                Log.d("ReadOBBtoInt", nfe.toString());
            } 
            if (isSize == fileSize) {
                return 2;
            }
        }
        if (deleteFileOnMismatch) {
            // delete the file --- we won't be able to resume
            // because we cannot confirm the integrity of the file
            fileForNewFile.delete();
        }
    }
    return 0;
}

OBB のファイル サイズが一致しない場合は、OBB を読み取り、内部に格納されているファイル サイズと比較します (これはファイル サイズであってはなりません)。これが一致する場合、ファイルは既に処理されていることがわかります。

これは私の ExpDownloaderActivity での私の変更です:

int expansionFilesDelivered() {
    int fileStatus = 0;

    for (XAPKFile xf : xAPKS) {
        if (xf.mFileSize > 0) {
            String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion);
            fileStatus = Helpers.doesFileExist(this, fileName, xf.mFileSize, false);
            if (fileStatus==0)
                return 0;
        }
    }
    return fileStatus;
}

ExpDownloaderActivity の onCreate で:

    initializeDownloadUI();

    int fileStatus = expansionFilesDelivered();
    if (fileStatus==0) {        // OBB is missing
            // ... Download the OBB file, same as on Downloader example
    } else if (fileStatus==1) {
        validateXAPKZipFiles(); // and, if OBB has no errors, unpack it to my favorite place
                                // if done, create a new OBB file with the original name
                                // and store a string with the original filesize in it.
    } else {
        finish();               // No action required        }

したがって、OPが述べたように、完全なOBBアンパックされたデータ用のsdcard上のスペースは必要ありません。

于 2013-08-04T07:42:38.897 に答える