2015年8月7日金曜日

MediaScannerService ファッキュー

  Android プログラミング、難しいですね。地雷の山。

Android のアプリケーションから、ファイルストレージにディレクトリを作成したり、ファイルを作成したりしても、PCからUSBで接続するとファイルが見えません。
これは、Android の ファイルシステムとは別に、MTP 接続でのファイル問い合わせが別管理になっているからなんです。
だから、Android のアプリケーションからファイル操作をファイルストレージに対して行ったら、いちいち MediaScannerService 様にお伺いを立てて登録をお願いする必要があります。
ところが、この MediaScannerService 様、登録をお願いしたものは、ディレクトリも含めて、全部「ファイル」として処理をして下さいます。
途中に登録されていない「ディレクトリ」が存在すれば、ついでに、それは「ディレクトリ」として登録してくださる親切仕様。
あ、存在しないファイルに関しては、いちいち通知しなくても、よしなに計らってくださいます。だから、ファイルやディレクトリの削除を通知してはいけません。

昔は、MEDIA_MOUNTED というのを通知してたんですが、今は、こうするのがベストなんじゃないでしょうか?
  public static void makeFileDiscoverable(File file, Context context){
    if( file.isDirectory() )  return;
    if( !file.exists() )  return;
    MediaScannerConnection.scanFile(context, new String[] { file.getAbsolutePath() }, null, null);
  }

ぼけーヽ(`Д´)ノウワァァァン!!

2016/2/2 追記:どうも、この static void MediaScannerConnection.scanFile を使用すると、LogCat に ConnectionのLeakが報告されるようです。
 Java エコシステムにおいて、Leak って言われてもね〜。
Intent を使って通知する方が良いかもしれません。
参考: MediaScanner ServiceConnectionLeaked
参考2:MediaScannerに登録を依頼する方法
  Uri contentUri = Uri.fromFile(newFile);
  Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, contentUri);
  context.sendBroadcast(mediaScanIntent);