WiFiServiceDiscovery – Android 4.1


20120329wifi_service_discovery_chat

Android 4.1 から Network Service Discovery がサポートされました。
マルチキャスト DNS をベースにした Service Discovery です。
Wifi 上にある Peer デバイスから提示されたサービスを見つけて接続します。
デバイスは、プリンタ、カメラ、メディア・プレイヤー、およびローカル・ネットワーク上で登録されているその他のものです。

サンプルコード

Android 4.2 の SDK の サンプルコードに WiFiServiceDiscovery が入りました。

Android 4.1 の端末が借りられたので、試してみました。
操作した感触では WiFiDirectDemo とさほど変わらないですね。

(1) 起動すると、通信可能なデバイスを検索します。
(2) 相手が見つかると、一覧に表示します。
(3) 相手に接続すると、チャットを開始できます。

20120329wifi_service_discovery_search20120329wifi_service_discovery_list20120329wifi_service_discovery_chat

Network Service Discovery の解説

公式サイトに解説が載っています。
Connecting Devices Wirelessly

(1) Network Service Discovery を使用する
自分のアプリにて、サービスを開始する方法を学習します。
ローカル・ネットワーク上であるサービスを発見します。
あなたが接続したいサービスに関して、詳細情報を得るために Network Service Discovery を使用します。

(2) Wi-Fi Direct で接続する
近くにある Peer デバイスの一覧を取得する方法を学習します、
レガシーデバイスのためにアクセス・ポイントを作ります、
および、Wi‐Fi Direct が可能なデバイスに接続します。

(3) Service Discovery のために Wi-Fi Direct を使用する
同じネットワーク上にないが、Peer デバイスによって公表されたサービスを、Wi-Fi Direct を使って発見する方法を学習します、

サンプルコードの解説

8つのソースがあります。

(1) WiFiServiceDiscoveryActivity.java
メインの Activity です。
起動すると、通信可能なデバイスを検索します。
相手が見つかると、一覧に表示します。
相手に接続すると、チャットを開始します。

(2) WiFiDirectServicesList.java
接続可能なデバイスの一覧を表示する Fragment です

(3) WiFiDirectBroadcastReceiver.java
wifi p2p events を受け取る BroadcastReceiver です。

(4) WiFiP2pService.java
サービスの情報を格納するコンテナです。

(5) GroupOwnerSocketHandler.java
ServerSocket を実行する Thread です。
wifi p2p group owner が使用します。

(6) WiFiChatFragment.java
チャットを表示する Fragment です。
メッセージをリスト形式で表示します。
Send ボタンでメッセージを送信します。

(7) ChatManager.java
チャットを実行する Runnable です。
ソケット・バッファーを介してメッセージのリードとライトを行います。

(8) ClientSocketHandler.java
ChatManager を実行する Thread です。


画像をドラック操作で移動する – FrameLayout


20130323image_move_sample_2

画像をドラック操作で移動するサンプルコードです。

FrameLayout の中に ImageView を置いた例です。
画像の移動は、View#layout を使用する。
ドラッグ操作は、View.OnTouchListener にて、判定する。

ソースコードは Google code に置いています。

関連
画像をドラック操作で移動する – Canvas
・画像をドラック操作で移動する – FrameLayout

参考
こんなに簡単だとは思わなかった!Viewのドラッグ方法 – kurukuru-papaの日記


画像をドラック操作で移動する – Canvas


20130322image_move_sample_1

画像をドラック操作で移動するサンプルコードです。

Canvas を使用した例です。
画像の表示は、View#onDraw にて、Canvas#drawBitmap を使用する。
ドラッグ操作は、View#onTouchEvent にて、判定する。

ソースコードは Google code に置いています。

関連
・画像をドラック操作で移動する – Canvas
画像をドラック操作で移動する – FrameLayout

参考
画像表示するAndroidアプリを作成する – TechFirm


ヨコハマ・アート・ガイド が NaviCon 連携アプリに掲載されました


20130302navicon

ヨコハマ・アート・ガイドどこでもPinQANaviCon 連携アプリに掲載されました。
NaviCon は、デンソーが提供している、スマホからカーナビの地図を操作したり、スマホで探した行き先をカーナビに転送するアプリです。

実は デンソー・スマートテック・アワード 2013 に応募するために、NaviCon に対応してみたのですが。
こちらは落選しました。(^^;

参考
デンソー・スマートテック・アワード 2013
「デンソー・スマートテック・アワード2013」の入賞作品の発表と表彰式を開催


ヨコハマ・アート・ガイド が いちGo!Go! に掲載されました


20130219ichigogo

ヨコハマ・アート・ガイドどこでもPinQA が いちGo!Go! に掲載されました。

いちGo!Go! は、アイラボさんが提供している、位置アプリの紹介サイトです。
身勝手ぐるめ も紹介して頂いています。


Toast のビューを変更する


20130318toast6

Toast#setView により、任意のレイアウトに変更することができます。

Toast の文字を大きくする では、標準のレイアウトを使って、文字を大きさだけを変更しました。
今度は、ドロイド君が付いた Toast を作成します。

ソースコードは google code にて公開しています。

参考
カスタムトーストビューの作成 − ソフトウェア技術ドキュメントを勝手に翻訳


Toast の表示位置を変更する


20130314toast5_normal 20130314toast5_center

Toast は、下3分の1くらいの位置に表示されます。
ソフトキーボードがあると、Toast と重なってしまい、見えにくいです。。

Toast#setGravity により、表示する位置を変更することができます。

ソースコードは google code にて公開しています。

参考
トーストの位置決め − ソフトウェア技術ドキュメントを勝手に翻訳


Toast の表示時間を変更する


結論からいうと、まじめに対応するのは断念しました。
代わりに Toast もどきのクラスを作って対応しました。

Toast のソースを読むと。
show() の中で INotificationManager#enqueueToast() を呼んでいます。
INotificationManager の実体は、 NotificationManagerService です。
この中で、Handler#sendMessageDelayed() を使って、表示時間を制御しています。
LENGTH_LONG ならば、3.5秒で、それ以外なら 2秒です。

表示時間を変更するには、NotificationManagerService を改造する必要があります。
NotificationManagerService は、システムに常駐しているサービスなので、いろいろ面倒です。
ということで、まじめに対応するのは断念しました。

代わりに Toast もどきのクラスを作って対応しました。
NotificationManagerService で行っている処理は、Toast のキュー管理と表示時間の制御です。
キュー管理は諦めて、表示時間の制御を行うクラスを作成しました。
Toast の表示と消去は、TN クラスで行っていますが、private になっているため、この部分も作成しました。

ソースコードは code.google にあります。

関連記事
Toast の移植
Toast が固まるのを回避する
Toast の文字を大きくする
・Toast の表示時間を変更する


Toast の文字を大きくする


20130311toast
上は標準の Toast (14sp)、下は今回のカスタマイズ (32sp)。

Toast の文字を大きくするには、
Toast#makeText に相当するクラスを作ることで対応できます。
ソースコードは code.google にあります。

Toast.java のソースを読むと。
文字の大きさは、makeText() の中で読み込まれるレイアウトファイル transient_notification で設定されている。
レイアウトファイルは さらに スタイル TextAppearance.Small を参照している。
文字の大きさは 14sp 固定です。

Toast の文字を大きくするのは、下記のようなコードにする。

使い方

// 32sp で表示する
MyToast.makeText( this, "abc", Toast.LENGTH_LONG, 32f ).show();

MyToast.java

public static Toast makeText( Context context, CharSequence text, int duration, float size ) {
	Toast result = new Toast( context );
	LayoutInflater inflate = (LayoutInflater)
		context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
	View v = inflate.inflate( R.layout.toast, null );
	TextView tv = (TextView) v.findViewById( R.id.message );
	tv.setText( text );       
	tv.setTextSize( size ); 
	result.setView( v );
	result.setDuration( duration );
	return result;
}

toast.xml

<TextView
	android:id="@+id/message"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:layout_weight="1"
	android:textColor="#ffffffff"			                                        
	android:textSize="14sp" // デフォルトの文字の大きさ
	android:shadowColor="#BB000000"
	android:shadowRadius="2.75" />

関連記事
Toast の移植
Toast が固まるのを回避する
・Toast の文字を大きくする
Toast の表示時間を変更する


Toast が固まるのを回避する


Toast は、キューに積まれています。
Toast を複数回実行すると、順番に表示されます。
ところが、連続する回数が多いと、Toast が消えなくなる (固まる) 現象を起こします。

これを回避するには、新しい Toast を実行する際には、前の Toast をキャンセルする必要があります。
AlarmClockToastMaster.java で実装されています。

Toast#cancel() の処理ですが、Android 1.6 (Donut) では、
表示を消すだけで、キューは残っています。
ということで、気休め程度の効果しかない感じです。

public void cancel() {
	mTN.hide();
	// TODO this still needs to cancel the inflight notification if any
}

Android 4.1 (Jelly Bean) から、キューを消す処理が入りました。
エミュレータで試すと、期待した動きをします。

public void cancel() {
	mTN.hide();
	try {
		getService().cancelToast(mContext.getPackageName(), mTN);
	} catch (RemoteException e) {
            // Empty
	}
}

サンプルコードは google code に置いています。

参考
Android Toastが固まるのを回避する方法 – Taosoftware

関連記事
Toast の移植
・Toast が固まるのを回避する
Toast の文字を大きくする
Toast の表示時間を変更する