I am trying to create an application for an Android mp3 player. I want to scan the entire file system for mp3 files (only once for the first time). Below the class is responsible for scanning mp3 files.
public class Mp3Scanner implements Runnable{
private static final String TAG = "Mp3Scanner";
final String MEDIA_PATH = new String("/");
private String[] mp3Extensions = new String[]{".mp3",".MP3"};
private ArrayList<HashMap<String,String>> songsList = new ArrayList<HashMap<String,String>>();
private ArrayList<String> excludePath = new ArrayList<String>();
private MediaMetadataRetriever mediaMetadataRetriever;
public Mp3Scanner(){
mediaMetadataRetriever = new MediaMetadataRetriever();
excludePath.add("/sys");
excludePath.add("/proc");
}
public ArrayList<HashMap<String, String>> getSongsList() {
return songsList;
}
private void scanDir(File directory){
if(directory != null){
File[] listFiles = directory.listFiles();
if(listFiles!=null && listFiles.length>0){
for(File file : listFiles){
if(file.isDirectory()){
Log.i(TAG, "Scanning Dir:" + file.getPath());
scanDir(file);
}else{
addSongToList(file);
}
}
}
}
}
private void addSongToList(File song){
if(song!=null && (song.getName().endsWith(mp3Extensions[0]) || song.getName().endsWith(mp3Extensions[1]))){
HashMap<String,String> songInfo = new HashMap<String, String>();
Log.i(TAG, "Adding Song:" + song.getPath());
mediaMetadataRetriever.setDataSource(song.getPath());
Log.i(TAG, "Album:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM));
Log.i(TAG, "AlbumArtish:" + mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST));
Log.i(TAG,"Artist:"+mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST));
Log.i(TAG,"Author:"+mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_AUTHOR));
Log.i(TAG,"Duration:"+mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
Log.i(TAG,"MimeType:"+mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE));
Log.i(TAG,"Title:"+mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
songInfo.put("path", song.getPath());
songInfo.put("name",song.getName());
songsList.add(songInfo);
}
}
@Override
public void run() {
long start = System.currentTimeMillis();
Log.i(TAG, "Scan started at:"+start);
scanForSongs();
long stop = System.currentTimeMillis();
Log.i(TAG, "Scan Completed at:"+stop);
long timeTaken = stop - start;
Log.i(TAG, "Total Time Taken To Scan:"+timeTaken);
}
public void scanForSongs() {
Log.i(TAG, "Preparing List..");
File home = new File(MEDIA_PATH);
Log.i(TAG, home.getPath());
File[] listFiles = home.listFiles();
if(listFiles!=null)
Log.i(TAG, "length:" + listFiles.length);
if(listFiles!=null && listFiles.length>0){
for(File file : listFiles){
if(file.isDirectory() && !excludePath.contains(file.getAbsolutePath())){
Log.i(TAG, "Scanning Dir:" + file.getPath());
scanDir(file);
}else{
addSongToList(file);
}
}
}
}
}
The above algorithm, which I found from different answers to the questions,
can any body tell me if the algorithm above is enough, because nowadays most smartphones contain 32 GB
And what is the best approach for executing the above code of either the service or AsyncTask using the service
public class SongScanService extends Service {
private static final String TAG = "Mp3Scanner";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG,"OnStartCommand");
Mp3Scanner mp3Scanner = new Mp3Scanner();
Thread mp3Thread = new Thread(mp3Scanner);
mp3Thread.start();
String[] paths = FileUtility.getStorageDirectories();
for(String path:paths){
Log.i("Path From Utility:",path);
}
this.stopSelf();
return Service.START_NOT_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG,"onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
}
the code snippet below is for starting a service from Activity
Intent i = new Intent(this ,SongScanService.class);
startService(i);
using AsyncTask
public class SongScanTask extends AsyncTask<Void , Void, Void> {
private static final String TAG = "SongScanTask";
@Override
protected Void doInBackground(Void... params) {
Log.i(TAG, "AsyncTask Starting..");
Mp3Scanner mp3Scanner = new Mp3Scanner();
Thread mp3Thread = new Thread(mp3Scanner);
mp3Thread.start();
try {
mp3Thread.join();
ArrayList songsList = mp3Scanner.getSongsList();
Log.i(TAG,"No.Of Songs Found:"+songsList.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, "AsyncTask Completed..");
return null;
}
}
the code snippet below is designed to run AsyncTask from Activity
new SongScanTask().execute();
, , , ui,