2013年4月15日月曜日

VideoView でapk内のファイルを再生

res/raw/sample.mp4 にビデオがある場合は↓で再生できた。

mVideoView.setVideoPath("android.resource://com.example.android.apis/" + R.raw.sample);

もしくは
mVideoView.setVideoURI(Uri.parse("android.resource://com.example.android.apis/" + R.raw.sample));

と、android.resource なスキーマでパスを指定すると良いらしい

android.resource://[アプリのパッケージ]/[ID]
って書式ですね。

android.resource://[アプリのパッケージ]/raw/sample
みたいにパス指定の書式でもOKらしい

Androidアフ゜リにおけるassetsフォルダとres/rawの使い分け

アプリで画像やXMLを利用するには res/drawable や res/value res/xml に配置してリソースIDを使用するよう決められているがそれ以外のファイルはassetsフォルダとres/raw どちらに配置するか迷った。
が、規約があった。

要はこういうこと

【assetsフォルダ】
・アプリから保存可能!!
・ディレクトリ構造可能(フォルダ作成可能)
・リソースIDが振られないので引数に使用するAPIには使用できない
・URLを引数とするAPIに「file:///android_asset/」として使える

【res/rawフォルダ】
・アプリからの保存不可
・ディレクトリ構造不可
・res/raw-en res/raw-hdpiのように解像度・言語別に端末自動判別してくれる機能が使える
・リソースIDがコンパイル時に振られるので引数に使うAPIに使用できる。
 ※特に音楽やビデオファイルの場合はAPIがリソースIDを求められることが多いし、公式でここ指定されている
・URLとしては取れないので引数をURLとするには一旦assetやテ゛ータフォルタ゛に保存する必要がある  ←俺追加
↑ごめんちゃい。ContentProviderでできました。

ちなみにアプリ固有なバイナリファイルを読み込む場合はここに「you might consider saving some resources in the assets/ directory (instead of res/raw/). 」
※俺訳:リソース(リソースID関連のソース・動作メモリ)を節約できるのでres/rawよりassetsを検討しる

とあったのでメテ゛ィアファイルやXMLのような特定のファイル形式でなく、解像度・言語別判別を使わないのならばassetsフォルダのほうがいいみたい


【おまけ】
フォントファイル(ttf)をアプリから使用する時のようにリソースIDが全く使えず、AssetManagerを優先するAPI
もあるので注意

assetsフォルダに圧縮ファイルを設置して、解凍するサンプルコード

bigfile.dataを圧縮してbigfile.zipとしたものを次の場所に設置した場合、
/assets/datadir/bigfile.zip
次の場所に解凍されます。
/data/data/com.example.sample.text/files/bigfile.data
String path = null;
try {
AssetManager am = getResources().getAssets();
InputStream is = am.open("datadir/bigfile.zip", AssetManager.ACCESS_STREAMING);
ZipInputStream zis = new ZipInputStream(is);
ZipEntry ze = zis.getNextEntry();

if (ze != null) {
path = getFilesDir().toString() + "/" + ze.getName();
FileOutputStream fos = new FileOutputStream(path, false);
byte[] buf = new byte[1024];
int size = 0;

while ((size = zis.read(buf, 0, buf.length)) > -1) {
fos.write(buf, 0, size);
}
fos.close();
zis.closeEntry();
}
zis.close();
} catch (Exception e) {
e.printStackTrace();
}

assetsフォルダには1MB以上の非圧縮ファイルを設置できない

Androidでファイルを設置する場合にassetsフォルダを使用することがありますが、このフォルダにはファイルの容量制限があります。

この容量を超えたものをインストールしようとすると、次のようなエラーが出ることがあります。
W/ResourceType(11947): Unable to get buffer of resource asset file

またインストールできたとしても、実行時に次のようなエラーが出て突如アプリが閉じます。
D/asset ( 300): Data exceeds UNCOMPRESS_DATA_MAX (1353552 vs 1048576)

この容量はOSの次のファイルの『UNCOMPRESS_DATA_MAX』の値で制限されています。
frameworks/base/include/utils/asset.h
#ifdef HAVE_ANDROID_OS
UNCOMPRESS_DATA_MAX = 1 * 1024 * 1024
#else
UNCOMPRESS_DATA_MAX = 2 * 1024 * 1024