从APK扩展文件中读取内容(来自obb文件)

时间:2013-01-24 06:50:22

标签: android apk-expansion-files

我已经实施了APK扩展文件下载服务,并且全部来自http://developer.android.com/google/play/expansion-files.html

我可以下载APK扩展文件,我可以使用下面的代码看到该文件

try {
        ZipResourceFile expansionFile = APKExpansionSupport
                .getAPKExpansionZipFile(this, 3, 0);

        ZipEntryRO[] zip = expansionFile.getAllEntries();
        Log.e("", "" + zip[0].mFile.getAbsolutePath());
        Log.e("", "" + zip[0].mFileName);
        Log.e("", "" + zip[0].mZipFileName);
        Log.e("", "" + zip[0].mCompressedLength);

        AssetFileDescriptor fd = expansionFile
                .getAssetFileDescriptor(zip[0].mFileName);

        if (fd != null && fd.getFileDescriptor() != null) {
            MediaPlayer mp = new MediaPlayer();
            mp.setDataSource(fd.getFileDescriptor());
            mp.start();
        } else {
            Log.e("", "fd or fd.getFileDescriptor() is null");
        }

    } catch (IOException e) {
        e.printStackTrace();
    }

我的obb有文件test.mp4,我的代码Log.e("", "" + zip[0].mFileName);打印test.mp4.

我的fdnull。为什么是null?我正在努力解决但未能解决。

我只是无法读取obb文件中的任何文件..

未答复Accessing to files inside obb expansion file暗示想法,但它对我不起作用。

Steps to create APK expansion file告诉从obb解压缩内容然后阅读它。它可靠而且好吗?

救救我!!需要最佳实践的意见。感谢

编辑:

我的日志

03-01 10:36:40.848: E/(27836): zip[0].isUncompressed() : false
03-01 10:36:40.848: E/(27836): mFile.getAbsolutePath() : /storage/sdcard0/Android/obb/smart.trigger/main.3.smart.trigger.obb
03-01 10:36:40.848: E/(27836): mFileName : test.mp4
03-01 10:36:40.848: E/(27836): mZipFileName : /storage/sdcard0/Android/obb/smart.trigger/main.3.smart.trigger.obb
03-01 10:36:40.848: E/(27836): mCompressedLength : 21657598

4 个答案:

答案 0 :(得分:6)

我用Google搜索,发现我们必须在http://developer.android.com/google/play/expansion-files.html

中提及0% (No compression) .zip。

Tip: If you're packaging media files into a ZIP, you can use media playback calls on the files with offset and length controls (such as MediaPlayer.setDataSource() and SoundPool.load()) without the need to unpack your ZIP. In order for this to work, you must not perform additional compression on the media files when creating the ZIP packages. For example, when using the zip tool, you should use the -n option to specify the file suffixes that should not be compressed: zip -n .mp4;.ogg main_expansion media_files

如何使用winrar制作0%压缩邮件?

enter image description here

这里看压缩方法

mac中的0%压缩zip

Create zip without compression on OS X from Terminal:
zip -r0 zipfilename.zip files-to-zip

所以我们必须在Play商店上传这个zip。

因此您无需使用 ZipHelper.java

只需使用

即可
ZipResourceFile expansionFile=null;

            try {
                expansionFile = APKExpansionSupport.getAPKExpansionZipFile(getApplicationContext(),3,0);

                     AssetFileDescriptor fd = expansionFile.getAssetFileDescriptor("test.mp4");
                     MediaPlayer mPlayer = new MediaPlayer();
                     mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                     mPlayer.setDataSource(fd.getFileDescriptor(),fd.getStartOffset(),fd.getLength());
                     mPlayer.prepare();
                     mPlayer.start();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

答案 1 :(得分:4)

我已解决使用解压缩..

ZipHelper.java

public class ZipHelper {
static boolean zipError = false;

public static boolean isZipError() {
    return zipError;
}

public static void setZipError(boolean zipError) {
    ZipHelper.zipError = zipError;
}

public static void unzip(String archive, File outputDir) {
    try {
        Log.d("control", "ZipHelper.unzip() - File: " + archive);
        ZipFile zipfile = new ZipFile(archive);
        for (Enumeration<? extends ZipEntry> e = zipfile.entries(); e
                .hasMoreElements();) {
            ZipEntry entry = (ZipEntry) e.nextElement();
            unzipEntry(zipfile, entry, outputDir);

        }
    } catch (Exception e) {
        Log.d("control", "ZipHelper.unzip() - Error extracting file "
                + archive + ": " + e);
        setZipError(true);
    }
}

private static void unzipEntry(ZipFile zipfile, ZipEntry entry,
        File outputDir) throws IOException {
    if (entry.isDirectory()) {
        createDirectory(new File(outputDir, entry.getName()));
        return;
    }

    File outputFile = new File(outputDir, entry.getName());
    if (!outputFile.getParentFile().exists()) {
        createDirectory(outputFile.getParentFile());
    }

    Log.d("control", "ZipHelper.unzipEntry() - Extracting: " + entry);
    BufferedInputStream inputStream = new BufferedInputStream(
            zipfile.getInputStream(entry));
    BufferedOutputStream outputStream = new BufferedOutputStream(
            new FileOutputStream(outputFile));

    try {
        IOUtils.copy(inputStream, outputStream);
    } catch (Exception e) {
        Log.d("control", "ZipHelper.unzipEntry() - Error: " + e);
        setZipError(true);
    } finally {
        outputStream.close();
        inputStream.close();
    }
}

private static void createDirectory(File dir) {
    Log.d("control",
            "ZipHelper.createDir() - Creating directory: " + dir.getName());
    if (!dir.exists()) {
        if (!dir.mkdirs())
            throw new RuntimeException("Can't create directory " + dir);
    } else
        Log.d("control",
                "ZipHelper.createDir() - Exists directory: "
                        + dir.getName());
}
}

用法

try {
        ZipResourceFile expansionFile = APKExpansionSupport
                .getAPKExpansionZipFile(this, 3, 0);

        ZipEntryRO[] zip = expansionFile.getAllEntries();
        Log.e("", "zip[0].isUncompressed() : " + zip[0].isUncompressed());
        Log.e("",
                "mFile.getAbsolutePath() : "
                        + zip[0].mFile.getAbsolutePath());
        Log.e("", "mFileName : " + zip[0].mFileName);
        Log.e("", "mZipFileName : " + zip[0].mZipFileName);
        Log.e("", "mCompressedLength : " + zip[0].mCompressedLength);

        File file = new File(Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "");
        ZipHelper.unzip(zip[0].mZipFileName, file);

        if (file.exists()) {
            Log.e("", "unzipped : " + file.getAbsolutePath());
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

答案 2 :(得分:3)

您的文件是否在zip文件中的文件夹中?我问,因为我有同样的问题,我的解决方案是在获取文件描述符时包含文件夹名称。

例如,我的扩展文件包含一个名为“Videos”的文件夹。因此,要获得文件描述符,我必须这样做:

AssetFileDescriptor fd = expansionFile.getAssetFileDescriptor("Videos/" + videoName + ".mp4");

答案 3 :(得分:0)

如果您使用setDataSource(),那么在首先压缩文件时,您不应该压缩文件,就像在文档(http://developer.android.com/google/play/expansion-files.html#ZipLib)中所说的那样:

  

为了使其正常工作,您不得执行其他压缩   在创建ZIP包时在媒体文件上。