从SD卡播放音乐可在模拟器上运行,但不能在手机上运行

时间:2013-10-06 10:56:19

标签: java android file storage

我正在创建一个播放用户音乐的Android应用程序。我已经让它在模拟器上工作正常但是当我在手机上安装它时它无法正常工作,它崩溃在这一行:

int songIndex = new Random().nextInt(songsList.size());

因为songList.size()返回0,因为它似乎在手机上运行时无法找到音乐。我已经将Micro SD卡放入手机,并将音乐加载到手机上(在根文件夹中)。我正在使用以下内容来获取路径:

final String MEDIA_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();

在模拟器和手机上,返回的字符串是/ mnt / sdcard。但它只适用于模拟器。我还在清单文件中包含以下权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

有什么想法吗?

编辑:

我没有包括这个,因为我觉得它不会有多大帮助,但这是我用来实际获得歌曲的代码:

public ArrayList<HashMap<String, String>> getPlaylist(){
    File home = new File(MEDIA_PATH);

    if(home.listFiles(new FileExtensionFilter()).length > 0) {
        for(File file : home.listFiles(new FileExtensionFilter())){
            HashMap<String, String> song = new HashMap<String, String>();
            song.put("songTitle", file.getName().substring(0, (file.getName().length() -4)));
            song.put("songPath", file.getPath());

            //Add song to song list
            songsList.add(song);
        }
    }

    return songsList;
}

2 个答案:

答案 0 :(得分:1)

怎么样

return Environment.getExternalStorageDirectory().toString() + "/Music";

这将返回内部SD挂载点的路径,如“/ mnt / sdcard”

这是一种比路径中的硬编码更好的编码方式。

修改

要让它在所有设备上运行,请尝试以下this thread中的代码,他们会讨论Android除了外部存储之外没有“外部SD”的概念。然后,由于他给出的所有答案和评论,OP为他的问题提出了以下解决方案。

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import android.os.Environment;
import android.util.Log;

public class ExternalStorage {

public static final String SD_CARD = "sdCard";
public static final String EXTERNAL_SD_CARD = "externalSdCard";

/**
 * @return True if the external storage is available. False otherwise.
 */
public static boolean isAvailable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

public static String getSdCardPath() {
    return Environment.getExternalStorageDirectory().getPath() + "/";
}

/**
 * @return True if the external storage is writable. False otherwise.
 */
public static boolean isWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;

}

/**
 * @return A map of all storage locations available
 */
public static Map<String, File> getAllStorageLocations() {
    Map<String, File> map = new HashMap<String, File>(10);

    List<String> mMounts = new ArrayList<String>(10);
    List<String> mVold = new ArrayList<String>(10);
    mMounts.add("/mnt/sdcard");
    mVold.add("/mnt/sdcard");

    try {
        File mountFile = new File("/proc/mounts");
        if(mountFile.exists()){
            Scanner scanner = new Scanner(mountFile);
            while (scanner.hasNext()) {
                String line = scanner.nextLine();
                if (line.startsWith("/dev/block/vold/")) {
                    String[] lineElements = line.split(" ");
                    String element = lineElements[1];

                    // don't add the default mount path
                    // it's already in the list.
                    if (!element.equals("/mnt/sdcard"))
                        mMounts.add(element);
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    try {
        File voldFile = new File("/system/etc/vold.fstab");
        if(voldFile.exists()){
            Scanner scanner = new Scanner(voldFile);
            while (scanner.hasNext()) {
                String line = scanner.nextLine();
                if (line.startsWith("dev_mount")) {
                    String[] lineElements = line.split(" ");
                    String element = lineElements[2];

                    if (element.contains(":"))
                        element = element.substring(0, element.indexOf(":"));
                    if (!element.equals("/mnt/sdcard"))
                        mVold.add(element);
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }


    for (int i = 0; i < mMounts.size(); i++) {
        String mount = mMounts.get(i);
        if (!mVold.contains(mount))
            mMounts.remove(i--);
    }
    mVold.clear();

    List<String> mountHash = new ArrayList<String>(10);

    for(String mount : mMounts){
        File root = new File(mount);
        if (root.exists() && root.isDirectory() && root.canWrite()) {
            File[] list = root.listFiles();
            String hash = "[";
            if(list!=null){
                for(File f : list){
                    hash += f.getName().hashCode()+":"+f.length()+", ";
                }
            }
            hash += "]";
            if(!mountHash.contains(hash)){
                String key = SD_CARD + "_" + map.size();
                if (map.size() == 0) {
                    key = SD_CARD;
                } else if (map.size() == 1) {
                    key = EXTERNAL_SD_CARD;
                }
                mountHash.add(hash);
                map.put(key, root);
            }
        }
    }

    mMounts.clear();

    if(map.isEmpty()){
             map.put(SD_CARD, Environment.getExternalStorageDirectory());
    }
    return map;
}
}

<强> USAGE

Map<String, File> externalLocations = ExternalStorage.getAllStorageLocations();
File sdCard = externalLocations.get(ExternalStorage.SD_CARD);
File externalSdCard = externalLocations.get(ExternalStorage.EXTERNAL_SD_CARD);

答案 1 :(得分:0)

我认为原因是,你已经运行了应用程序,在调试模式下将手机连接到电脑。并且您的手机处于大容量存储模式,因此当连接到PC时,您的SD卡已卸载。这就是为什么你没有收到列表中的歌曲。希望它有所帮助。