assetsフォルダのHTML表示

assetsフォルダのHTML表示

アプリにHTMLやCSS
Javascriptや画像などのリソースを含めておき、WebViewで表示することができる

これをやるには
loadUrl()の引数に指定するURLを
file:///android_asset/ファイル名
とする

mWebView.loadUrl("file:///android_asset/index.html");

というかんじ

これは、利用規約やプライバシーポリシーの表示
アプリの解説やFAQなどに使うことが多い

また、PhoneGapなどでもこの方法は使われる

ただし、追加するごとにアプリサイズが大きくなるので注意

ファビコンの取得

ファビコンの取得

ファビコンは、WebページやWebサイトのシンボルマークとして設置できるアイコンのこと

Webサイトを閲覧していると
ブラウザのURL欄の左側にでているのがわかる

ファビコンを取得するには
WebIconDatabaseクラスに
ファビコンの保存先を指定して
WebChromeClientクラスの
onReceivedIconハンドラ経由で取得する

onCreate()の中へ処理を追加

setupWebIconDatabase();

mWebView = (WebView)findViewById(R.id.web);
mFaviconView = (ImageView)findViewById(R.id.imgFavicon);
mTitleView = (TextView)findViewById(R.id.title);

mWebView.getSettings().setJavascriptEnabled(true);
mWebView.setWebViewClient(newWebViewClient());
mWebView.setWebChromeClient(new WebChromeClient(){

@Override
public void onReceivedTitle(WebView view, String title){
mTitleView.setText(string);
}

@Override
public void onReceivedIcon(WebView view, Bitmap icon){
Log.d(TAG, "onReceivedIcon");
mFaviconView.setImageBitmap(icon);
}

@Override
public void onReceivedTouchIconUrl(WebView view, String url, boolean precomposed){
Log.d(TAG,"onReceivedTouchIconUrl, url = "+ url);
}
});
mWebView.loadUrl("アイコンのURL");

次に、ファビコンアイコンの保存先を
setWebIconDatabase()で指定

@SupportWarnings("deprecation")
private void setWebIconDatabase(){
if(Build.VERSION_SDK_INT <= Build.VERSION_CODES.JELLY_BEANS_MR2){
//アイコンを保存するディレクトリを取得
File databaseDir = getDir("icon", Context.MODE_PRIVATE);

if(!databaseDir.exists()){
//ディレクトリがないなら作成
databaseDir.mkdirs();
}

//正常につくれたら、WebIconDatabase保存先として指定
android.webkit.WebIconDatabase.getInstance().open(databaseDir.getAbsolutePath());

Log.d(TAG,"IcondatabaseDir = "+ databaseDir);
}
}

Android 4.4からは
WebIconDatabaseクラスは非推奨になったけど
それ以下のバージョンだと、使わないと
onReceivedIconUrlハンドラが呼ばれなくなる

onReceivedTouchIconUrl()は
ファビコンではなく
apple-touch-iconを取得するためのハンドラ

apple-touch-iconは
Appleの独自仕様で、大きなファビコンみたいなもの

Webサイトがこれに対応してると
このイベントハンドラが動作するので
そのURLから画像を取得することになる

長押しリンクのURL取得

長押しリンクのURL取得

Webページのリンクを長押ししたら
リンクをクリップボードへコピー
とか
リンク先の保存などをするときに
長押しリンクのURL取得を利用する

WebViewを長押ししたときのイベントを取得するには
長押しを有効にして
長押しのイベントリスナーをセットする

長押しの有効には
WebViewクラスの
setLongClickable()

長押しイベントリスナーのセットには
WebViewクラスの
setOnLongClickListener()
を使う

まず、

implements OnLongClickListener

を追記

private WebView mWebView;

でアクセスしやすくする

次に、onCreate()の中で

mWebView = new WebView(this);
setContentView(mWebView);

これでビュー作成と配置

mWebView.setSettings().setJavascriptEnabled(true);

でJavascriptを使えるようにしておく

mWebView.setLongClickable(true);

で長押し有効に

mWebView.setOnLongClickListener(this);

で長押しリスナーセット

mWebView.setWebViewClient(new WebViewClient());
mWebView.loadUrl("http://www.google.co.jp/");

でWebページ表示

次に、HitTestResult からデータの取り出し

HitTestResultは
ユーザーがアクションを起こした対象の箇所の情報を保持するクラス

WebViewクラスの
getHitTestResult()
で取得できる

さらにそこから長押し対象を判定し、URLを取得する

@Override
public boolean onLongClick(View v){

if(v == mWebView){

//長押しした箇所の情報を取得
HitTestResult hittestresult = mWebView.getHitTestResult();

//長押し対象の判定
switch(hittestresult.getType()){

case hittestresult.SRC_ANCHOR_TYPE:
//長押しがアンカーリンクの処理
String url = hittestresult.getExtra();
Toast.makeText(this, "url: "+ url, Toast.LENGTH_SHORT).show();
break;
}
}
return false;
}

今回は、HitTestResult.SRC_ANCHOR_TYPEなので、HTMLのaタグのリンクを取得している

ほかにも
EDIT_TEXT_TYPE
EditTextの場合

EMAIL_TYPE
メールアドレスの場合

GEO_TYPE
地図情報の場合

IMAGE_TYPE
HTMLのimgタグの場合

PHONE_TYPE
電話番号の場合

SRC_IMAGE_ANCHOR_TYPE
HTMLのaタグで、imgタグを囲んでいる場合

UNKNOWN_TYPE
不明なターゲットの場合
これは、何もないところの長押しとか
通常のテキストの長押しの場合適用される

タイムラプス画像を動画へ変換

タイムラプス画像を動画へ変換

raspberry Pi で撮影した画像を動画変換するけど
処理に時間がかかるので
Ubuntu で行う

sudo apt-get install libav-tools 

で変換ツールをインストール

静止画から動画へ変換するには
avconvコマンドを使う

avconv -r 10 -i image-%04d.jpg -r 10 -vcodec libx264  -crf 29 -g 15 video.mp4

これを core i7 のCPUの Ubuntu でやったら
数秒で変換が終わった

なお変換したファイルは
Ubuntu なら VLC Media Player などで再生できる

avconv コマンドのオプションは
-r で一秒あたりのコマ数
通称フレームレートになる

今回は -r 10 にしたので
1秒間で10コマ進む

撮影するときに1分ごとに撮影しているので
10分を1秒で再生することになる

-i オプションでは変換するファイルの指定
-i image-%04d.jpg
としたので
image-0001.jpg から iamge-0061.jpg
までのファイルを指定している

Youtubeに timelapse で検索すると
いろいろでてくるので自分で挑戦して投稿するとおもしろいかもしれない

https://www.youtube.com/results?search_query=timelapse

で youtube の timelapse をみることができる

raspberry pi でタイムラプス撮影

raspberry pi でタイムラプス撮影

raspberry pi 専用カメラモジュールを使うことで
タイムラプス撮影を行える

今回使用した専用モジュールは
ラズベリーパイ カメラモジュール Camera Module for Raspberry Pi

なお、これだとカバーがないので、作成するか購入することになります

とりあえず
Raspberry Pi用カメラケース (Black)

を購入

タイムラプス撮影は
TVのCMとかで雲が流れる様子や一日の景色が
あっというまに変わっていくような映像のこと

よくみるのは朝日がでて
どんどん時間が流れて夜になるもの

これを行うには
一定間隔で撮影した写真を
つなぎ合わせて高速再生すればいい

raspberry pi で使う raspistill コマンドは
1枚の写真を撮影するコマンドだけど
-tl オプションを使うことで
このタイムラプス撮影が可能になる

タイムラプス撮影をするには、以下のオプションを使う

-o
ファイル名を指定
%d をつけることで通し番号で保存できる
さらに %04d とすれば
4桁の通し番号で保存できる

-tl
撮影間隔の指定
単位はミリ秒となる
1秒なら 1000ミリ秒
1分なら 60000ミリ秒
となる

-t
撮影時間の指定
単位はミリ
これも
1秒なら 1000ミリ秒
1分なら 60000ミリ秒

もし 640 x 480 pixel で1分おきに1時間撮影するなら

raspistill -o image-%04d.jpg -tl 60000 -t 3600000 -w 640 -h 480 

ミリ秒変換は面倒に思えるけど
一度秒単位にして 1000 をかければ算出しやすくなる

もし1時間おきに1週間撮影するなら

raspistill -o image-%04d.jpg -tl 3600000 -t 604800000 -w 640 -h 480 

となる

これで撮影できたけど
これを動画に変換する必要がある

変換に必要なツールはインストールできるけど
raspberry pi ではCPUが非力なので変換には時間がかかる

このため別の Linux マシンで行うほうが効率的

今回は Ubuntu 12.04 LTS に
FileZilla で撮影したファイル
image-0001.jpg から
image-0061.jpg までを
ダウンロード

これを変換することにする
時間がかなりかかる処理になりそうなので
変換作業は後日

端末のバックキーで前に戻るには

端末のバックキーで前に戻るには

端末のバックキーを検出するには
ActivityクラスのonBackPressed()を
Overrideする

そして、このメソッドのスーパークラスは呼ばないこと
これでアプリを終了せずに任意の操作ができる

よくブラウザでもとるキーを押したりして使うことになる

@Override
public void onBackPressed(){

if(mWebView.canGoBack()){
//前のページへ戻る
  mWebView.goBack();
}
else{
//アプリ終了
  super.onBackPressed();
}
}

今回は、WebViewクラスの
onGoBack()で履歴があるか調べ
有るなら前のページへ戻り

履歴がないなら、アプリ終了している

raspberry pi で動画撮影

raspberry pi で動画撮影

Raspberry pi 専用カメラモジュールを使うことで
1080pk
1920 x 1020 ピクセル
で動画を撮影できる

今回も使用したのは
ラズベリーパイ カメラモジュール Camera Module for Raspberry Pi

USB接続のカメラでも動画撮影できるけど
こっちだと 320 x 240 ピクセルぐらいでカクカクになる

動画撮影には
raspivid コマンドを使う

-o オプションで保存したいファイル名を指定する

.h264 拡張子で保存すればH.264 形式の動画ファイルになる

そして -t オプションで撮影する時間をミリ秒単位で指定する
1秒は 1000ミリ秒なので
10秒撮影したいのなら
-t 10000
となる

構文としては

raspivid -o 保存したいファイル名.h264 -t 撮影したいミリ秒

となる

コマンドの例としては

raspivid -o video.h264 -t 10000

これで video.h264 ファイルが作成される

撮影した動画を raspberry pi で再生するには
omxplayer コマンドを使う

これは標準でインストールされているので
そのまま使える

omxplayer 再生したい動画ファイル名
で再生できる

今回なら

omxplayer video.h264 

なお、これはディスプレイにHDMIで接続してあれば
リモートでも表示することができる

今回はSSHで ubuntu からログインして再生したけど
問題なく再生できた

H.264 形式の場合
Raspberry Pi のGPUに
H.264 再生支援機能があるのでなめらかに再生できる

ただ、標準で動画撮影すると
高解像度なため、10秒程度で20MBになってしまう

このため -w で幅 -h で高さを指定して
解像度を調整する

もし 320 x 320 の解像度にするなら

raspivid -o video.h264 -t 10000 -w 320 -h 320

また -b オプションでビットレートの設定ができる

指定する単位はビットなので
10MBits/s
なら
-b 1000000

50KBits/s
なら
-b 50000
となる

例を書くと

raspivid -o video.h264 -t 10000 -w 320 -h 320 -b 50000

ただし、ディスプレイに表示されるのは変換前の状態なので
変換した状態で表示したいのなら
-e オプションをつけて実行

raspivid -o video.h264 -t 10000 -w 320 -h 320 -b 50000 -e

raspberry pi のカメラモジュールでエフェクト機能実験

raspberry pi のカメラモジュールでエフェクト機能実験

前回カメラモジュールを購入したので
引き続きカメラ機能を実験

使用したのは
ラズベリーパイ カメラモジュール Camera Module for Raspberry Pi

本体は
Raspberry Pi Type B 512MB
を使用

raspistill コマンドを使うことでデジカメみたいに写真をとれる

raspistillコマンドは、さまざまなオプションがあり
目的に応じて様々な撮影条件を設定できる

ユニークなものとしてはエフェクト機能

エフェクトモードは20種類あり
-ifx オプションに続けてエフェクトモードを指定することで設定できる

エフェクトモードを水彩画みたいにして撮影するなら

 raspistill -o image.jpg -ifx watercolour

とする

なお、リモートでログインしているとその端末では見れないけど
HDMIケーブルとかでディスプレイに接続しておけば
プレビューをみることができる

HDMIケーブルについては
Amazon で安いのがあったので、これを利用

なお
raspistillコマンドには
露出モードを設定する -ex オプション
ホワイトバランスを設定する -awb オプション
測光モードを設定する -mm オプション
の設定が可能となっている

Webページの進捗状況の取得

Webページの進捗状況の取得

進捗状況がわからないと
フリーズしたと思われる

進捗状況の取得には
WebChromeClientクラスの
onProgressChangedハンドラを使う 

このメソッドをoverrideすることで進捗状況を取得できる

Webview..setWebChromeClient(new WebChromeClient(){

@Override
public void onProgressChanged(Webview view, int newProgress){
super.onProgressChanged(view, newProgress);

//行う処理

}
});

onProgressChanged()の引数は
WebView viewが
WebChromeClient()をセットしているWebView

int newProgressがWebページの進捗状況を表す0~100の数値
これは、パーセンテージを意味する

これで、進捗状況が取得できたので
画面に表示する

表示方法は2種類あり
進捗バーを使うか
進捗インジケータ、これは回転するアイコン
を使うことになる

まず、進捗バーの場合
この場合、レイアウトファイルに
ProgressBarを追加する


[/java]

次に表示する進捗インジケータの準備

進捗インジケータの表示には
ActivityクラスのsetProgressBardeterminateVisibility()を使う

このメソッドを使うには
Activityクラスの
setContentView()を使う前に
ActivityクラスのrequestWindowFeature()を使う必要がある

もし、それより後に実行すると
RuntimeException requestFeature() must be called before adding content
という例外が発生する

タイトルバーに進捗インジケータを表示するなら

@Override
public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

//タイトルバーへ進捗インジケータ表示
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

setContentView(R.layout.main);
}

というように、レイアウトファイル読み込みの前に記述する

そして、進捗インジケータや進捗バーは
ページ読み込み開始の時点では表示するけど
読み込んだら非表示にしておく

この方がWebページを広く使えるし見やすい
この表示、非表示を実現するには
WebViewClientの
onPageStartedハンドラと
onPageFinishedハンドラを使う

mWebView.setWebChromeClient(new WebChromeClient(){

@Override
public void onProgressChanged(WebView view, int newProgress){

super.lnProgressChanged(view, newProgress);

//進捗状況の取得
mProgressBar.setProgress(newProgress);
}
});

mWebView.setWebViewClient(new WebViewClient(){

@Override
public void onPageStarted(WebView view, String url, Bitmap favicon){
super.onPageStarted(view, url, favicon);

//ProgressBarの表示
mProgressBar.setVisibility(View.VISIBLE);

//進捗インジケータ表示
setProgressBarIndeterminateVisibility(true);

}


@Override
public void onPageFinished(WebView view, String url){
super.onPageFinished(view,url);

//ProgressBar非表示に
mProgressBar.setVisibility(View.GONE);
//進捗インジケータを非表示に
setProgressBar.IndeterminateVisibility(false);
}
});

ページ履歴の前後へ移動するには

ページ履歴の前後へ移動するには

WebViewは、ページ内のリンクをクリックすると次のページへ遷移する

遷移履歴をたどり、戻るなら
goBack()

進むなら
goForward()
を使う

履歴の取得には
WebViewクラスのcopyBackForwardList()を使う

webview.copyBackForwardList();
WebBackForwardList bfList = webview.copyBackForwardList();
WebHistoryItem item = bfList.getCurrentItem();
String title = item.getTitle();
String url = item
getUrl();

さらに、今見ているページ以外の前後の履歴の削除も可能
これは、 clearHistory()を使う

webview.clearHistory();

というように使う

残念なことに1つ前とかのように特定ページのみの削除ということはできない