「RN-42Bluetoothモジュールの使い方1」の続きです。
今回はアンドロイドタブレットとBluetooth通信をしてみたいと思います。
RN-42BluetoothモジュールをつなげたPCをマスター、タブレットをスレーブとして、両者間でSPP(Serial Port Profile)による無線通信を行います。
SSP通信を使って、タブレットからPCのマウスを遠隔操作できるようにしてみます。
アンドロイドのプログラム
スレーブ側の実装をしていきます。
アンドロイドでBluetoothを使う場合は、
・パーミッションの追加
・BluetoothDeviceの取得
・BluetoothSocketを開いて入出力ストリームを取得
・入出力ストリームを使って通信
を行います。
#今回はデバイスの探索とかは対応しないことにする
パーミッションの設定
AndroidManifest.xmlに2つのパーミッションを追加
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
BluetoothDeveceの取得
今回はペアリング済みのデバイスを使用するようにします。
(事前にアンドロイド端末上でペアリング操作を行っておく必要があります)
private void connectServer() { mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); BluetoothDevice selected = null; if (pairedDevices.size() > 0) { for (BluetoothDevice device : pairedDevices) { //TODO:ペアリング済み&デバイスは1つ以外は対応しない selected = device; } mConnection = new BtClientConnection(selected); mConnection.start(); } else { Toast.makeText(this, "端末がありません", Toast.LENGTH_SHORT).show(); } }
2行目:BluetoothAdapter.getDefaultAdapter()でスマホ端末のBluetoothにアクセスするためのハンドラを取得しています。
3行目:getBondedDevices()でペアリング済みのデバイスを取得します。
(複数取得できるため、通常その中から選択する処理が必要になりますが、今回は簡単にするため対応しない)
12-13行目:選択したデバイスに対しソケットを開く処理を実行します
BluetoothSocketを開く
次はソケットを開いて入出力ストリームを取得するまでです。
この一連の処理を1つのクラスに突っ込んで実装してみました。
public class BtClientConnection extends Thread { private final BluetoothSocket mSocket; private final BluetoothDevice mDevice; private final OutputStream mOutput; private enum State{CONNECT, CONNECTED, DISCONNECT}; private State mState; public BtClientConnection(BluetoothDevice device) { mDevice = device; BluetoothSocket socket = null; OutputStream out = null; try { socket = mDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); out = socket.getOutputStream(); } catch (Exception e) { e.printStackTrace(); } mSocket = socket; mOutput = out; mState = State.CONNECT; } public void run() { Log.d("LOG", "Client start"); if (mSocket == null) return; while (true) { switch (mState) { case CONNECT: try { mSocket.connect(); } catch (IOException e) { e.printStackTrace(); mState = State.DISCONNECT; return; } mState = State.CONNECTED; Log.d("LOG", "Connected!"); break; case CONNECTED: break; case DISCONNECT: if (mSocket != null) { try { mOutput.write('E'); TimeUnit.MILLISECONDS.sleep(100); mSocket.close(); Log.d("LOG", "Disconnected"); } catch (Exception e) { e.printStackTrace(); } } return; } } } public void send(byte sendData[]) { if (!mState.equals(State.CONNECTED)) return; try { mOutput.write(sendData); } catch (Exception e) { e.printStackTrace(); } } public void disconnect() { mState = State.DISCONNECT; } }
16行目:ソケットを作成しています。UUIDはSPP用IDを使用しています。
アンドロイドアプリ同士で通信を行う場合は、独自のUUIDを作る必要があるみたいですね。リファレンス
入出力ストリームを使って通信
あとは、上記64-81行目のsend()メソッドを使用して、データを送信するだけです。
今回はスレーブからは送信しか行っていませんが、OutputStream同様にInputStreamを用意すれば受信もできます。
以上です。
動作テスト
RN42モジュールをマスターとして動作させるため、コマンドモードで次のように設定します(デフォルト設定でもOK)。
SM,4 //Auto-Connect DTR Mode S~,0 //SPP R,1 //Reboot!
アンドロイド端末から何か文字を送って、TeraTermに表示されれば完成です。
あとがき
今回はBlutetoothモジュールの使い方のアンドロイド端末側について紹介しました。
作ってて思ったんですが、Bluetooth標準搭載、各種センサー搭載、Wifi搭載の端末を大多数の個人が所有してるって・・・スマホ凄いな。
そんでもって、お次はウェアラブルになって、その次はインプラントで、その次はフュージョンですね。
次回は、スマホでPCのマウス動かすところを書きたいと思います。
→続きは『RN-42 Bluetoothモジュールの使い方3』
記載されたと内容をAndroid Studioに入力しましたが、うまくゆきません。
Android Studioではだめなのでしょうか?
4年前に書いた記事なので,Android SDKのバージョンアップにより記事のコードでは動かないかもしれません.
#最近めっきりAndroid開発から遠ざかってしまって詳しくは言えないのですが,パーミッション取得方法が6.0以降大きく変わったような…
Bluetoothの使い方については,下記が参考になると思います.
https://developer.android.com/guide/topics/connectivity/bluetooth.html