I am doing a memory game and in one of my method, I'm trying to create all cards by using File, but it could not run. It always goes to "Picture path is empty", but I want it to run.
/*
Create all Cards.
*/
public static List<Card> createAllCards(String dirPath){
//System.out.println("create all cards");
List<Card> cardList = new ArrayList<>();
File file = new File(dirPath);
File[] pictures = file.listFiles();
//System.out.println("file:" + Arrays.toString(pictures));
int index;
String type = "";
String cardPath;
if (pictures != null){
for (File picture : pictures) {
index = picture.getName().lastIndexOf(".");
if (picture.isFile()){
if (index > 0) {
type = picture.getName().substring(index + 1);
System.out.println("output:" + type);
if (type.equals("png")){
cardPath = picture.getPath();
//cardPath = cardPath.replaceAll("\\\\","\\\\\\\\");
cardList.add(new Card(picture.getName(),cardPath));
}
}
}
}
}else {
System.out.println("Picture path is empty");
}
return cardList;
}
}
The java.io.File class is obsolete. The java.nio.file package is its replacement.
The File class was part of Java 1.0 and did a poor job of reporting errors. Many of its methods return null or false, which tells you nothing about what actually went wrong. The classes in java.nio.file will actually throw exceptions telling you exactly what went wrong.
Specifically, you want to use the Path and Files classes:
try (DirectoryStream<Path> pictures =
Files.newDirectoryStream(Paths.get(dirPath), "*.png")) {
for (Path picture : pictures) {
if (Files.isRegularFile(picture)) {
cardList.add(
new Card(picture.getFileName().toString(), cardPath));
}
}
} catch (IOException e) {
e.printStackTrace();
}
This probably won’t make your program work, but it will give you the information you need to resolve the problem.
Okay, I used your code and modified this, as per your requirement.
Have a look:
NOTE: My photos folder is in the room directory
import java.io.File;
import java.util.ArrayList;
import java.util.List;
class Card{
String photoName,cardPath;
public Card(String name, String cardPath2) {
this.photoName = name;
this.cardPath = cardPath2;
}
}
public class readPhotos {
public static List<Card> createAllCards(String dirPath){
//System.out.println("create all cards");
List<Card> cardList = new ArrayList<>();
File file = new File(dirPath);
File[] pictures = file.listFiles();
//System.out.println("file:" + Arrays.toString(pictures));
int index;
String type = "";
String cardPath;
if (pictures != null){
for (File picture : pictures) {
index = picture.getName().lastIndexOf(".");
if (picture.isFile()){
if (index > 0) {
type = picture.getName().substring(index + 1);
System.out.println("output:" + type);
if (type.equals("png")){
cardPath = picture.getPath();
//cardPath = cardPath.replaceAll("\\\\","\\\\\\\\");
cardList.add(new Card(picture.getName(),cardPath));
}
}
}
}
}else {
System.out.println("Picture path is empty");
}
return cardList;
}
public static void main(String...args)
{
List<Card> cardList = readPhotos.createAllCards("./photos/");
System.out.println(cardList);
}
}
add your photos path accordingly... when calling the method readPhotos.createAllCards("./photos/");
Related
How to implement an algorithm in Java 8, given a start directory and a filename, that searches for the file in the given directory or any sub-directories which are nested not deeper than 5 levels.
For example consider the following directory structure:
Folder 1
Folder 2
Folder 3
Folder 4
Folder 5
Folder 6
nfiles.txt....
MyFile.txt
xfile.txt
filesInFolder4....
filesInFolder3...
.....
The algorithm should search for the file up to files containd in the Folder 5 and report if a file with given filename exists?
How to do that using Java 8?
Please have a look at Files.find method.
try (Stream<Path> stream = Files.find(Paths.get("Folder 1"), 5,
(path, attr) -> path.getFileName().toString().equals("Myfile.txt") )) {
System.out.println(stream.findAny().isPresent());
} catch (IOException e) {
e.printStackTrace();
}
I find solution working with Files.find and Files.walk as follows:
// Finding a file upto x level in File Directory using NIO Files.find
Path start = Paths.get("/Users/***/Documents/server_pull");
int maxDepth = 5;
try(Stream<Path> stream = Files.find(start,
maxDepth,
(path, attr) -> String.valueOf(path).endsWith(".json"))){
String fileName = stream
.sorted()
.map(String::valueOf)
.filter((path) -> {
//System.out.println("In Filter : "+path);
return String.valueOf(path).endsWith("system_health_12_55_TestServer.json");
})
.collect(Collectors.joining());
System.out.println("fileName : "+fileName);
}catch(Exception e){
e.printStackTrace();
}
// Finding a file upto x level in File Directory using NIO Files.walk
Path startWalk = Paths.get("/Users/***/Documents/server_pull");
int depth = 5;
try( Stream<Path> stream1 = Files.walk(startWalk,
depth)){
String walkedFile = stream1
.map(String::valueOf)
.filter(path -> {
return String.valueOf(path).endsWith("system_health_12_55_TestServer.json");
})
.sorted()
.collect(Collectors.joining());
System.out.println("walkedFile = "+walkedFile);
}catch(Exception e){
e.printStackTrace();
}
It seems more simpler than walkFileTree...
public static String getAdobeExePath(String basePath, String exeName) {
File[] files = new File(basePath).listFiles();
String foundPath;
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
foundPath = getAdobeExePath(files[i].getAbsolutePath(), exeName);
if (foundPath != null) {
return foundPath;
}
}else {
if (exeName.equals(files[i].getName())) {
return files[i].getAbsolutePath();
}
}
}
return null;
}
This is using recursion.
I did a little more down drill on the problem and found a way to do this in a synchronised manner using ForkJoinPool as follows:
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
public class ForkJoinFolderProcessor {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
MyFolderProcessor hadoop = new MyFolderProcessor("/Users/*****/backups/h/", "log");
MyFolderProcessor t8 = new MyFolderProcessor("/Users/*******/apache-tomcat-9.0.2", "log");
MyFolderProcessor t9 = new MyFolderProcessor("/Users/******/apache-tomcat-8.5.20", "log");
pool.execute(hadoop);
pool.execute(t8);
pool.execute(t9);
do {
System.out.println("---------------------");
System.out.println("Parallelism : "+pool.getParallelism());
System.out.println("Active Threads : "+pool.getActiveThreadCount());
System.out.println("Task Count : "+pool.getQueuedTaskCount());
System.out.println("Steal Count : "+pool.getStealCount());
System.out.println("---------------------");
try
{
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}while((!hadoop.isDone()) || (!t8.isDone()) || (!t9.isDone()));
pool.shutdown();
List<String> results = hadoop.join();
System.out.println("Hadoop: Files found : " + results.size()+" "+results.toString());
results = t8.join();
System.out.println("T8: Files found : " + results.size()+" "+results.toString());
results = t9.join();
System.out.println("T9: Files found : " + results.size()+" "+results.toString());
}
}
class MyFolderProcessor extends RecursiveTask<List<String>>{
private static final long serialVersionUID = 1L;
private final String filepath;
private final String fileExt;
public MyFolderProcessor(String path, String extension) {
this.filepath = path;
this.fileExt = extension;
}
#Override
protected List<String> compute() {
List<String> list = new ArrayList<String>();
List<MyFolderProcessor> tasks = new ArrayList<MyFolderProcessor>();
File file = new File(filepath);
File content[] = file.listFiles();
if(content != null) {
for(File f : content) {
if(f.isDirectory()) {
MyFolderProcessor task = new MyFolderProcessor(f.getAbsolutePath(), fileExt);
task.fork();
tasks.add(task);
}else {
if(checkFile(f.getName()))
list.add(f.getAbsolutePath());
}
}
}
if (tasks.size() > 50) {
System.out.println("tasks ran."+ file.getAbsolutePath()+" "+ tasks.size());
}
addResultsFromTasks(list, tasks);
return list;
}
private void addResultsFromTasks(List<String> list, List<MyFolderProcessor> tasks) {
for (MyFolderProcessor item : tasks) {
list.addAll(item.join());
}
}
private boolean checkFile(String name) {
return name.endsWith(fileExt);
}
}
Though it is more complex solution, but it works pretty well in case of multi threaded environment.
I'd like to write a function that deletes all empty folders, with the option to ignore certain file types (allowed file types are stored in the hashmap) and tell if it should look inside directories.
Calling:
HashMap<String, Boolean> allowedFileTypes = new HashMap<String, Boolean>();
allowedFileTypes.put("pdf", true);
deleteEmptyFolders("ABSOLUTE PATH", allowedFileTypes, true);
Function:
public static void deleteEmptyFolders(String folderPath, HashMap<String, Boolean> allowedFileTypes, boolean followDirectory) {
File targetFolder = new File(folderPath);
File[] allFiles = targetFolder.listFiles();
if (allFiles.length == 0)
targetFolder.delete();
else {
boolean importantFiles = false;
for (File file : allFiles) {
String fileType = "folder";
if (!file.isDirectory())
fileType = file.getName().substring(file.getName().lastIndexOf('.') + 1);
if (!importantFiles)
importantFiles = (allowedFileTypes.get(fileType) != null);
if (file.isDirectory() && followDirectory)
deleteEmptyFolders(file.getAbsolutePath(), allowedFileTypes, followDirectory);
}
// if there are no important files in the target folder
if (!importantFiles)
targetFolder.delete();
}
}
The problem is that nothing is happening, even though it looks through all folders till the end. Is this a good approach or am I missing something completely?
This piece of code recursively delete all the empty folders or directory:
public class DeleteEmptyDir {
private static final String FOLDER_LOCATION = "E:\\TEST";
private static boolean isFinished = false;
public static void main(String[] args) {
do {
isFinished = true;
replaceText(FOLDER_LOCATION);
} while (!isFinished);
}
private static void replaceText(String fileLocation) {
File folder = new File(fileLocation);
File[] listofFiles = folder.listFiles();
if (listofFiles.length == 0) {
System.out.println("Folder Name :: " + folder.getAbsolutePath() + " is deleted.");
folder.delete();
isFinished = false;
} else {
for (int j = 0; j < listofFiles.length; j++) {
File file = listofFiles[j];
if (file.isDirectory()) {
replaceText(file.getAbsolutePath());
}
}
}
}
}
You can use code to delete empty folders using Java.
public static long deleteFolder(String dir) {
File f = new File(dir);
String listFiles[] = f.list();
long totalSize = 0;
for (String file : listFiles) {
File folder = new File(dir + "/" + file);
if (folder.isDirectory()) {
totalSize += deleteFolder(folder.getAbsolutePath());
} else {
totalSize += folder.length();
}
}
if (totalSize ==0) {
f.delete();
}
return totalSize;
}
Shortest code I could come up with is following Java >=8 code:
Files.walk(Paths.get("/my/base/dir/"))
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.filter(File::isDirectory)
.forEach(File::delete);
Add a second (or more) filter statement with whatever clause you need to include/exclude certain folders. File::delete should not delete folders with contents.
Use at own risk.
Kotlin:
fun deleteAllEmptyDirectories(rootPath: Path): Collection<Path> =
mutableListOf<Path>()
.apply {
Files.walk(testPath)
.sorted { p1, p2 -> p2.count() - p1.count() }
.map { it.toFile() }
.filter { it.isDirectory }
.forEach {
if (it.listFiles().all { el -> el.isDirectory && contains(el.toPath()) }) {
val path = it.toPath()
add(path)
Files.delete(path)
}
}
}
Test:
private val testPath = Path.of("build", javaClass.simpleName, UUID.randomUUID().toString())
#Test
fun test() {
Files.createDirectory(testPath)
val dirWithTwoEmptySubdirs = Files.createDirectory(testPath.resolve("dirWithTwoEmptySubdirs"))
val dir1 = Files.createDirectory(dirWithTwoEmptySubdirs.resolve("dir1"))
val dir2 = Files.createDirectory(dirWithTwoEmptySubdirs.resolve("dir2"))
val dirWithOneDiffDir = Files.createDirectory(testPath.resolve("dirWithOneDiffDir"))
var emptyDir = Files.createDirectory(dirWithOneDiffDir.resolve("empty"))
val notEmptyDir = Files.createDirectory(dirWithOneDiffDir.resolve("notempty"))
Files.writeString(notEmptyDir.resolve("file.txt"), "asdf")
assertEquals(
setOf<Path>(dirWithTwoEmptySubdirs, dir1, dir2, emptyDir),
deleteAllEmptyDirectories(testPath).toSet()
)
}
After reading all answers and concluding that all of them have at least one problem I still had to write it myself:
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Temp {
public static void main(String[] args) {
final String path = "D:\\";
deleteEmpty(new File(path));
}
private static int deleteEmpty(File file) {
List<File> toBeDeleted = Arrays.stream(file.listFiles()).sorted() //
.filter(File::isDirectory) //
.filter(f -> f.listFiles().length == deleteEmpty(f)) //
.collect(Collectors.toList());
int size = toBeDeleted.size();
toBeDeleted.forEach(t -> {
final String path = t.getAbsolutePath();
final boolean delete = t.delete();
System.out.println("Deleting: \t" + delete + "\t" + path);
});
return size;
}
}
I'm having this weird issue where a class from some transitive dependency keeps showing up at runtime, shadowing a newer version of the class from the (correct) first level dependency, even though I thought I made sure that I excluded the older version from all other dependencies I declare (this is in a Maven/IntelliJ setup)
More specifically, at runtime the app fails with a NoClassDefFoundError, since during class loading a wrong version of the owning class is loaded, which has a field of a type that does not exist in newer versions of the library that class is defined in. To illustrate:
// lib.jar:wrong-version
class Owner {
private SomeType f;
}
// lib.jar:new-version
class Owner {
private OtherType f;
}
At runtime, the class loader finds a reference to the symbol Owner and attempts to load the version that has SomeType, which in return does not exist anymore. This is even though I excluded wrong-version where ever I could spot it.
I also ran mvn dependency:tree to see if the old version is still being pulled in somewhere, but it's not!
In order to further debug this, I was wondering if there is a way to find out where a class loader was reading a specific class from, i.e. which file? Is that possible? Or even better, build a list of origins where a certain symbol is defined, in case it's defined more than once?
Sorry if this is vague, but the problem is rather nebulous.
The following code will search the whole classpath for a particular class. With no arguments it will dump every class it finds and then you can pipe to grep or redirect to a file. It looks inside jars...
Usage: WhichClass or WhichClass package.name (note no .class)
Apologies for the lack of comments ...
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public final class WhichClass {
private WhichClass() {
}
static Vector<String> scratchVector;
public static void main(final String[] argv) {
Vector v;
if ((argv.length == 0) || "-all".equals(argv[0])) {
v = findClass(null);
} else {
v = findClass(argv[0]);
}
for (int i = 0; i < v.size(); i++) {
System.out.println(v.elementAt(i));
}
}
static String className(final String classFile) {
return classFile.replace('/', '.').substring(0, classFile.length() - ".class".length());
}
static Vector findClass(final String className) {
if (className != null) {
scratchVector = new Vector<String>(5);
} else {
scratchVector = new Vector<String>(5000);
}
findClassInPath(className, setupBootClassPath());
findClassInPath(className, setupClassPath());
return scratchVector;
}
static void findClassInPath(final String className, final StringTokenizer path) {
while (path.hasMoreTokens()) {
String pathElement = path.nextToken();
File pathFile = new File(pathElement);
if (pathFile.isDirectory()) {
try {
if (className != null) {
String pathName = className.replace('.', System.getProperty("file.separator").charAt(0)) + ".class";
findClassInPathElement(pathName, pathElement, pathFile);
} else {
findClassInPathElement(className, pathElement, pathFile);
}
} catch (IOException e) {
e.printStackTrace();
}
} else if (pathFile.exists()) {
try {
if (className != null) {
String pathName = className.replace('.', '/') + ".class";
ZipFile zipFile = new ZipFile(pathFile);
ZipEntry zipEntry = zipFile.getEntry(pathName);
if (zipEntry != null) {
scratchVector.addElement(pathFile + "(" + zipEntry + ")");
}
} else {
ZipFile zipFile = new ZipFile(pathFile);
Enumeration entries = zipFile.entries();
while (entries.hasMoreElements()) {
String entry = entries.nextElement().toString();
if (entry.endsWith(".class")) {
String name = className(entry);
scratchVector.addElement(pathFile + "(" + entry + ")");
}
}
}
} catch (IOException e) {
System.err.println(e + " while working on " + pathFile);
}
}
}
}
static void findClassInPathElement(final String pathName, final String pathElement, final File pathFile)
throws IOException {
String[] list = pathFile.list();
for (int i = 0; i < list.length; i++) {
File file = new File(pathFile, list[i]);
if (file.isDirectory()) {
findClassInPathElement(pathName, pathElement, file);
} else if (file.exists() && (file.length() != 0) && list[i].endsWith(".class")) {
String classFile = file.toString().substring(pathElement.length() + 1);
String name = className(classFile);
if (pathName != null) {
if (classFile.equals(pathName)) {
scratchVector.addElement(file.toString());
}
} else {
scratchVector.addElement(file.toString());
}
}
}
}
static StringTokenizer setupBootClassPath() {
String classPath = System.getProperty("sun.boot.class.path");
String separator = System.getProperty("path.separator");
return new StringTokenizer(classPath, separator);
}
static StringTokenizer setupClassPath() {
String classPath = System.getProperty("java.class.path");
String separator = System.getProperty("path.separator");
return new StringTokenizer(classPath, separator);
}
}
If you know the fully qualified name of the class, say somelib.Owner, you can try calling the following in your code:
public void foo() {
URL url = somelib.Owner.class.getClassLoader().getResource("somelib/Owner.class");
System.out.println(url);
}
I want to return a file list from a function which loops through all the files/directories on SD card on android and which confirm the specific data type(mp3, mp4, png). But I cannot figure out when to return the values from the loop. Can anyone help me with this?
My code:
private Pattern patternVideo = Pattern.compile("([^\\s]+(\\.(?i)(mp4))$)");
private Pattern patternAudio = Pattern.compile("([^\\s]+(\\.(?i)(mp3))$)");
private Pattern patternImages = Pattern
.compile("([^\\s]+(\\.(?i)(png|jpeg|jpg))$)");
Matcher videoMatcher, audioMatcher, imageMatcher;
private ArrayList<String> videoFiles = new ArrayList<String>();
private ArrayList<String> audioFiles = new ArrayList<String>();
private ArrayList<String> imageFiles = new ArrayList<String>();
private void buildFileList(File dirName) {
if (dirName.isFile()) {
// matcher = pattern.matcher(dirName.getName());
// if (matcher.find())
// fileNamesWithPaths.add(dirName.getAbsolutePath());
} else if (dirName.isDirectory()) {
File[] files = dirName.listFiles();
for (File file : files) {
if (file.isFile()) {
videoMatcher = patternVideo.matcher(file.getName());
audioMatcher = patternAudio.matcher(file.getName());
imageMatcher = patternImages.matcher(file.getName());
if (videoMatcher.find()) {
videoFileNames.add(file.getAbsolutePath());
} else if (audioMatcher.find()) {
audioFileNames.add(file.getAbsolutePath());
} else if (imageMatcher.find()) {
imageFileNames.add(file.getAbsolutePath());
}
} else if (file.isDirectory()) {
buildFileList(file);
}
}
}
}
Just put your return statement outside of the isDirectory() test:
private ArrayList buildFileList(File dirName) {
if (dirName.isDirectory()) {
File[] files = dirName.listFiles();
for (File file : files) {
if (file.isFile()) {
videoMatcher = patternVideo.matcher(file.getName());
audioMatcher = patternAudio.matcher(file.getName());
imageMatcher = patternImages.matcher(file.getName());
if (videoMatcher.find()) {
videoFiles.add(file.getAbsolutePath());
} else if (audioMatcher.find()) {
audioFiles.add(file.getAbsolutePath());
} else if (imageMatcher.find()) {
imageFiles.add(file.getAbsolutePath());
}
} else if (file.isDirectory()) {
buildFileList(file);
}
}
}
//Combine your arrayLists here
return CombinedLists //return the Combined Lists
}
You don't need to return anything; after the call the three *Files lists will have all the files you seek.
Edit: why won't you use the MediaStore provider?
Using Stack will help you to avoid recursion:
private void buildFileList(File dirName) {
Stack<File> stack = new Stack<File>();
stack.add(dirName);
while(!stack.isEmpty()){
File next = stack.pop();
if (next.isFile()) {
// do something...
} else if (next.isDirectory()) {
stack.addAll(Arrays.asList(next.listFiles()));
}
}
}
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.