2014年5月2日金曜日

MediaScannerConnection.scanFileを同期処理させる

MediaScannerConnection.scanFileでファイルをスキャンさせてその完了を待つコードを考えてみた。が、どんな状況でも動くようにさせるのは難しそうだ。
以下のようなコードはうまくいきそうだが、実際には状況によってはうまくいかない。

  final Object lock = new Object();
  synchronized (lock) {
   Log.d(TAG, "ScanFile Start");
   MediaScannerConnection.scanFile(context, new String[] { filePath },
     null, new OnScanCompletedListener() {

      @Override
      public void onScanCompleted(String path, Uri uri) {
       Log.d(TAG, "onScanCompleted");
       synchronized (lock) {
        lock.notify();
       }
      }
     });
   try {
    Log.d(TAG, "lock start");
    lock.wait();
    Log.d(TAG, "unlocked");
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
その状況とは、このコードがUIスレッドで動いている場合。
おそらくMediaScannerServiceへconnectしてonMediaScannerConnectedを待つあたりでUIスレッドが動いていないと駄目なんだろうなーと。

というわけで、回避策としては非同期にできるところまでさかのぼって、別スレッドで動かすしかなさそう。
それが嫌なら、MediaScannerConnection インスタンスを作って(事前にサービスへの接続をしておいて)scanFileすればいけるんじゃないですかね(試してません)。