3

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

所以我打电话

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

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

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

  • 首先,我尝试从一个新线程调用 MediaScannerConnection,但这不起作用,因为扫描仪是在结束活动后最早启动的。我认为“上下文活动”参数将导致在结束此活动后启动。

  • 其次在另一个线程中等待结果并不总是可以的,因为这取决于结果如何继续。

因此两种方式都行不通。:-(

所以我的问题是:如何从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 ... ");

提前感谢任何有好主意解决这个问题的人!

4

1 回答 1

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


}
于 2015-11-07T06:47:01.853 回答