閉じる

COLUMN_LOCAL_URI と COLUMN_LOCAL_FILENAME

DownloadManagerでダウンロードを行うサンプルを探すと大抵は COLUMN_LOCAL_URI を使って Uri.parse(…).getPath()と書いてある。

ところが、データをキャッシュへ保存*1 すると COLUMN_LOCAL_URI で得られるのは「content://downloads/10」ってな代物。

これを Uri.parse(…).getPath()しても得られるのは「/downloads/10」だけで途方に暮れる羽目に。*2

コンテントプロバイダを使えば内容は得られる気もするけど、単純にファイルの保存場所が知りたいというケースでは COLUMN_LOCAL_URIでなく COLUMN_LOCAL_FILENAMEが正解。

これでばっちりとフルパスが得られる。*3

ただし…APIレベル 11以上、すなわち Android 3.0以上なんだけどね。*4

で、APIレベル9での解法を探してみた。

ACTION_DOWNLOAD_COMPLETEを受けてから、IDを得て queryして Curosrを得て、DownloadManager.COLUMN_LOCAL_URIを使ってローカルの URI(String LocalUri)を得るまでは普通に。

URIのスキームが contentであることからわかるようにこれはコンテントプロバイダを使ってアクセスする。

2968-0.java
Cursor c2 = getActivity().getContentResolver().query(Uri.parse(LocalUri), null, null,null, null);
c2.moveToFirst()
String LocalPath = c2.getString(c2.getColumnIndex("_data"));

以上で「LocalPath」に「/data/user/0/com.android.providers.downloads/cache/HOGEHOGE.zip」や「/cache/download/HOGEHOGE.zip」的なファイルシステム上のパスが得られる。

ところで、この「_data」ってのが何者かというと、「android.provider.Downloads.impl._DATA」がその正体。

そこまでわかってるのになぜに即値でアクセスを?となるのだけど、android.provider.Downloads自体が不可視属性だかシステム属性だか非公開だかで IDEから見えないんだよね。


*1 保存場所を明示しなかった場合はそうなる。

*2 保存場所を指定すると「file:///mnt/sdcard/Download/FILENAME」と fileスキームな URIが得られるので、getPathすれば普通に Fileに食わすことができる。

*3 キャッシュとは言っても普通にストレージ上のファイルで、永続性が不要であれば問題ない。

*4 Androidってこういうの多いんだよね。

コメントを残す

メールアドレスが公開されることはありません。必須項目には印がついています *

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)