什么是在android中扫描filesytem for mp3文件的更好方法?

时间:2015-12-25 14:31:27

标签: android android-asynctask filesystems android-service


我正在尝试创建一个Android mp3播放器应用程序
我想扫描整个文件系统的mp3文件(第一次只有一次)
以下类负责扫描mp3文件

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);
            }
        }
    }
 }
}

上面的算法我从堆栈溢出问题的不同答案中找到了 可以告诉我上述算法是否足够有效吗?因为现在大多数智能手机都包含32GB左右 使用服务

执行上述代码服务或AsyncTask的更好方法是什么?
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");
 }
}

以下代码段用于从Activity

启动服务
Intent i = new Intent(this ,SongScanService.class);
startService(i);

使用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;
}
}

以下代码段用于从活动

启动AsyncTask
new SongScanTask().execute();

我发现使用服务的扫描文件系统可能会停止ui,如果需要很长时间

0 个答案:

没有答案