从SD卡播放mp3声音

8
我在平板电脑的SD卡上有一个名为“/Android/data/com.example.android.app/files”的目录。我手动创建了它,因为我不知道如何测试我应用程序的这个方面。我在SQLite数据库中存储了文件名,如“/folder1/audio1.mp3”,“/folder2/audio1.mp3”等。这些文件具有相同的名称,但位于不同的文件夹中,因为它们是不同语言的相同内容。我将这些文件夹(folder1和folder2)以及所有mp3文件放在SD卡上的“/Android/data/com.example.android.app/files”目录中。
因此,我从数据库获取文件名,并尝试使用以下方式访问SD卡上的文件夹:
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/com.example.android.app/files";

这将最终使得路径为“storage/Android/data/com.example.android.app/files”。

现在,在早期开发阶段,我的raw文件夹中确实有一些mp3文件,但最终将有太多文件无法保存在该文件夹中,因此我开始研究如何从SD卡获取它们。当它们在raw文件夹中时,我是这样获取它们的:

rid = getResources().getIdentifier(filname,  "raw", "com.example.android.app");

现在,随着文件存储在SD卡上,情况发生了变化:
filename = "/folder1/audio.mp3"

我手头的不是“raw”,而是:

"storage/Android/data/com.example.android.app/files"

并且基本上像这样玩它们:
AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(rid);
mMP.reset();
mMP.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
mMP.prepare();
mMP.start();
afd.close();

然而,这种方法现在似乎都不起作用了。
您能从SD卡上的mp3文件中获取resourceid吗?现在这样做是否合适?我应该以不同的方式播放它们,以便无论源是内部还是外部存储器都可以工作吗?
非常困惑。
编辑: 我找到了这个可能会有所帮助...但它可能只是方程式的一半。
编辑2: 我在这里看。它使用mediastore,我认为那不是我想要的。
2个回答

12

你无法获取SD卡中mp3的资源ID,因为该mp3不属于项目的资源文件夹,因此没有资源ID。

来自Android开发者指南:

在编译应用程序时,aapt会生成R类,其中包含您的res/目录中所有资源的资源ID。

为了能够从内部存储和SD卡播放mp3,您可以执行以下操作:

try {
    FileDescriptor fd = null;

    if (isInInternalMemory(audioFilename)) {
        int audioResourceId = mContext.getResources().getIdentifier(audioFilename, "raw", "com.ampirik.audio");
        AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(audioResourceId);
        fd = afd.getFileDescriptor();
    } else if (isInSdCard(audioFilename)) {
        File baseDir = Environment.getExternalStorageDirectory();
        String audioPath = baseDir.getAbsolutePath() + audioFilename + ".mp3";
        FileInputStream fis = new FileInputStream(audioPath);
        fd = fis.getFD();
    }

    if (fd != null) {
        MediaPlayer mediaPlayer = new MediaPlayer();
        mediaPlayer.setDataSource(fd);
        mediaPlayer.prepare();
        mediaPlayer.start();
    }
} catch (Exception e) {
    e.printStackTrace();
}

这只是一个示例,展示了它如何工作,显然你应该调整它指向存储音频文件的文件夹,并以适当的方式处理你需要的异常情况。

编辑: 此外,你可以在这里看到更复杂的示例,演示如何从SD卡播放音频: https://github.com/ankidroid/Anki-Android/blob/develop/AnkiDroid/src/main/java/com/ichi2/libanki/Sound.java


1
@ZahanSafallwa:感谢您指出这个问题,现在应该已经修复了。 - Edu Zamora

0

在安卓设备中,根目录路径可能是可变的,例如,在一个设备中它可以是/mnt/sdcard,而在另一个设备中则可以是/sdcard/。因此,您可以使用一种简单的方法通过使用android.os.Environment.getExternalStorageDirectory();来提取root文件夹,并在定义后,您可以直接指向您想要的内部或外部路径中的目录。 例如:(try catch可以由IDE自动生成)

        mediaPlayer = new MediaPlayer();
        final File root = android.os.Environment.getExternalStorageDirectory();
        try {

            mediaPlayer.setDataSource(root.getAbsolutePath() + AUDIO_FILES_DIRECTORY+"/musicFile.MP3");

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

            mediaPlayer.prepare();

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接