What is the best file scanning approach for mp3 files in Android?


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();
       // 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 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,

+4

Source: https://habr.com/ru/post/1621716/


All Articles