Android で MIME Type 判別

ちょっとアプリを作っていてかなり悩んだのでメモとして残しておく

MIME Typeというのは見たことはあるが、きちんと知らないので調べて見ました

MIME 【Multipurpose Internet Mail Extension】
"マイム"と読むらしい
直訳してみれば、"多目的インターネットメール拡張機能"かな?

ネットワーク上で動画、音声、画像などのファイルを扱うための規格
RFC2045~2049で規定されている。
 拡張子とファイルのデータを関連付けているものらしい
" タイプ名/サブタイプ名"のように区切られて表現される

例としては、
text/html
text/plain
image/jpg
application/pdf
などなど


さて、例えば、AndroidでSDカードにアクセスし適当なファイルを開いた際
どんなファイルか判別したいとする

この時にMIMEを読み取り画像か音声かテキストか判別し
他のアプリにIntentを投げようと思います


※12/25追記:以下の方法だと動作しない場合があるので更に下に追記しました。
Android Developerのここを参考に
//ファイル名からMIMEタイプ取得
public String GetMIMEType(String Path){
 //拡張子を取得
 String ext=MimeTypeMap.getFileExtensionFromUrl(Path);
 //小文字に変換
 ext=ext.toLowerCase();
 //MIME Typeを返す
 return MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
}


引数のパスは"/sdcard/Music/xxx.mp3"のように渡しています。
そこからgetFileExtensionFromUrlメソッドを使って、拡張子(mp3)を取得
それをgetMimeTypeFromExtensionメソッドに入れてMIME Typeを呼び出し元に返す
getFileExtensionFromUrlとgetMimeTypeFromExtensionはエラーだとnullを返すので注意
加えて、他のサイトで見た時、端末によってMIME Typeにばらつきがあるとかなんとか…


最終的に取得したMIME Typeをintent.setType(MIME type)などに渡せば
対応したアプリが起動するはず



※12/25追記
動作する場合としない場合が多くあったのでより調べてみたところ
MimeTypeMapは全角文字に対応していないらしい…
実際空白や漢字がファイル名に含まれた場合に動作しませんでした
具体的にはgetFileExtensionFromUrl()で""が返ってくるようです

getMimeTypeFromExtension()の方は拡張子に対応したMIME Typeを返すので
自分でファイル名の"."以下を読み取って与えるようにしました
ついでにインテントの部分も載せておきます。


private void CreateIntent(String Path){
  //ファイルから拡張子取得
  File file = new File(Path); 
  String fn = file.getName(); 
  int ch = fn.lastIndexOf('.'); 
  String ext = (ch>=0)?fn.substring(ch + 1):null;
  
//拡張子からMIMEType取得
  String MIME = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext.toLowerCase()); 
  
  if(MIME != null && !MIME.equals("")){
   //Intent生成
   Intent intent = new Intent(Intent.ACTION_VIEW); 
   intent.setDataAndType(Uri.fromFile(file),MIME); 
   startActivity(intent); 
  }else
   Log.e("CreateIntent","MIME is Error");
 }


多分今度こそ動くはず…(;´Д`)

コメント

このブログの人気の投稿

カーソルキーさん@つかわない インサートモード編

Elixir に入門したいので雑な 分散KVS を自作した