I am trying to create an android mp3 player app
i want to scan entire filesystem for mp3 files(only once during first time)
the below class is responsible for scaning of 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 i found from different answers of stack overflow questions
can any body please tell me whether the above algorithm is efficient enough?because nowadays most smart phones contains 32GB
And what is the better approach to execute the above code either service or AsyncTask
using 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();
// mp3Thread.join();
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 below code snippet is for to start 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 below code snippet is for to start AsyncTask from Activity
new SongScanTask().execute();
i found scanning file system using service may stop ui if it takes long time