我正在加载 mp3 文件以在基于 AndEngine 的 Android 游戏中播放。当我将游戏打包为 APK 时,assets 文件夹中的 mp3 音频会抛出错误“无法作为文件描述符打开;它可能已被压缩。”
但是,当我使用 Eclipse (MOTODEV Studio 3.0.2) 中的运行 > 按钮运行游戏时,应用程序被打包、部署到设备并且游戏有声音。在设备上完美运行。
如果我使用“导出 Android 应用程序”打包应用程序,这会创建一个准备好在 Android Market 中部署的签名 APK,然后将该 APK 安装到设备上,游戏运行良好,但声音不播放并引发以下错误:
> 02-02 20:42:31.433: E/AndEngine(1925): AndEngine 02-02 20:42:31.433:
> E/AndEngine(1925): java.io.FileNotFoundException: This file can not be
> opened as a file descriptor; it is probably compressed 02-02
> 20:42:31.433: E/AndEngine(1925): at
> android.content.res.AssetManager.openAssetFd(Native Method) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> android.content.res.AssetManager.openFd(AssetManager.java:330) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> org.anddev.andengine.audio.music.MusicFactory.createMusicFromAsset(MusicFactory.java:75)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> com.snoffleware.android.roshambomb.PlayLevelActivity.onLoadResources(PlayLevelActivity.java:255)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> org.anddev.andengine.ui.activity.BaseGameActivity.doResume(BaseGameActivity.java:168)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> org.anddev.andengine.ui.activity.BaseGameActivity.onWindowFocusChanged(BaseGameActivity.java:85)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> com.android.internal.policy.impl.PhoneWindow$DecorView.onWindowFocusChanged(PhoneWindow.java:2012)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> android.view.View.dispatchWindowFocusChanged(View.java:3924) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:659)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> android.view.ViewRoot.handleMessage(ViewRoot.java:1968) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> android.os.Handler.dispatchMessage(Handler.java:99) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> android.os.Looper.loop(Looper.java:130) 02-02 20:42:31.433:
> E/AndEngine(1925): at
> android.app.ActivityThread.main(ActivityThread.java:3683) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> java.lang.reflect.Method.invokeNative(Native Method) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> java.lang.reflect.Method.invoke(Method.java:507) 02-02 20:42:31.433:
> E/AndEngine(1925): at
> com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:850)
> 02-02 20:42:31.433: E/AndEngine(1925): at
> com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608) 02-02
> 20:42:31.433: E/AndEngine(1925): at
> dalvik.system.NativeStart.main(Native Method)
我尝试将 APK 部署到 Kindle Fire、Motorolo Droid 和 Motorolo Droid 2 Global。该游戏可在所有这些设备上运行,但没有声音。
音频以 mp3 文件的形式存储在 Assets 下名为 Sound 的文件夹中。一个示例文件名是“music-a-nebulas-promise.mp3”。我曾尝试重命名其中一个文件“simple.mp3”,担心命名中不允许使用破折号,但这没有任何区别。
加载音频的代码如下,请注意,当我使用 MOTODEV Studio 运行应用程序时,声音可以完美播放。只有当我尝试将应用程序导出为 APK 并安装它时,我才会收到上述关于压缩的错误:
SoundFactory.setAssetBasePath("sound/");
MusicFactory.setAssetBasePath("sound/");
try {
if (!level.getMusic().equals("")) {
backgroundMusic = MusicFactory.createMusicFromAsset(this.mEngine.getMusicManager(), this, level.getMusic());
backgroundMusic.setLooping(true);
} else {
// music is turned on but there is no music file -- protect
// against crash
isMusic = false;
}
} catch (final IOException e) {
Debug.e(e);
// music is turned on but the music file was not found -- protect
// against crash
isMusic = false;
}
try {
collisionSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "sfx-collision.mp3");
portalSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "sfx-portal-activated.mp3");
winningSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "sfx-winning.mp3");
losingSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "sfx-losing.mp3");
} catch (final IOException e) {
Debug.e(e);
isSound = false;
}
初始化音频的 AndEngine 方法:
public static Music createMusicFromAsset(final MusicManager pMusicManager, final Context pContext, final String pAssetPath) throws IOException {
final MediaPlayer mediaPlayer = new MediaPlayer();
final AssetFileDescriptor assetFileDescritor = pContext.getAssets().openFd(MusicFactory.sAssetBasePath + pAssetPath);
mediaPlayer.setDataSource(assetFileDescritor.getFileDescriptor(), assetFileDescritor.getStartOffset(), assetFileDescritor.getLength());
mediaPlayer.prepare();
final Music music = new Music(pMusicManager, mediaPlayer);
pMusicManager.add(music);
return music;
}
我尝试将 mp3 文件转换为 ogg 和 wav。ogg 和 wav 都抛出与 mp3 文件相同的错误。
由于游戏声音在我使用 Eclipse 运行或调试时有效,这似乎将最终导出步骤作为罪魁祸首。我已经看到建议控制构建过程以防止压缩 Assets 文件夹中的文件的帖子,但我不确定如何从 MOTODEV Studio 中实现这一点。
我还看到了建议将 mp3 音频存储在 res/raw 文件夹中的帖子,但是由于从 Eclipse 运行时会播放 Assets 文件夹中的音频,因此它似乎在打包为 APK 时也应该可以工作。
版本详情
我目前使用 Android SDK Tools v.15 和 Android SDK Platform-tools v.9 的目标是 Android SDK 级别 13(Android 3.2)——所以我认为它可能与 SDK 工具有关,我将 SDK 更新为 v。 16 和 v.10 的平台工具,但这并没有解决问题。