6

从扩展文件中读取 mp3 文件

我有创建和扩展文件的名称

“main.1.com.example.app.obb”

其中包含音频文件名“about_eng.mp3”

现在问题我已经编写了以下代码来读取和播放 mp3 文件

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

static String[] getAPKExpansionFiles(Context ctx, int mainVersion, int patchVersion) {
    String packageName = ctx.getPackageName();
    Vector<String> ret = new Vector<String>();
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        // Build the full path to the app's expansion files
        File root = Environment.getExternalStorageDirectory();
        File expPath = new File(root.toString() + EXP_PATH + packageName);

        // Check that expansion file path exists
        if (expPath.exists()) {
            if ( mainVersion > 0 ) {
                String strMainPath = expPath + File.separator + "main." +
                        mainVersion + "." + packageName + ".obb";
                File main = new File(strMainPath);
                if ( main.isFile() ) {
                        ret.add(strMainPath);
                }
            }
            if ( patchVersion > 0 ) {
                String strPatchPath = expPath + File.separator + "patch." +
                        mainVersion + "." + packageName + ".obb";
                File main = new File(strPatchPath);
                if ( main.isFile() ) {
                        ret.add(strPatchPath);
                }
            }
        }
    }
    String[] retArray = new String[ret.size()];
    ret.toArray(retArray);
    return retArray;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    // Get a ZipResourceFile representing a merger of both the main and patch files

    try {
        ZipResourceFile expansionFile = APKExpansionSupport.getAPKExpansionZipFile(this,1,1);
        if(expansionFile!=null){

            AssetFileDescriptor fd = expansionFile.getAssetFileDescriptor("about_eng.mp3");
                //or
            MediaPlayer mediaPlayer = new MediaPlayer();
            mediaPlayer.setDataSource( fd.getFileDescriptor(), 
                    fd.getStartOffset(),fd.getLength());
            mediaPlayer.prepare();
            mediaPlayer.start();

            }




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

    // Get an input stream for a known file inside the expansion file ZIPs


}

但它总是在这一行抛出异常

 mediaPlayer.setDataSource( fd.getFileDescriptor(), 
                    fd.getStartOffset(),fd.getLength());
            mediaPlayer.prepare();

因为变量 fd 为空。

任何机构都可以帮我解决这个问题

4

3 回答 3

8

我用谷歌搜索,发现我们必须制作 .zip,在http://developer.android.com/google/play/expansion-files.html0% (No compression)中提到

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%压缩zip? 在此处输入图像描述

这里看压缩方法

所以我们应该把这个 zip 上传到 Play 商店。

所以你不需要使用其他 SO 答案中提到的ZipHelper.java

只需简单地使用

ZipResourceFile expansionFile=null;

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

                     AssetFileDescriptor fd = expansionFile.getAssetFileDescriptor("test.mp3");
                     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();
            }
于 2013-09-23T07:30:38.077 回答
1

尝试使用expansionFile.getAssetFileDescriptor("main_expansion/about_eng.mp3").

如果它不起作用,请调用:

ZipResourceFile.ZipEntryRO [] entries = expansionFile.getAllEntries();

并查看文件名:

entries[0].mFileName;.

这可能是路径应该是什么样子的提示。

我知道这个问题很老,但也许它可以帮助某人。

于 2017-02-09T13:14:32.113 回答
0

要阅读 mp3,使用媒体播放器,您可以通过 3 种方式进行

例如。我的应用程序包名称是

com.bluewindsolution.android.sampleapp

那么我的扩展文件应该是

main.1.com.bluewindsolution.android.sampleapp.obb

详细的,你可以关注这里

[main|patch].<扩展版本>.<包名>.obb


从扩展中,您可以通过 3 种方式获得它:

通过 AssetFileDescriptor

// this one work with image file, media file
// Get a ZipResourceFile representing a specific expansion file
// mainContext, version no. of your main expansion, version no of your patch
ZipResourceFile expansionFile = APKExpansionSupport.getAPKExpansionZipFile(this, 1, 0); 
AssetFileDescriptor afd_img1 = expansionFile.getAssetFileDescriptor("your_path/your_file.jpg");
AssetFileDescriptor afd_mpbg = expansionFile.getAssetFileDescriptor("your_path/your_file.mp3");

// to set image
ImageView imageView1 = (ImageView)findViewById(R.id.iv1); 
imageView1.setImageBitmap(BitmapFactory.decodeFileDescriptor(afd_iv1.getFileDescriptor()));

// to set sound
try {
    mpbg.setDataSource(afd_mpbg.getFileDescriptor(), afd_mpbg.getStartOffset(), afd_mpbg.getDeclaredLength());
    mpbg.prepareAsync();
    mpbg.start();
} catch (IllegalStateException e) {
    Log.w("Error=====", "Failed to prepare media player", e);
}

通过输入流

// this one work with image file, media file
// Get a ZipResourceFile representing a specific expansion file

ZipResourceFile expansionFile = new ZipResourceFile(filePathToMyZip);

// Get an input stream for a known file inside the expansion file ZIPs

InputStream fileStream = expansionFile.getInputStream(pathToFileInsideZip);

通过乌里

//this one can use in almost thing such as jpg, mp3, mp4, pdf, etc.

//you need to create new class to override APEZProvider
public class ZipFileContentProvider extends APEZProvider {
    @Override
    public String getAuthority() {
        return "com.bluewindsolution.android.sampleapp";
    }
}

//you need to add <provider> in AndroidManifest.xml
<provider
 android:name="com.bluewindsolution.android.sampleapp.ZipFileContentProvider"
   android:authorities="com.bluewindsolution.android.sampleapp" 
      android:exported="false"
      android:multiprocess="true"
    >
    <meta-data android:name="mainVersion"
              android:value="1"></meta-data>
</provider>

//after that you can use it any time by this code:
String filename2 = "image/i_commu_a_1_1_1_1.jpg"; // suppose you store put your file in directory in .obb
String uriString2 = "content://com.bluewindsolution.android.sampleapp" +  File.separator + filename2;
Uri uri2 = Uri.parse(uriString2);
imageView2.setImageURI(uri2);

// Filename inside my expansion file
String filename = "video/v_do_1_1_1.mp4"; // suppose you store put your file in directory in .obb
String uriString = "content://com.bw.sample_extension_download_main" +  File.separator + filename;
Uri uri = Uri.parse(uriString);

v1 = (VideoView)findViewById(R.id.videoView1);
v1.setVideoURI(uri);
v1.start();
于 2015-06-19T19:02:11.980 回答