I'm creating an android application that plays the users music. I've got it to work fine on an emulator but it's not working when I install it on a phone, it crashes at this line:
int songIndex = new Random().nextInt(songsList.size());
Because songList.size() is returning 0, since it seems the music can't be found when it runs on a phone. I've put a Micro SD card in the phone, and have loaded music onto it (in the root folder). I'm using the following to get the path:
final String MEDIA_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
On both the emulator and the phone, the returned string from this is /mnt/sdcard. But it's only working on the emulator. I've also included the following permission in my manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Any ideas?
EDIT:
I didn't include this because I didn't think it would help much, but this is the code I'm using to actually get the songList:
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;
}
How about
return Environment.getExternalStorageDirectory().toString() + "/Music";
This will return the path to internal SD mount point like "/mnt/sdcard"
This is a better way of coding than hard coding in the path.
EDIT
To get it working on all devices try the code below from this thread where they discuss that Android has no concept of "external SD", aside from external storage. OP then came up with the following solution for his problem as a result of all the answers and comments he was given.
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);
I think the reason is , you have run the app connecting your phone to pc in debug mode. And your phone is in Mass Storage Mode , so when connected to pc your SD card is unmounted. That's why you are not getting the songs in your list. Hope it helps.