3

MediaStoreから情報を収集したい。.nomediaファイルを使用すると、ファイルがスキャンされない場合があるため、明示的な呼び出しを使用して、ファイルがスキャンされたことを確認します。

だから私は呼んでいます

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

...スキャンを強制します。ただし、これには時間がかかる場合があるため、バックグラウンドで実行したいと思います...

私はこれを達成しようとしていくつかの問題に遭遇しました:

  • 最初に、新しいスレッドからMediaScannerConnectionを呼び出そうとしましたが、アクティビティの終了後にスキャナーが最も早く開始されたため、これは機能しませんでした。「コンテキストアクティビティ」パラメータは、このアクティビティの終了後に開始されると思います。

  • 続行する方法は結果に依存するため、別のスレッド内で結果を待つことは必ずしも問題ありません。

したがって、両方の方法は機能しません。:-(

だから私の質問は:MediaScannerConnection.scanFile()アクティビティスレッド以外のスレッドで開始する方法は?これが不可能な場合、非同期処理を実行するためのベストプラクティスは何ですか?IMHO、待機は新しいスレッド内で発生する必要がありますが、続行する方法を決定するために結果を使用するには遅すぎます。


最初の試行のサンプル-結果が返されることはありません:

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

2回目の試行のサンプル:

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 に答える