如何通知异步调用MediaScannerConnection.scanFile(),同时通知它已完成?

时间:2011-11-27 13:29:09

标签: android multithreading android-activity android-mediascanner

我想从MediaStore收集一些信息。有时.nomedia文件导致文件未被扫描,因此我使用显式调用来确保文件已被扫描!

所以我正在打电话

MediaScannerConnection.scanFile(Context activity, String[] path, 
   String[] mimeTypes, OnScanCompletedListener oscl);

...强制扫描。但是,这可能需要一段时间,所以我想在后台运行它...

我遇到了几个试图实现这个目标的问题:

  • 首先,我尝试从新线程调用MediaScannerConnection,但这不起作用,因为扫描程序是在结束活动后最早启动的。我认为“Context activity”参数将在结束此活动后启动。

  • 第二个等待另一个线程内的结果并不总是正常的,因为它取决于结果如何继续。

因此两种方式都不起作用。 : - (

所以我的问题是:如何在活动线程以外的线程中启动MediaScannerConnection.scanFile()?如果无法做到这一点,那么完成异步处理的最佳做法是什么?恕我直言,等待必须发生在一个新的线程中,但是现在使用结果决定如何继续已经为时已晚。


第一次尝试的样本 - 从不返回结果:

Log.d(TAG, "MAIN: ID of the main thread ... " 
      + Thread.currentThread().getId());
final Object o = new Object();

Thread scannerThread = new Thread() {
  public void run() {
    Log.d(TAG, "SCAN: scanner thread is started ... (thread id: " 
      + Thread.currentThread().getId() + ")");
    MediaScannerConnection.scanFile(ActivityPlayer.this, new String[] { 
         mp3File.getAbsolutePath() }, null,
         new MediaScannerConnection.OnScanCompletedListener() {
           @Override
           public void onScanCompleted(String path, Uri uri) {
             Log.d(TAG, "SCAN: the onScanCompleted is called! (" + path + ")");
             synchronized (o) {
               o.notifyAll();
               Log.d(TAG, "SCAN: notify is successful executed!");
             }
           }
         });
         Log.d(TAG, "SCAN: MediaScanner is called");
       }
     };         
     Log.d(TAG, "MAIN: start scanning thread");
     scannerThread.start();

     synchronized (o) {
       try {
         Log.d(TAG, 
               "WAITER: Start: Waiting - for the notify of this object o!");
         o.wait();
         Log.d(TAG, "WAITER: End: Waiting - the notify happened!");
       } catch (Exception e) { // InterruptedException
         e.printStackTrace();
       }
     }  

第二次尝试的样本:

Log.d(TAG, "MAIN: ID of the main thread ... " 
      + Thread.currentThread().getId());
final Object o = new Object();

// call scanner ...
Log.d(TAG, "scanning of file started ...");
MediaScannerConnection.scanFile(ActivityPlayer.this, 
        new String[] {mp3File.getAbsolutePath() }, 
        null,   
        new MediaScannerConnection.OnScanCompletedListener() {
          @Override
          public void onScanCompleted(String path, Uri uri) {
            Log.d(TAG, "the onScanCompleted is called! (" + path + ")");
            synchronized (o) {
              o.notifyAll();
              Log.d(TAG, "notify is successful executed!");
            }
          }
        });
// Start thread for waiting ...
Thread waiterThread = new Thread() {
  public void run() {
    Log.d(TAG, "WAITER: waiter thread is started!");
    synchronized (o) {
      try {
        Log.d(TAG, 
              "WAITER: Start: Waiting - for the notify of this object o!");
        o.wait();
        Log.d(TAG, "WAITER: End: Waiting - the notify happened!");
      } catch (Exception e) { // InterruptedException
        e.printStackTrace();
      }
    }
  }
};
waiterThread.start();
Log.d(TAG, "MAIN: ended things ... ");

提前感谢任何有想法解决这个问题的人!

1 个答案:

答案 0 :(得分:0)

我用这个

public class MediaLibraryHelper {
    public interface OnMediaScanListener{
        void onError();
        void onSuccess(Uri uri);
    }

    private MediaScannerConnection conn;
    private Context context;
    public MediaLibraryHelper(Context context){
        this.context=context;
    }

    public void scanFile(final File file,final OnMediaScanListener lis){
        if(conn!=null)
            conn.disconnect();

        if(!file.isFile()){
            lis.onError();
            return;
        }

        conn=new MediaScannerConnection(context,new MediaScannerConnectionClient(){


            public void onMediaScannerConnected() {
                conn.scanFile(file.getAbsolutePath(),null);
            }


            public void onScanCompleted(String arg0, Uri arg1) {
                conn.disconnect();
                if(arg1==null){
                    lis.onError();
                }
                lis.onSuccess(arg1);

            }});
        conn.connect();
    }


}