通信
ネットワークプロトコル
- ソケットを使ったTCP/IP通信
- HTTPプロトコルを使った通信
TCP/IP通信
インターネット標準の通信
Socketクラス
java.net.Socketクラスを使用して通信する
Socketクラスを使用するには以下の2つの方法がある
- connectメソッドで指定した通信相手に接続する方法
Socketクラスを生成し、connectメソッドに接続先IPとポートを渡して接続する。
(InetSocketAddressクラスのインスタンス)
- コンストラクタで通信相手を指定する方法
Socketクラスを生成する際に、アドレスと、ポートを渡して接続する。
TCP/IP通信通信をするにはマニフェストファイルにandroid.permission.INTERNETを指定して
権限をもらう必要がある。
InputStreamクラス
データを受信するにはInputStreamクラスを用いる。
SocketクラスのgetInputStreamメソッドでInputStreamクラスのインスタンスを取得する。
得られたインスタンスのreadメソッドを利用して、byte配列に受信できる。
OutputStreamクラス
データを送信するにはOutputStreamクラスを用いる。
SocketクラスのgetOutputStreamメソッドでOutputStreamクラスのインスタンスを取得する。
得られたインスタンスのwriteメソッドを利用して、byte配列を送信できる。
最後にflushメソッドを使うことで、送信実施できる。
HTTP通信
以下の3つのクラスがある。
- org.apache.http.impl.client.DefaultHttpClient
- android.net.http.AndroidHttpClient
- java.net.HttpURLConnection
DefaultHttpClientクラス
org.apache.http.client.methodsのHttpGetクラスのインスタンスを生成する。引数としてリクエストしたいURLを渡しておく。
次にDefaultHttpClientのインスタンスを生成し、executeメソッドにっ最初に作ったHttpGetクラスのインスタンスを渡す。
レスポンスとして、HttpResponseクラスのインスタンスが返ってくる。
返ってきたHttpResponseクラスのインスタンスを利用して、リクエストに対する結果を判定できる。
POSTリクエストを行う場合はorg.apache.http.client.methods.HttpPostクラスを使用する。
AndroidHttpClientクラス
Androidに最適化されたHTTP通信を行うために用意されたもの。
- UIスレッドで使うことが禁じられている
- Cookieが使用できない
- コンテンツのgzip圧縮処理が追加されている
- リダイレクトが禁止されている
- Android2.2(APIレベル8)以降で導入されたクラス
AsyncTaskを使用するのが一般的
AndroidHttpClientクラスのインスタンスを生成するには、引数にUserAgent名を指定してnewInstanceメソッドを呼び出す。
HttpURLConnectionクラス
Java標準のクラス。
接続先のURLを指定してURLクラスのインスタンスを生成する。URLクラスのopenConnectionメソッドを呼び出して、HttpURLConnectionクラスのインスタンスを取得する。setRequestMethodメソッドでリクエストで使用するメソッド(GET, POST)を指定して、connectメソッドでリクエスト送信し、レスポンス取得が可能となる。
レスポンスからは、getResponseCodeメソッドでレスポンスコードが取得できる。
またgetInputStreamメソッドでInputStreamクラスのインスタンスが取得できデータを読み取れる。
取得後は、disconnectメソッドで切断する。
通信処理はメインスレッド(UIスレッド)では行わない
通信処理は時間がかかるのでUIスレッドでは実施しないこと。
5秒以上止まってしまうと、ANR(Android Not Responding)が発生してしまう場合がある。
Bluetooth
Android2.0(APIレベル5)以降で利用可能
Bluetoothのプロファイル
Bluetoothプロファイルとは、通信機器の種類によってプロトコルを標準化したもの
DUM | Bluetoothを通して、インターネットやダイヤルアップサービスにアクセスするためのプロファイル |
HID | キーボードやマウスなどの入力デバイス用 |
HSP | ワイヤレスホンやカーナビと接続し、ハンズフリー通話するためのもの |
OPP | 電話帳などのデータ送受信するためのプロファイル |
SPP | 仮想シリアルポートを設定し、それらを接続するためのプロファイル |
Bluetoothを有効にする
BluetoothAdapterクラスのgetDefaultAdapterメソッドを呼び出すことで、インスタンスを取得できる。
取得できない場合は端末がBluetoothをサポートしていないことを表す。
取得したインスタンスのisEnabledメソッドで有効になっているかどうかを調べることが出来る
有効にするには、ACTION_REQUEST_ENABLEをインテントのコンストラクタに指定して、インテントを生成し、
startActivityForResultメソッドを呼び出す。これによりBluetooth許可リクエストダイアログが表示される
ダイアログの結果はonActivityResultメソッドに返される。有効になった場合は、resultCodeにActivity.RESULT_OKが渡され、Bluetoothが有効にできなかった場合はActivity.RESULT_CANCELEDが渡される。
Bluetoothデバイスを検索する
BluetoothAdapterクラスのstartDiscoveryメソッドを呼び出すことで、検索を開始できる。
検索処理は非同期で実施される。見つかるとACTION_FOUNDのインテントに見つけたデバイスの
情報を含ませてブロードキャストするため。受け取るブロードキャストレシーバが必要となる。
ブロードキャストレシーバのonReceiveメソッドを実装する。
BluetoothDevice.EXTRA_DEVICEという名前でデバイスの情報を保持するBluetoothDeviceクラスのインスタンスが格納されている。
ペアリング済み Bluetoothデバイス一覧の取得
BluetoothAdapterクラスのgetBondedDevicesメソッドを呼び出すことで、ペアリング済みのデバイス情報のリストを取得できる
デバイスの接続と通信
クライアントとして特定のデバイスに接続をするためには、BluetoothDeviceクラスのインスタンスから、
BluetoothSocketクラスのインスタンスを生成し、connectメソッドによってサーバ側機器と接続する。
UUID(Univerally Unique Identifier: 汎用一意識別子)はプロファイルごとに決まった値を指定する必要がある。
接続後のデータは、BluetoothSocketクラスのインスタンスから、InputStreamとOutputStreamを取得して行うことが出来る。
リモートデバイスのデバイス検索に応答する
デバイスを他のデバイスから発見可能にしたい場合は、ACTION_REQUEST_DISCOVERABLEをインテントのコンストラクタに指定し、startActivityForResultメソッドを呼び出す。
これによりダイアログが表示され、許可することで言って時間応答できるようになる。
onActivityResultメソッドの引数resultCodeに最大応答時間の値が入っている。
リモートデバイスからの接続要求の受付をする
サーバ側で接続を受け付けるには、BluetoothServerSocketクラスを使用する。
BluetoothAdapterクラスのlistenUsingRfcommWithServiceRecordを呼び出すことで、BluetoothServerSocketクラスのインスタンスが取得できる。引数にはサービス名とプロファイルのUUIDを指定する。
接続要求の受付はacceptメソッドで行い、完了したらcloseメソッドで切断する。BluetoothSocketクラスの扱いと同じになる。
acceptメソッドの呼び出しは、接続受付か例外発生までブロックされるためUIスレッドとは別スレッドで実施する必要がある。
Bluetoothの利用許可
アプリケーションでBluetoothを操作するにはマニフェストファイルにandroid.permission.BLUETOOTHを指定する必要がある。Bluetoothの有効化/無効化やデバイス検索をするにはandroid.permission.BLUETOOTH_ADMINも必要となる。
Wi-Fi
Wi-Fi機能の有効化
android.net.wifiパッケージのWifiManagerクラスでWi-Fi機能を制御できる。WifiManagerクラスのsetWifiEnabledメソッドにより、Wi-Fi機能の有効/無効を切り替えることが出来る。
isWifiEnabledメソッドで、現在有効なのか無効なのかを調べることが出来る。
Wi-Fiアクセスポイントの探索
アクセスポイントの探索をするにはWiFiManagerクラスのstartScanメソッドを使う。結果はgetScanResultsメソッドにより取得できる。
探索終了時にはSCAN_RESULTS_AVAILABLE_ACTIONを持つインテントがブロードキャストされる。そのため結果を取得するにはこのインテントを受け取るブロードキャストレシーバを作成し、onReceiveメソッドでgetScanResultsメソッドを呼び出す。List<ScanResult>が返ってくるので取り出して使用できる。
ScanResultの内容
BBSID | 基本サービスセット識別子 |
SSID | 無線LANの識別子 |
capabilities | 暗号化情報 |
frequency | チャンネル周波数 |
level | 信号レベル |
Wi-Fiアクセスポイントへの接続
接続するためにはWifiConfigurationクラスのインスタンスにSSID(Service Set Identifier: 無線LANアクセスポイント識別子)やWEP(Wired Equivalent Privacy:無線LANで使われる共通鍵暗号方式)のキーを設定して、
addNetworkメソッドを呼び出すことで行える。
戻り値として、ネットワークIDが返されるのでこの値をenableNetworkメソッドの引数に渡すことで接続を有効にできる。saveConfigurationメソッドで接続した情報をシステムに保存できる。
Wi-Fi接続設定情報の取得
設置情報はWiFiManagerクラスのgetConfiguredNetworksメソッドで取得できる。
設定情報は複数あるのでWifiConfigurationが入ったListで返される。
Wifiの設定情報
BBSID | 基本サービスセット識別子 |
SSID | 無線LANの識別子 |
allowedAuthAlgorithms | サポートされる認証プロトコル |
allowedGroupCiphers | サポートされているGroup Cipher |
allowedKeyManagement | サポートされているキー管理 |
allowedPairwiseCiphers | サポートされているPairwise Cipher |
allowedProtocols | サポートされているセキュリティプロトコル |
hiddenSSID | ステルスモードを示すフラグ |
networkId | ネットワーク番号 |
preSharedKey | WPS-PSKの鍵 |
priority | 使用するアクセスポイントの優先度 |
status | ネットワークの状態 |
wepKeys | WEPキー |
wepTxKeyIndex | WEPキーのインデックス |
Wi-Fi接続情報の取得
接続中のWifi情報は、WifiManagerクラスのgetConnectionInfoメソッドで取得できる。
WiFiInfoクラスのインスタンスが返されるためgetterメソッドを値を参照できる
getBSSID | 基本サービスセット識別子 |
getHiddenSSID | ステルスモードを示すフラグ |
getIpAddress | IPアドレス |
getLinkSpeed | リンクスピード |
getMacAddress | MACアドレス |
getNetworkId | ネットワークID |
getRssi | 受信信号強度 |
getSSID | 無線LANの識別子 |
getSupplicantState | ネットワークとの接続ステータス |
Wi-Fiの利用許可
Wi-Fiの状態を取得するにはマニフェストファイルのandroid.permission.ACCESS_WIFI_STATEのパーミッションを設定
Wi-Fiの設定変更にはandroid.permission.CHANGE_WIFI_STATEのパーミッションを設定
##### WEPとは
無線LAN通信で使用される暗号化技術。すでに古いため、WPAやWPA2などのより強固なものが使用されることが多い。