My Photo

« July 2011 | Main | September 2011 »

August 30, 2011

Androidアプリ開発メモ015:タッチイベント

タッチイベントの処理

Activity または View の onTouchEvent() をオーバーライドしてタッチイベントの処理を行う。
View では上位の View の onTouchEvent() から順に呼ばれる。
Activity では View でタッチイベントが消費されなかった場合に呼ばれる。

onTouchEvent() はtrueを返すとイベントを消費したとみなされて他のコンポーネントにイベントは伝わらない。つまりそのイベントの処理はそのonTouchEvent()で終わりということになる。
falseを返すとほかのコンポーネントにもイベントは通知される。

ActivityとViewの両方でonTouchEvent()を下記のようにオーバーライドして実験した。
Activityの方はsuper.onTouchEvent()に委譲し、View#onTouchEvent() は true または false を返すようにハードコーディングした。
エミュレータでマウスをドラッグした場合の動きを、Viewの方の戻り値を変えて比較した。

View#onTouchEvent() が true を返す場合
View は DOWN、UP、MOVE のイベントを拾った。
Activity にはイベントが伝わらない。
View#onTouchEvent() が false を返す場合
View では DOWN イベントしか拾えなかった。
Activity は DOWN、UP、MOVE のイベントを拾った。
public boolean onTouchEvent(MotionEvent event) {
	// アクション種別とタッチ数の取得
	int action = event.getAction();
	int count = event.getPointerCount();
	
	// アクションインデックスとポインタIDの取得
	int index
		= (action & MotionEvent.ACTION_POINTER_ID_MASK)
			>> MotionEvent.ACTION_POINTER_ID_SHIFT;	// API LEVEL 5~7
//	int index = event.getActionIndex();	// API LVEL 8(Android 2.2)以降
	int pointerId = event.getPointerId(index);
	
	// タッチ位置の取得
	switch (action & MotionEvent.ACTION_MASK) {
	case MotionEvent.ACTION_DOWN:
	case MotionEvent.ACTION_POINTER_DOWN:
		Log.v("EV", "DOWN actindex:" + index + "  pid:" + pointerId);
		break;
	case MotionEvent.ACTION_UP:
	case MotionEvent.ACTION_POINTER_UP:
		Log.v("EV", "UP actindex:" + index + "  pid:" + pointerId);
		break;
	case MotionEvent.ACTION_MOVE:
		Log.v("EV", "MOVE actindex:" + index + "  pid:" + pointerId);
		break;
	default:
		Log.v("EV", "action=" + action + " actindex:" + index + "  pid:" + pointerId);
	}
	return true;
//	return false;
//	return super.onTouchEvent(event);	// Activityの方では元のonTouchEvent()を呼ぶ
}

MotionEvent

ポインタIDを得るにはアクションインデックスというものが必要。
本に
「アクションインデックスは「タッチ数-1」以下の整数で、同じ指でもタッチ数が変わると値が変わる可能性がある。」
とあったが?同じ指って同じタッチということ?システムがどの指かなんて識別できるないと思うのだが?。
1箇所タッチしていてさらに2箇所目をタッチした場合、1箇所目のタッチのポインタIDは変わらないがアクションインデックスは変わる可能性があるという意味か?

アクションインデックスを使えばほかにイベントを起こしているのとは別のタッチの位置も取れる。
MotionEventで引数なしのgetX()はそのイベントのX座標、アクションインデックスを引数に取るgetX()はそのアクションインデックスのタッチのX座標。

エミュレータで1箇所タッチした場合、アクションインデックスもポインタIDも0だった。

参考ページ:Androidでアプリ画面のタッチイベントを取得する方法 | Tech Booster

August 28, 2011

第24節、新潟完封負け、磐田は大宮に今期ホーム初勝利を献上

Jリーグタイムを視聴。


J's GOAL:試合詳細:2011 J1 第24節 サンフレッチェ広島 1-0 アルビレックス新潟


鈴木大輔が試合後のコメントで
「最後のところで粘り強く守れていた。そこはよかった」
って言ってる。
失点して負けたのにDFが「よかった」はないよなあ。

ヨンチョルは相変わらずなんだろうか。
シーズン開始当初、ヨンチョルは新潟のストロングポイントだったと思うのだが、いまじゃウィークポイントになってないか。
黒崎監督は調子が戻ってくるのを待ってるんだろうけど、ダメなら外す勇気を持って欲しい。

大宮に勝ち点で並ばれた。
ちょっと前までは今年は降格は心配しなくてもいいかなと思ってたが、そうも言ってられなくなってきたな。


J's GOAL:試合詳細:2011 J1 第24節 大宮アルディージャ 2-0 ジュビロ磐田


Jリーグタイムでこの試合、大宮の攻撃シーンしかなかった。
そんだけ大宮の方が良かったというか、磐田が悪かったってことか。
山崎に代えてしゅうとって、理解不能。攻撃的な選手はほかにいくらでもいるだろうに。
あの監督、なんでそんなにしゅうとに固執するんだろう。
育成能力はあるのかもしれんが、試合中での臨機応変な対応・選手交代に関しては最低レベルの監督だ。

西の復活だけが今節の唯一の救い。


仙台-山形戦で山形を中傷するダンマク出した奴ら、出入り禁止にしてくれ。
ドメサカ板まとめ見たけど、2chで事前予告して、止められたのに強行したらしい。
バカは死んでも直らないから、そういうのは見つけ次第、スタジアムから永久追放でいいと思う。

August 27, 2011

FF11 獣神印章99BC「戦慄の角」を4回

LSメンバーで黒帯を欲している人がいるので、ベヒーモスの舌を取るために一昨日1回、昨日3回やった。


初戦は2人で挑戦。おいらは白/赤。
敵を倒すと同時に最後のメテオで全滅したが、リレしていたので問題なし。
1回コンバートして、プロエーテル1回使ってMPはぎりぎりだった。
ベヒーモスの舌はドロップせず。


日を改めて金曜夜は6人PTでやった(実際は中の人は3人。アタッカーと白はそれぞれ一人で1キャラを操作、残りの4キャラは一人で4アカで操作)。
おいらのジョブは白/黒。サポ赤にするのを忘れていたが、詩人と赤がいるので大丈夫でしょうということでそのままに。
1回目は、最後のメテオの時にストンスキンがあったと思うのだけど、それでも白は死んでしまった。
戦闘自体は勝利。舌出た^^


2回目。おいらがテミスオーブをトレード。
やはり白は最後メテオで戦闘不能。
戦闘自体は勝利。またも舌出たが、他の人にゆずった。


ラストの3回目は、途中でおいらのMPが尽きたorz
でアタッカー死亡。
タゲはおいら(白)にあるようで、赤さんがバインド・グラビデしてマラソン。
BCの入り口の方で赤さんがベヒにバインドしておいらが折り返そうとしたが、ベヒの脇を通った瞬間にスタンさせられて、さらにメテオで戦闘不能。リレ切れていたorz
でも他のPTメンバーがなんとかマラソンを継続して、アタッカーの衰弱が直って、倒すことが出来た。
リレ切れは完全なミスだし、バインドになったときも素早く祝福使えばなんとでもなったのに。
まったくもって情けないorz
舌は、どうだったかな^^;


ドロップ品のうち特大獣肉は80万ギルでバザってたら外人が「500kにまけて」とtellしてきたのでその値段で売ってやった。
甘露の免罪符はどうしようか。店売りもバザーも出来ないし。


獣神99BCは初めてやった。
レベルキャップが解放された今ならまたやってもいいかな、と思ったが獣神印章を集めるのが大変だ^^;

FF11 CLタブレット+1をゲット

コーラー型紙:胴が@1だったので、今週はアビセア-グロベルグのクエ「ある娘の使命」を繰り返しやっていた。
そして昨日、召胴紙出たーヽ(´Д`)ノ
今日、納品してCLタブレット+1をゲット。
今まで使っていたオステアローブと比較するとこんな感じ。


オステアローブ 防29 CHR-2 召喚獣維持費-1 契約の履行使用間隔-3 Lv50~
CLタブレット+1 防47 MP+45 召喚魔法スキル+7 召喚獣維持費-3 召喚獣:契約の履行ダメージアップ Lv89~


履行間隔マイナスがない以外、CLタブレット+1が勝っている。
オステアローブは競売に5万ギルで出品したらすぐに売れた。
これで召喚士のエンピリアン装束は+1以上がそろった。

August 26, 2011

ちょっとした手術

かなり前からある小鼻のできものがだんだん大きくなってきたので、先日皮膚科に行ってきた。保険適用で1万円以内で取ることができるというので手術で取ってもらうことにした。
で、今日の午前中、手術した。
手術といっても入院するわけでもないし、局部麻酔してちょちょいと取るだけ。


最初に鼻に局部麻酔。歯科治療で使う麻酔と同じような感じだった。
それから患部以外を布で覆われた。何されているか見えなくなった。
「ジョギ、ジョギ、ジョギ」っと何かを切る音。
あとは何されてるかよくわからなくて、最後に縫っているような感じがした。
10分くらいで終了。


術後、お医者さんの説明によるとできものを全体を丸く取ったとのこと。
おいらは直線に切開して中身を取り出すような感じかと思ってたけど、ゴッソリ全部取ったのか。
抜糸は1週間後で、生検の結果はもう少し先と言われた。
#悪性腫瘍でしたとか言われたらどうしよう(;゚∀゚)
痛み止め、抗生物質、消毒薬を処方されて医院を出た。


薬の入手に少し手間取った。
最初によく利用する調剤薬局に行った。ここはこちらから言わなくても「ジェネリックありますがどうされますか?」って聞いてくる良心的な調剤薬局だ。
#今時ふつう?
処方箋を渡して待ってたら、しばらくして薬剤師が来て「0.05W/V%マスキン水」という消毒薬がないと言う。
用意できる薬局を探しますとのことだったが、結構待たされた。
で、消毒薬が用意できる薬局に行ってやっと薬が手に入った。
5分で済むと思ってたのに30分近くかかった^^;


今のところ痛みも全然ないし、こんな簡単な手術だったらもっと早く取ればよかったなあ。

August 25, 2011

寝つきはすごく悪い

ブログネタ: あなたは「寝つき」のいいほう?参加数


高校2年までは特に寝つきが悪いという意識はなかったが、高3になって、受験と家庭の問題のストレスからだろうか寝れなくなった。
床についても2時間とか3時間とか寝られない日々が続いた。


一人暮らしになってからも一時期眠れなくなって、心療内科で睡眠導入剤を処方してもらった。


今も薬を飲むほどではないが寝つきは悪い。
特に気になること、心配事があると布団に入っても1時間以上寝つけないことがある。
布団に入ってあっという間に寝ちゃう人(よゐこの濱口とか)、すごいうらやましい^^;

Androidアプリ開発メモ014:Intentその2

Intentについてもう少し詳しく。
ここに書いてあることを自分なりに理解して要約。自信ないけど。

Intentの配信

アクティビティに配信

  • Context.startActivity()
  • Activity.startActivityForResult()

サービスに配信

  • Context.startService()
  • Context.bindService()

ブロードキャストレシーバに配信

  • Context.sendBroadcast()
  • Context.sendOrderedBroadcast()
  • Context.sendStickyBroad

Intentに含まれる主な情報

コンポーネント名

  • Componentオブジェクト。Intentを受けとるコンポーネント名。
  • これが設定されているIntentを明示的オブジェクトと言う。

アクション

  • 動作の文字列名。アクティビティアクションとブロードキャストアクションがある。

データ

  • データのURIとMIMEタイプ。アクションと対になっていることが多い。

カテゴリ

  • Intentを受け取ることができるコンポーネントの種類の付加的な情報を表す文字列。

エクストラ
フラグ

明示的Intent・暗黙的Intent
明示的IntentはコンストラクタやsetComponent(),setClass()でコンポーネント名が設定されたIntentで、明示的Intentを付けてstartActivity()を実行すれば設定されたアクティビティが起動する。

Intent intent = new Intent(this, Activity1.class);
startActivity(intent);

暗黙的Intentは明示的IntentではないIntent。暗黙的Intentを付けてstartActivity()を実行した場合はシステムがIntentのアクション、データ、カテゴリーから適切なアクティビティを選択して起動する。
暗黙的Intentを使用したほうがコンポーネント間の結合が疎になる。

インテントフィルタ
アクティビティ、サービス、ブロードキャストレシーバがどのIntentを受け取るシステムに知らせる設定というかオブジェクトというか。
アクティビティの場合、AndroidManifest.xmlのactivity要素の子要素に設定する。

<activity android:name=".ActivityExample"
                  android:label="@string/app_name">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>

上記ではアクションにACTION_MAIN、カテゴリにCATEGORY_LAUNCHERが設定されている。アプリの最初のアクティビティにはこのインテントフィルタが必要だと思われる。

ACTION_MAIN:データ入力なしかつ出力の返却なしで、タスクの初期アクティビティとして開始する。
CATEGORY_LAUNCHER:タスクの初期アクティビティになれるまたはアプリケーションランチャーのトップレベルにリストされているアクティビティ。

2011/9/9追記:
インテントフィルタを持たないコンポーネントは明示インテントのみ受け取れる。
インテントフィルタを持つコンポーネントは明示・暗黙のどちらのインテントも受け取れる。

August 24, 2011

第23節、新潟スコアレスドロー、磐田は赤嶺にまたやられたけどなんとかドロー

Jリーグタイムを視聴。
今節は引き分けが多かったが、ガンバ、名古屋、横浜と勝ちきれる実力のあるチームが勝ったという印象。


J's GOAL:試合詳細:2011 J1 第23節 アルビレックス新潟 0-0 大宮アルディージャ


GKは東口が先発。ミシェウと高徳が控え。
無得点。うーん。負けなくて良かった。


J's GOAL:試合詳細:2011 J1 第23節 ジュビロ磐田 1-1 ベガルタ仙台


なんというか、赤嶺、本当にすごいな。磐田戦では。
しかしなんとか追いついてドロー。川口の奮闘がなければ負けてたんじゃないか。
駒野は相変わらず絶好調みたいだ。

WindowsXPの再インストール時の設定メモ

スタートメニューの設定
スタートメニューがデフォルトの(「クラシック」ではない)場合、[C:\Documents and Settings\アカウント名\スタートメニュー]にショートカットを置いても、スタートメニュー直下にショートカットが現れない。
スタートメニューフォルダにショートカットを作って(別の場所でも良いけど)、スタートメニューにショートカットをドロップすればよい。作ったショートカットは消してはいけない。


常駐ソフトを切る
「ファイル名を指定して実行」でmsconfigを実行して不要な常駐ソフトを切る。


DirectXのバージョンの確認
「ファイル名を指定して実行」でdxdiagで確認できる。

August 23, 2011

Androidアプリ開発メモ013:minSdkVersion、アプリのアンインストール

最低限必要なAPIレベルの設定
アプリに最低限必要なAPIレベルを設定しておくと、そのAPIレベル以下のシステムにインストールできなくなる。設定しておくべき。
例えばAndroid 2.0での新機能を使ったアプリであれば、AndroidManifest.xmlに以下のように記述しておけば、Android 1.6以下(APIレベル4未満)のシステムにはインストールできなくなる。

<uses-sdk android:minSdkVersion="5" />
バージョンAPI Level
1.53
1.64
2.05
2.0.16
2.17
2.28
2.39
2.3.310


AVDからアプリをアンインストール
AVDを操作して削除する方法の他に、コマンドプロンプトでadbを実行して削除することができる。
adbはtoolsではなくplatform-toolsフォルダにある。

adb uninstall <パッケージ名>
「クラス名」じゃなくて「パッケージ名」なので注意。

背の眼

帰省のときに電車内で読んだので感想を。


作者は京極夏彦をリスペクトしているらしいが、この作品は百鬼夜行シリーズに遠く及ばない。
巻末の選考委員の評によると、ホラーサスペンス大賞に応募したときは百鬼夜行シリーズを意識してか長大な作品だったが「無駄に長い」という評価で、この出版されたバージョンでは大幅にスリム化されたそうだ。
以下、ネタバレを含む。


殺人事件の真相については百鬼夜行シリーズまんまな感じがする。スーパーナチュラルな現象に見えることも、その実、人間が起こしているんだよと。
そしてタイトルにもなっている「背の眼」という現象は、心霊現象と断定されている。
えー。。。
その説明も「自殺しようとている人はすでに死者に近い存在だから霊が寄って来て心霊現象が起きる」なんて、なんかありきたりで説得力が薄い。


本格推理+ホラーということなんだろうけど、どちらの要素も残念な感じ。
京極夏彦や森博嗣、貴志祐介の作品をはじめて読んだときのような衝撃は全くなかった。


背の眼〈上〉 (幻冬舎文庫)背の眼〈上〉 (幻冬舎文庫)
道尾 秀介

幻冬舎 2007-10
売り上げランキング : 12976

Amazonで詳しく見る
by G-Tools

August 21, 2011

FF11 GTコート+1、GTペタソス+1をゲット

先週末と今週末、それぞれLSのメンバーがやっているNM戦に入れてもらって黒胴と黒頭の型紙がそろった。


先週やったのはアルテパのAmarok、だったと思う^^;


今週はWherwetrice。@1だったので1戦で合計8枚になった。
そろった後にトラップ強化クエやったら黒頭型紙が出たorz


そしてGTコート+1、GTペタソス+1をゲット。

GTペタソス+1 防27 INT+6 精霊魔法スキル+10 精霊魔法の詠唱時間-6% 敵対心-4 Lv85~ 黒
GTコート+1 防47 MP+35 魔法命中率+8 魔法攻撃力アップ+8 リフレシュ 精霊魔法の再詠唱間隔-6% Lv89~ 黒


これで黒のエンピリアン装束は+1以上がそろった^^

再インストール時のアプリケーションの設定メモ

Sleipnir
メニュー:ツール>Sleipnirオプション>クライアント>全般>「空白ページ」ボタン
メニュー:ツール>Sleipnirオプション>クライアント>起動>「起動時に前回終了時の状態を復元する」のチェックをはずす
メニュー:ツール>Sleipnirオプション>Dock>タブの追加と削除>「新しいタブの追加位置」で「常に最後」を選択


Atok
プロパティ(環境設定)>入力・変換>ATOKナビ>「カーソル位置に入力モードを表示」で「しない」を選択

3年ぶりくらい?WindowsXP再インストール

3年ぶりくらい?WindowsXP再インストール
ビデオカードを交換して以来、スタンバイができなくなって困っていた。
節電のために作業を中断するときはスタンバイにしたいのだが、できないので仕方なくシャットダウン。
シャットダウンだと戻ってきて作業再開するのに時間がかかる。


で、いい機会だし、この週末にWindowsXPの再インストールをした。
時間がかかったけど、スタンバイできるようになった。
アンインストールしたアプリケーションの残骸とかもなくなってすっきり。
やって良かった^^

August 16, 2011

ムーンライトえちご意外と空いていた

日曜日、だめかなと思いながら駅の窓口に行ったら月曜日のムーンライトが取れた。
で、ムーンライトで東京に戻ってきた。
乗車率は60%くらいな感じ。新幹線や高速道路はUターンで混雑した日なのに。
この前の大雨でお盆までに復旧するかどうかわからないからとキャンセルした人がいたのかもしれない。復旧が決まるまでは予約受付してなかった影響もあるかもしれない。でもこの乗車率の低さまずいのではないかと余計な心配をしてしまった。

自分の席は先頭車両右側の窓側。冷房が直撃して寒い。
持っていたTシャツをTシャツの上に着て(Tシャツ2枚重ね^^;)アルビのミニタオルを首に巻き(短くて1周しないけど)、さらに通路側の席が空いていたのでそちらに移動した。冷気の直撃は避けられるようになって大分マシになったが、まだ寒いことは寒い。
寒かったが、隣が空いているのでかなり眠ることができた。
#隣に人がいると気になって眠れない

自分には冷房が強すぎるように感じたが電車では細かく温度調整とかできないんだろうし、同じ温度にしても暑いと思う人もいれば寒いと思う人もいるから仕方ないのかな。
夜行に乗る時は念のために長袖シャツとタオル持っていった方がいいな。
#タオルはマフラーみたいに首に巻く。

キス釣り2011

月曜日、帰省中恒例の釣りに行ってきた。
いつもは2回行くのだが、今年は1回だけ。

朝5時半から近くの1級河川の河口へ。すでに結構釣りをしている人がいる。
もうちょっと早く行ってもよかったかも。というか、夜釣りで良かったかも。

今回は手抜きして力糸を付けずにナイロン4号の糸に25号のジェット天秤を付けた。
力一杯投げなければ大丈夫だろうと^^;

最初は河口のすぐ側で釣り始めたが、釣れない。
それに先日の大雨のせいだろうか、波打ち際に大量のゴミがあって非常に釣りづらい。
で、30分ほどで河口から少し離れところに移動。
するとポツリ、ポツリと釣れ始めた。

8時を過ぎに数十m移動したら、ぱったり釣れなくなった。動かなければ良かったorz
10時からはフグが釣れ始めるorz
11時過ぎに最後の1匹が釣れて、11時半に終了。
釣果はキス5匹、ヒイラギ4匹。
#と、フグ2匹。捨てたけど。
キスは小さいのばかりだったが、まあ数は自分にしては多く釣れたのでいいか。

釣りを終えて竿をしまおうと思ったら、竿のおしりにあるネジになっている部品がなくなっているのに気付いた。
いつ落としたのか気付かなかった。砂浜では探しようがない。
もう結構使ったから、この竿は今回で使用終了だ。
次からシーバスロッドでチョイ投げにしよう。どうせ投げ釣り専用竿でも50mしか飛ばないから。

あと、次回からはレンタル携帯電話を持っていこうと思う。
去年までは釣り場から少し歩けばPHSが繋がったが、今年はたまたまかもしれないが、なんかつながりが悪くなってた。
Fishing20110815


August 15, 2011

第21節、新潟は浦和が苦手らしい、磐田6得点大勝

J's GOAL:試合詳細:2011 J1 第21節 アルビレックス新潟 2-3 浦和レッズ


初めてビッグスワンに行ってきました。前半で帰ってきたが^^;
あまりにひどい内容に怒りの途中退席というわけではなく、最後まで見てると家に着くのが10時を過ぎてしまい、翌日の早朝からの釣りに響くので泣く泣く前半で戻ってきた。


前半だけの内容は、新潟いいところなし。
裏へのパスは長すぎたりカットされたり。
全体的に悪かったけど、特に左サイド、ヨンチョルと高徳の攻撃が良くなかった。ライン際を行かずに内に切れ込むな動きが多かったが、ことごとく止められていた。
ほかの人の感想で亜土夢をほめているのがあったが、そんなにほめらるような動きだったかな。シュートは枠内に行ってなかったし。


帰宅してスポーツニュースを見たら結果は2-3。よく2点返したなと思ったらPKか。
前半の内容から逆転は無理だと思ってたが、その通りだった。


あと、ビッグスワンの運営はあんまり良くない感じがした。
3万7千人というのは予想外だったのか、入場に20分くらいかかった。
それに暑さも考慮して、入場ゲートのもぎりの人を増やすとか開場時間を早めるとか何か対応して欲しかった。


J's GOAL:試合詳細:2011 J1 第21節 ジュビロ磐田 6-1 柏レイソル


スポーツニュースでゴールシーンだけ見た。
前田は欠場。新加入のロドリゴ・ソウトがボランチに入りしゅうとが右MF、那須が左サイドという新布陣。
結果はロドリゴ・ソウトが2得点の活躍。
金園も得点して9点目で得点ランキング2位タイ。
すばらしい勝利。6位浮上。ACL圏内は厳しいかもしれないが、ひとつでも上へ。
しかし欠場の前田は立場ないな^^;

August 14, 2011

ドタバタ帰省

昨日、実家に帰省した。
9時か10時くらいに出発する予定で、そのために7時起きるつもりだった。
しかし朝、起きたら10時^^;
バタバタと準備をして、1時過ぎに家を出た。
#目覚ましが鳴らなかったのは「午後7時」にセットしたからのような気がしてきた。今頃、アパートの部屋で目覚ましが延々と鳴り続けていたり。。。


上野で前橋行きの普通に乗車。大宮あたりまではそこそこ人が乗っていたが熊谷過ぎるとかなり人が減り、本庄過ぎるとガラガラ。
高崎で水上行きに乗り換え。途中、どの駅のあたりかは忘れたがパラグライダーやってるのが見えた。気持ちよさそう^^
高崎線の電車内は節電のためか冷房が弱くて暑かったが、上越線の水上行きは普通に冷房が効いていた。この違いはなぜだろう。


水上で1時間くらい電車待ち。さすがに平地と比べると涼しい、とまではいえないが過ごしやすい。ただ、駅の待合室にハエとか虫が結構飛んでた。電気蚊取りとか置いたほうが良いのでは。


5時40分くらいの長岡行きに乗る。
新潟県に入るとかなり激しい雨。先日の大雨のことを考えて少し不安になるが、雨は山沿いだけで長岡では月が見えていた。
長岡で新潟行きに乗り換えて、さらに新津、新発田で乗り換え、10時くらいに実家の最寄り駅に到着。


明るいうちに新潟県内に入っていつもと違うルート(弥彦線と越後線)に乗ったり、釣具店で買い物する予定を立てていたのだが、寝坊して全部パーになってしまった^^;

August 13, 2011

Androidアプリ開発メモ012:マルチアクティビティ、Intent

マルチアクティビティ

複数のアクティビティを使用する場合はAndroidManifest.xmlにそれぞれのアクティビティのactivity要素を記述する。最低限android:name属性とandroid:label属性を記述する。

新しいアクティビティを立ち上げるにはContext#startActivity()を使用する。
アクティビティの終了はActivity#finish()を使用する。

Intent

アクティビティのための情報を詰め込んだクラス。
アクティビティを開始する場合やアクティビティ間でデータをやり取りするときに使う。

Intent intent = new Intent(this, Activity1.class);
startActivity(intent);

アクティビティ間のデータのやりとり

親アクティビティから子アクティビティにデータを渡すには、親アクティビティではIntentにデータをセットして渡す。

Intent intent = new Intent(this, SubActivity.class);
intent.putExtra(PARAM_NAME, aEditText.getText().toString());
startActivity(intent);

子アクティビティでデータを受け取るにはActivity#getIntent()でIntentを取得し、geIntExtra()やgetStringExtra()などでIntentから取得する。

Intent intent = getIntent();
String s = intent.getStringExtra(PARAM_NAME);

子アクティビティから親アクティビティにデータを渡すには、親はActivityクラスのstartActivityForResult()で子を開始し、onActivityResult()をオーバーライドしてIntentから値を取り出す。

public void startActivityForResult(Intent intent, int requestCode)
requestCode:0以上。開始したアクティビティが終了したとき、onActivityResult()のrequestCodeの値になる。

protected void onActivityResult(int requestCode, int resultCode, Intent data)
requestCode:startActivityForResult()のrequestCode。この結果がどこから来たものか識別に使える。
resultCode:子アクティビティのsetResult()でセットした値

void test() {
	Intent intent = new Intent(this, SubActivity,class);
	startActivityForResult(intent, RETURN_CODE);
}

protected void onActivityResult(int returnCode, int resultCode, Intent intent) {
	String s = intent.getExtras().getString(RETURN_NAME);
	textView.setText(s);
}

子アクティビティはIntentに渡す値をセットし、setResult()を実行してからアクティビティを終了する。

Intent intent = getIntent();
String s = editText.getText().toString();
intent.putExtra(RETURN_NAME, s);
setResult(RESULT_OK, i);
finish();

アクションIntent

IntentにIntent.ACTION_XXXと関連するデータをセットしてアクティビティを起動すると、適切なアクティビティが選択されて起動する。

指定したURLを開く
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(<URL>));

Google検索
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, <検索キーワード>);

ダイアルする(Dial Activityに電話番号が入力されるところまでで、電話はかけない)
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + <電話番号>));

電話をかける
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + <電話番号>));

Google Maps
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("geo:<緯度>,<経度>?q=旗を立てる場所(地名or<緯度>,<経度>)&z=<ズーム指定>));

瀬川さんちとかわいそう

2chの将棋板をたまに見るのだが、最近、瀬川さんスレでの叩かれてようを見てちとかわいそうな気がしてきた。
#俺もこの前、「女流とお年寄りにしか勝ってない」とtwitterに書いた。ごめんなさい。


まあ編入試験の対戦相手に女流が入っていたのは私もどうかと思ったが。
成績に関してはこんなもんだろう。フリークラスから上がれないんじゃないかと予想してた人もいたし、C2に上がっただけで大したもんだ。
そもそも、当時の将棋連盟の理事さんたちもタイトルを取るような活躍を期待したわけではなく、知名度を生かして普及でがんばって欲しいと思っていたのだろう。
瀬川さんもそのあたりは十分わかっていて、各地に飛び回って指導をしているから忙しい。
それを「対局をおろそかにして講演ばっかりやってる」と批判されている。
講演もやってるけど、多くは指導だろう。この前北海道に行ったのも高校生に指導しに行ったんだし。
それに普及活動だってプロ棋士の立派な仕事だ。仕事をしてるんだから批判される筋合いはないと思う。


昨日は瀬川さんが竜王戦の6組昇級者決定戦で田丸八段に勝利。久しぶりの勝ちだ。
でも一番大事なのは順位戦だ。なんとか降級点は回避を。
がんばれ瀬川四段。

August 07, 2011

Androidアプリ開発メモ011:SQLiteの利用

SQLiteの利用

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
 
public class SQLiteSimpleExample2 extends Activity {
  
//  private static final String DATABASE_NAME = "kishi.db";
  private static final int DB_VERSION = 1;
  private static final String TABLE_NAME = "kishiData";
  public static final String KISHI_ID = "kishiId";
  public static final String NAME = "name";
  public static final String WIN = "win";
  public static final String LOSE = "lose";
  private KishiData players;
  
  private TextView aTextView;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    aTextView = (TextView)findViewById(R.id.myTextView);
    
    // DB作成
    players = new KishiData(this);
    
    // データをdeleteで削除
    SQLiteDatabase sqlwdb = players.getWritableDatabase();
    int numDelete = sqlwdb.delete(
        TABLE_NAME,
        NAME + " = ? OR " + KISHI_ID + " = ?",
        new String[] { "T.Kubo", "235" });
    Log.v("db", "number of delete = " + numDelete);
    
    // データをselectで取得
    String[] columns = { "_id", KISHI_ID, NAME, WIN, LOSE };
    SQLiteDatabase sqlrdb = players.getReadableDatabase();
    Cursor cursor = sqlrdb.query(
        TABLE_NAME, columns,
        NAME + "=" + "'Y.Habu'",
        null, null, null, null);
    Log.v("db", "number of rows = " + cursor.getCount());
    if (cursor.getCount() != 0) {
      cursor.moveToFirst();
      aTextView.setText(
          cursor.getString(1) + ","
          + cursor.getString(2) + ","
          + cursor.getInt(3) + ","
          + cursor.getInt(4));
    } else {
      aTextView.setText("no data to display");
    }
  }
  
  public class KishiData extends SQLiteOpenHelper {
    public KishiData(Context context) {
//    super(context, DATABASE_NAME, null, DB_VERSION);
      super(context, null, null, DB_VERSION);
    }
    
    @Override
    public void onCreate(SQLiteDatabase db) {
      
      // テーブル作成
      db.execSQL(
          "CREATE TABLE " + TABLE_NAME
          + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
          + KISHI_ID + " TEXT, "
          + NAME + " TEXT, "
          + WIN + " INTEGER, "
          + LOSE + " INTEGER);");
      
      ContentValues cv = new ContentValues(4);
      
      // 初期データをINSERTで作成
      cv.put(KISHI_ID, "175");
      cv.put(NAME, "Y.Habu");
      cv.put(WIN, 1);
      cv.put(LOSE, 0);
      db.insert(TABLE_NAME, null, cv);
      
      cv.put(KISHI_ID, "235");
      cv.put(NAME, "A.Watanabe");
      cv.put(WIN, 1);
      cv.put(LOSE, 0);
      db.insert(TABLE_NAME, null, cv);
      
      cv.put(KISHI_ID, "207");
      cv.put(NAME, "T.Kubo");
      cv.put(WIN, 0);
      cv.put(LOSE, 1);
      db.insert(TABLE_NAME, null, cv);
    }
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
  }
}

SQLiteOpenHelperを使用してDBを作成する

public SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
context:コンテキスト(?)
name:データベースファイルの名前。nullの場合はインメモリーデータベース。
factory:カーソルオブジェクト作成に使われるfactory(?)。nullの場合はデフォルト
version:データベースのバージョンナンバー(1から始まる)。

android.database.sqlite.SQLiteDatabaseのメソッド

public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
columns:取得するカラムのカラム名の配列
selections:where句。値にピリオドを含む場合はシングルクウォーテーションで歓呼でおいたほうが良い。たとえば "version=3.3.1"はエラーではエラーになるので、"version='3.3.1'"とする。ピリオドってSQLで特別な意味を持ってたっけ?
selectionArgs:selectionsに'?'を含む場合の引数
public long insert(String table, String nullColumnHack, ContentValues values)
nullColumnHack:普通はnullでよい。nullじゃない場合、not nullなところの値がnullだったら"NULL"という値を入れる(?)(全く自信なし)。

public int delete(String table, String whereClause, String[] whereArgs) whereClauseとwhereArgsは query() のselectionsとselectionArgsと同じ。 以下の2つは同じ結果になる。

delete(tableName,"NAME=?", new String[] {"Taro"});
delete(tableName,"NAME='Taro'", null);

public int update(String table, ContentValues values, String whereClause, String[] whereArgs)

第20節、新潟ホームで大勝

J's GOAL:試合詳細:2011 J1 第20節 アルビレックス新潟 4-0 清水エスパルス


3連勝^^/
ホームのサポは最高だよな。こういう試合は。
菊地が後半20分に交代してるけどケガ?足つったとかならいいんだけど。
新戦力アンデルソンはプレースキックがかなりいいみたいね。楽しみだわ。
しかし、清水は3戦続けて0-4で敗戦って、守備崩壊だ^^;


福岡と甲府が監督を変えたけど、後任がヘッドコーチとGMって、意味あるのかねえ。
成績低迷の原因は戦力不足なんだから、頭をすげ替えてもよくなるとは思えないんだが。
監督変えて残留に成功したのって、内山→オフトのジュビロ(2008年)くらいしか記憶にないんだけど。
#ただし2008シーズンは入れ替え戦があったから、今のルールだったら降格だけどね。

August 06, 2011

どうやって帰ろうか

上越線の越後湯沢~六日町の運転再開は8月中旬の予定と新潟支社のサイトに載っていた。中旬って、13日には間に合わないな。でもバスで代行輸送は始まった。
帰省のルートは中央本線から長野、糸魚川、柏崎と迂回することも考えたけど12時間かかる。代行輸送のバス使っても上越線経由の方がずっと早そうだ。
ということで、いつもの高崎・越後湯沢・長岡経由で帰ることに決定。代行輸送のバスに一度乗ってみたいというのもある。
それと、長岡から新潟は信越線1本ではなく、東三条で弥彦線に乗り換えて吉田から越後線で新潟に向かうことにする。
燕三条の上州屋でアオイソメ買いたいから。帰省ルート上で、駅前にあって生き餌を売っている釣具屋が上州屋の燕三条店しかなかった。
本間釣具店の竹尾IC店は東新潟駅から歩いて行けないことはないが、駅前とはとても言えないし。

Androidアプリ開発メモ010:プリファレンス、ファイルアクセス

アプリケーションの設定などをローカルに保存、参照できる。プリファレンスの実体はXMLファイル。
SharedPreferenceのインスタンスをContext#getSharedPreferences()で取得して使用する。
プリファレンスには名前があり、プリファレンスはキーと値の組み合わせを複数保持する。

android.content.Contextクラス
public abstract SharedPreferences getSharedPreferences(String name, int mode)
名前とモードを指定してプリファレンスを取得する。
引数:
  name  プリファレンスの名前
  mode  MODE_PRIVATE:このアプリからだけ読み書きできる
        MODE_WORLD_READABLE:他のアプリから読める
        MODE_WORLD_WRITEABLE:他のアプリが書き込める

値の変更にはSharedPreferences.Editorを使用する。インスタンスはSharedPreferences#edit()で取得する。
Editorに対してputXXX()で値を設定する。また値をすべて削除するにはclear()を使用する。
変更をcommit()でコミットする。
android.content.SharedPreferencesクラス
public abstract SharedPreferences.Editor edit()
新しいEditorを生成する。

android.content.SharedPreferences.Editorクラス
public abstract SharedPreferences.Editor putXXX(String key, データ型 value)
「XXX」の部分はBoolean,Int,Long,Float,String。
「データ型」はboolean,int,long,float,String。

android.content.SharedPreferences.Editorクラス
public abstract SharedPreferences.Editor clear()
プリファレンスからすべての値を削除する。

値の取得はSharedPreferences#getXXX()を使う。
android.content.SharedPreferencesクラス
データ型 getXXX(String key, データ型 defValue)
「データ型」はboolean,int,long,float,String。
「XXX」の部分はBoolean,Int,Long,Float,String。

値の設定、取得のサンプルコード。
private void setIntValue(int value) {
  SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
  SharedPreferences.Editor editor = prefs.edit();
  editor.putInt(MY_KEY, value);
  editor.commit();
}

private int getIntValue() {
  SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
  return prefs.getInt(MY_KEY, DEF_VALUE_INT);
}

ファイルアクセス

Androidはローカルのストレージに対するアクセスに制限があり、アプリごとに決まったフォルダ
/data/data/<アプリのパッケージ名>/files
にのみアクセスできる。このフォルダにあるファイル(リファレンスでは"private file associated with this Context's application package"とある)にファイルの場所を意識せずアクセスするために、ContextクラスのopenFileInput()、openFileOutput()などが用意されている。
#Activityで実際に利用するのはandroid.content.ContextWrapperの実装。

public FileInputStream openFileInput(String name)
読み込み用にファイルをオープンする。
引数:
  name  ファイル名。パスセパレータを含むことはできない。
戻り値:
  "/data/data/<アプリのパッケージ名>/files/<name>"への入力ストリーム

public abstract FileOutputStream openFileOutput (String name, int mode)
書き込み用にファイルをオープンする。
引数:
  name  ファイル名。パスセパレータを含むことはできない。
  mode  MODE_PRIVATE。デフォルト。
    MODE_APPEND
    MODE_WORLD_READABLE
    MODE_WORLD_WRITEABLE
戻り値:
  "/data/data/<アプリのパッケージ名>/files/<name>"への出力ストリーム

public boolean deleteFile(String name)
ファイルを削除する。
引数:
  name  ファイル名。パスセパレータを含むことはできない。
戻り値:
  削除に成功した場合true

public String[] fileList()
ファイル名の配列を取得する。

ファイルの読み書きのサンプル。
private void readFile(String filename) {
  FileInputStream fip;
  String text;
  try {
    fip = openFileInput(filename);
    byte[] buf = new byte[fip.available()];
    fip.read(buf);
    fip.close();
    text = new String(buf);
  } catch (FileNotFoundException e) {
  } catch (IOException e) {
  }
  editText.setText(text);
}

private void writeFile(String filename) {
  FileOutputStream fos;
  try {
    fos = openFileOutput(filename, MODE_PRIVATE);
    fos.write(editText.getText().toString().getBytes());
    fos.close();
  } catch (FileNotFoundException e) {
  } catch (IOException e) {
  }
}

参考:データを簡単に保存する方法(ファイル入出力編) << Tech Booster

August 05, 2011

Androidアプリ開発メモ009:Google Mapsの利用

2011/09/28更新
2011/09/29追記
2012/06/03追記

GoogleMapsの利用の準備

Google Maps APIキーを取得して、レイアウトファイルを使用する場合はレイアウトファイルに記述する。レイアウトファイルを使用しない場合はソースコード中でMapViewのコンストラクタに引数でAPIキーを渡す。
Gogole Mapsライブラリは外部ライブラリなのでAndroidManifest.xmlにインターネット接続の許可に加え、下記のようにapplication要素の子要素としてGogole Mapsライブラリの使用宣言をする必要がある。

<uses-library android:name="com.google.android.maps" />

Google Mapsライブラリのパッケージは com.google.android.maps
Google MapsライブラリのAPIリファレンスは
<android sdkのフォルダ>/add-ons/addon-google_apis-google_inc_-<APIバージョン>/doc/reference
にある。

MapView

GoogleMapを表示するView。

public GeoPoint getMapCenter()
地図の中央の位置をGeoPointで返す。

GeoPointは緯度・経度を10の6乗した整数のペアを持つ。例えば東京駅あたりを示すGeoPointのインスタンスは(35681381,139766083)を持つ。

public void setBuiltInZoomControls(boolean on)
on:trueの場合、地図の拡大・縮小ができるようになる。
public MapController getController()
MapControllerを取得する。

MapControllerについては後述。

MapActivity

MapViewを利用する場合、アクティビティはActivityではなくMapActivityを拡張して実装する。

protected abstract boolean isRouteDisplayed()
経路情報を表示しているかどうかを示す。とりあえずfalseを返すように実装しておけばいい?

位置情報取得の準備

アプリが位置情報を得ることができるようにするには、AndroidManifest.xmlのmanifest要素の子要素に以下を追加する。

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

1行目は無線ネットーワークの基地局から大まかな位置情報の取得を許可する。
2行目はGPSからの位置情報の取得を許可する。

MapController

地図を移動したり縮尺を変更したりする機能を持つクラス。

public int setZoom(int zoomLevel)
zoomLevel:1~21で、1つ数字が大きくなるごとに2倍拡大。
ズームレベルを指定する。

下記はWVGAのAVDにおいてズームレベル9,11,13,15に設定したときのMapViewの表示。
Zoom09_2 Zoom11_2 Zoom13_2 Zoom15_2

public void setCenter(GeoPoint point)
地図を指定した場所に移動する。
public void animateTo(GeoPoint point)
地図を指定した場所にアニメーションする。
public boolean zoomIn()
1段階ズームインする。
public boolean zoomOut()
1段階ズームアウトする。

MyLocationOverlay

現在位置を地図に表示するためのクラス。
MapViewとContextを渡して生成する。

public boolean enableMyLocation()
GPSから現在位置を取得できるようにする。
戻り値:成功した場合true。
public boolean enableCompass()
コンパスからの情報を取得できるようにする。
戻り値:成功した場合true。
public boolean runOnFirstFix(java.lang.Runnable runnable)
位置情報が更新されたときに呼び出されるRunnableのインスタンスを設定する。

以下のように位置情報更新時の処理を実装する(thisはMapActivityのサブクラス)。

// オーバーレイの生成
MyLocationOverlay overlay = new MyLocationOverlay(this, mapView);

// オーバーレイにRunnableオブジェクトを設定する
overlay.runOnFirstFix(new Runnable() {
  public void run() {
    // ここに位置情報更新時の処理を記述
  }
});

LocationManger

Google MapsライブラリではなくAndroid SDKの標準ライブラリのクラス。パッケージはandroid.location。
ロケーションマネージャを使用すれば位置情報の提供元(Provider)、取得間隔を指定して、現在位置が更新された際の処理を指定できる。
LocationManager や LocationListener は位置情報を扱うクラスであるが地図と直接関係はない。現在位置が変わったときに地図に関する処理を行わず位置情報を保存したり、位置情報から何かを計算するといったことできる。もちろん、リスナー内でGoogle MapsのAPIで地図に関する処理を呼ぶこともできるが、それはGoogle Mapsの機能であって LocationManager や LocationListener の機能ではない。

public void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)
名づけられたプロバイダによって定期的に通知されるカレントアクティビティを通知する(?)。なんのこっちゃ?
ようは位置情報通知の開始。
provider:位置情報の提供元(電波とかGPSとか)
minTime:通知のための最小時間間隔。最低限これくらいの間隔を空けて位置情報を更新しますよ、ということ。
minDistance:通知のための最小距離間隔。ここで指定した値動いたら位置情報を通知されますよ、ということ。
listener:位置情報リスナー

minTimeとminDistanceは大きい値を設定すればバッテリーの節約になるかもしれない。minTimeが十分長ければ位置情報取得から次取得までの間GPSがOFFになるとか。しかし必ずしも設定どおりに動く訳ではないようだ。頻繁に位置情報を更新したければどちらも0を設定すればよい。

public void removeUpdates(LocationListener listener)
どんなカレントの登録も削除する、カレントアクティビティの位置情報更新のための、与えられた位置情報リスナによる。
ようは位置情報通知を停止する。

LocationListenerのメソッド。

public void onLocationChanged(Location location)
位置変更時に呼ばれる。

public void onProviderEnabled(String provider)
ユーザによってプロバイダがenableにされた時に呼ばれる。

public void onProviderDisabled(String provider)
ユーザによってプロバイダがdisableにされた時に呼ばれる。

public void onStatusChanged(String provider, int status, Bundle extras)
プロバイダのステータスが変わったときに呼ばれる。

実装

protected void onStart() {
  super.onStart();
  
  // ロケーションマネージャの設定
  locationManger = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
  locationManger.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); // GPSの場合
  //locationManger.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); // 網の場合
}

protected void onStop() {
  super.onStop();
  
  // ロケーションマネージャの設定
  locationManger.removeUpdates(this);
}

public void onLocationChanged(Location location) {
  Log.v("TEST", "onLocationChanged() called.");
  // 緯度と経度の取得
  GeoPoint pos = new GeoPoint(
      (int)(location.getLatitude() * 1E6),
      (int)(location.getLongitude() * 1E6));
  mapCtrl.setCenter(pos);
}

public void onProviderEnabled(String provider) {
}

public void onProviderDisabled(String provider) {
}

public void onStatusChanged(String provider, int status, Bundle extras) {
}

参考ページ:
com.google.android.mapsパッケージのAPIリファレンスの在り処 | mucchinのAndroid戦記
地図アプリの作成-Android版その2 | SpiriteK Blog

August 03, 2011

上越線の被害はかなり大きい

JR東日本の新潟支社のサイトに先日の大雨による被害をふまえた運行情報が載っていた。
越後湯沢~六日町は8/4以降はバスの代行運転。ネットで調べたら、線路だけじゃなくて変電施設も被害を受けたらしい。


災害情報:平成23年7月新潟・福島豪雨の被害状況等について - 国土交通省


これはお盆までに復旧しそうにないか?
もう青春18きっぷ買ってしまった。早まった。
磐越西線も線路の盛り土が流れたっぽいけど、復旧までどれくらいかかるんだか。
困りましたな。

PSP故障した

UMDが読めなくなったorz
ごく稀に読み込めることもあるけど。
メモリースティックに入っているゲームはできるが、UMDのゲームがプレイできない。一番やるゲームがUMDのもじぴったんなのに。
修理に出すと基板総取っ替えで1万円くらい取られそうだし。
帰省時の電車の中というPSPが一番活躍する時期が近づいているのに、どうしたもんかなー。

Androidアプリ開発メモ008:WebView

インターネットへ接続の許可
AndroidManifest.xmlのmanifest要素の下に以下の記述をする。

<uses-permission android:name="android.permission.INTERNET" />


WebView
webページを表示するためのビュー。
自分のプログラムのバグかもしれないが、WebViewを使っていると一部の(というかかなりの)キーイベントがonKeyDown()とonKeyUp()で拾えない。dispatchKeyEvent()では拾えるのだが。なぜだろう。

拾える:KEYCODE_BACK,KEYCODE_MENU,KEYCODE_VOLUME_UP,KEYCODE_VOLUME_DOWN
拾えたり拾えなかったり:KEYCODE_DPAD_CENTER,KEYCODE_DPAD_UP,KEYCODE_DPAD_DOWN,KEYCODE_DPAD_RIGHT,KEYCODE_DPAD_LEFT
拾えない:KEYCODE_0,KEYCODE_A,KEYCODE_ENTER,KEYCODE_SPACE,KEYCODE_ALT_RIGHT,KEYCODE_ALT_LEFT

KEYCODE_DPAD_○○は、WebViewの画面が反応する(スクロールする、選択しているリンクが移動するなど)の場合は拾えないが、反応しない場合は拾える。ただし、CENTERとLEFTは画面に何も変化がないのに拾えない。
反応するのはMENUやBACKなど多くの機種についているキーで、QWERTYキーボードのキーには反応しない。


WebViewでリンク先をWebView自身に表示する方法
デフォルトではWebViewで表示しているページのリンクをクリックすると標準ブラウザが起動し標準ブラウザにリンク先のページが表示される。
リンク先をWebView自身に表示するには、WebView#setWebViewClient()でWebViewClientを設定すればよい。
本ではshouldOverrideUrlLoading()をオーバーライドしたWebViewClientのサブクラスを作り、WebViewにセットしているが、WebViewClientをそのまま使っても自身でリンク先を表示するようになる。


WebViewClient
WebViewのWebクライアントとしての動作を変えるためにあるクラスらしい。
public boolean shouldOverrideUrlLoading (WebView view, String url)
#全く自信のない訳
ホストアプリケーションに、カレントのWebViewに新しいURLが今まさにロードされるときにコントロールを引き継ぐチャンスを与える。
WebViewClientが提供されていない場合、デフォルトでは、WebViewは、URLの適切なハンドラを選択する("選択することを"?)アクティビティマネージャに("を"?)要求します。
WebViewClientが提供されている場合、trueを返すことはホストアプリケーションがURLをハンドルすることを意味し、一方、falseを返すことはカレントのWebViewがURLをハンドルすることを意味する。

« July 2011 | Main | September 2011 »

April 2017
Sun Mon Tue Wed Thu Fri Sat
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            
無料ブログはココログ

日本blog村

  • にほんブログ村 IT技術ブログへ
  • にほんブログ村 アニメブログへ
  • にほんブログ村 サッカーブログ アルビレックス新潟へ

好きな音楽家

メモ

XI-Prof