今現在Androidアプリでbluetoothを扱おうと考え触っていたのですが、詳しい仕組みがわからず困っています。現在のサンプルコードでは接続が確認されると乱数が表示されるようになっています。
やりたいこと
Androidアプリにセンサーからデータを送り、そのデータを表示する。
接続する機器を選択できるようにする。
Androidのバージョンは5.0.2です。
http://mslgt.hatenablog.com/entry/2015/05/17/212257
こちらのサイトのソースコードを使用しています。
java
1// 対象のサービスUUID. 2 private static final String SERVICE_UUID = "2B1DA6DE-9C29-4D6C-A930-B990EA2F12BB"; 3 // キャラクタリスティックUUID. 4 private static final String CHARACTERISTIC_UUID = "7F855F82-9378-4508-A3D2-CD989104AF22"; 5 // キャラクタリスティック設定UUID(固定値). 6 private static final String CHARACTERISTIC_CONFIG_UUID = "00002902-0000-1000-8000-00805f9b34fb"; 7 8 // 乱数送信用. 9 private Random mRandom = new Random(); 10 private Timer mTimer; 11 private SendDataTimer mSendDataTimer; 12 13 private final LeScanCallback mScanCallback = new BluetoothAdapter.LeScanCallback() { 14 @Override 15 public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { 16 runOnUiThread(new Runnable() { 17 @Override 18 public void run() { 19 // スキャン中に見つかったデバイスに接続を試みる.第三引数には接続後に呼ばれるBluetoothGattCallbackを指定する. 20 mBleGatt = device.connectGatt(getApplicationContext(), false, mGattCallback); 21 } 22 }); 23 } 24 }; 25 private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { 26 @Override 27 public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) 28 { 29 // 接続状況が変化したら実行. 30 if (newState == BluetoothProfile.STATE_CONNECTED) { 31 // 接続に成功したらサービスを検索する. 32 gatt.discoverServices(); 33 } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { 34 // 接続が切れたらGATTを空にする. 35 if (mBleGatt != null) 36 { 37 mBleGatt.close(); 38 mBleGatt = null; 39 } 40 mIsBluetoothEnable = false; 41 } 42 } 43 @Override 44 public void onServicesDiscovered(BluetoothGatt gatt, int status) 45 { 46 // Serviceが見つかったら実行. 47 if (status == BluetoothGatt.GATT_SUCCESS) { 48 // UUIDが同じかどうかを確認する. 49 BluetoothGattService service = gatt.getService(UUID.fromString(SERVICE_UUID)); 50 if (service != null) 51 { 52 // 指定したUUIDを持つCharacteristicを確認する. 53 mBleCharacteristic = service.getCharacteristic(UUID.fromString(CHARACTERISTIC_UUID)); 54 55 if (mBleCharacteristic != null) { 56 // Service, CharacteristicのUUIDが同じならBluetoothGattを更新する. 57 mBleGatt = gatt; 58 59 // キャラクタリスティックが見つかったら、Notificationをリクエスト. 60 boolean registered = mBleGatt.setCharacteristicNotification(mBleCharacteristic, true); 61 62 // Characteristic の Notificationを有効化する. 63 BluetoothGattDescriptor descriptor = mBleCharacteristic.getDescriptor( 64 UUID.fromString(CHARACTERISTIC_CONFIG_UUID)); 65 66 descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 67 mBleGatt.writeDescriptor(descriptor); 68 // 接続が完了したらデータ送信を開始する. 69 mIsBluetoothEnable = true; 70 } 71 } 72 } 73 } 74 @Override 75 public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) 76 { 77 // キャラクタリスティックのUUIDをチェック(getUuidの結果が全て小文字で帰ってくるのでUpperCaseに変換) 78 if (CHARACTERISTIC_UUID.equals(characteristic.getUuid().toString().toUpperCase())) 79 { 80 // Peripheralで値が更新されたらNotificationを受ける. 81 mStrReceivedNum = characteristic.getStringValue(0); 82 // メインスレッドでTextViewに値をセットする. 83 mBleHandler.sendEmptyMessage(MESSAGE_NEW_RECEIVEDNUM); 84 } 85 } 86 }; 87 private Handler mBleHandler = new Handler() 88 { 89 public void handleMessage(Message msg) 90 { 91 // UIスレッドで実行する処理. 92 switch (msg.what) 93 { 94 case MESSAGE_NEW_RECEIVEDNUM: 95 mTxtReceivedNum.setText(mStrReceivedNum); 96 break; 97 case MESSAGE_NEW_SENDNUM: 98 mTxtSendNum.setText(mStrSendNum); 99 break; 100 } 101 } 102 }; 103 104 @Override 105 protected void onCreate(Bundle savedInstanceState) { 106 super.onCreate(savedInstanceState); 107 setContentView(R.layout.activity_central); 108 109 mIsBluetoothEnable = false; 110 111 // Writeリクエストで送信する値、Notificationで受け取った値をセットするTextView. 112 mTxtReceivedNum = (TextView) findViewById(R.id.received_num); 113 mTxtSendNum = (TextView) findViewById(R.id.send_num); 114 115 // Bluetoothの使用準備. 116 mBleManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 117 mBleAdapter = mBleManager.getAdapter(); 118 119 // Writeリクエスト用のタイマーをセット. 120 mTimer = new Timer(); 121 mSendDataTimer = new SendDataTimer(); 122 // 第二引数:最初の処理までのミリ秒 第三引数:以降の処理実行の間隔(ミリ秒). 123 mTimer.schedule(mSendDataTimer, 500, 1000); 124 125 // BluetoothがOffならインテントを表示する. 126 if ((mBleAdapter == null) 127 || (! mBleAdapter.isEnabled())) { 128 Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 129 // Intentでボタンを押すとonActivityResultが実行されるので、第二引数の番号を元に処理を行う. 130 startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 131 } 132 else 133 { 134 // BLEが使用可能ならスキャン開始. 135 this.scanNewDevice(); 136 } 137 } 138 @Override 139 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 140 // Intentでユーザーがボタンを押したら実行. 141 super.onActivityResult(requestCode, resultCode, data); 142 switch (requestCode) { 143 case REQUEST_ENABLE_BT: 144 if ((mBleAdapter != null) 145 || (mBleAdapter.isEnabled())) { 146 // BLEが使用可能ならスキャン開始. 147 this.scanNewDevice(); 148 } 149 break; 150 } 151 } 152 private void scanNewDevice() 153 { 154 // OS ver.5.0以上ならBluetoothLeScannerを使用する. 155 if (Build.VERSION.SDK_INT >= SDKVER_LOLLIPOP) 156 { 157 this.startScanByBleScanner(); 158 } 159 else 160 { 161 // デバイスの検出. 162 mBleAdapter.startLeScan(mScanCallback); 163 } 164 } 165 @TargetApi(SDKVER_LOLLIPOP) 166 private void startScanByBleScanner() 167 { 168 mBleScanner = mBleAdapter.getBluetoothLeScanner(); 169 // デバイスの検出. 170 mBleScanner.startScan(new ScanCallback() { 171 @Override 172 public void onScanResult(int callbackType, ScanResult result) { 173 super.onScanResult(callbackType, result); 174 // スキャン中に見つかったデバイスに接続を試みる.第三引数には接続後に呼ばれるBluetoothGattCallbackを指定する. 175 result.getDevice().connectGatt(getApplicationContext(), false, mGattCallback); 176 } 177 @Override 178 public void onScanFailed(int intErrorCode) 179 { 180 super.onScanFailed(intErrorCode); 181 } 182 }); 183 } 184 public class SendDataTimer extends TimerTask{ 185 @Override 186 public void run() { 187 if(mIsBluetoothEnable) 188 { 189 // 設定時間ごとに0~999までの乱数を作成. 190 mStrSendNum = String.valueOf(mRandom.nextInt(1000)); 191 // UIスレッドで生成した数をTextViewにセット. 192 mBleHandler.sendEmptyMessage(MESSAGE_NEW_SENDNUM); 193 // キャラクタリスティックに値をセットして、Writeリクエストを送信. 194 mBleCharacteristic.setValue(mStrSendNum); 195 mBleGatt.writeCharacteristic(mBleCharacteristic); 196 } 197 } 198 } 199 @Override 200 protected void onDestroy() 201 { 202 // 画面遷移時は通信を切断する. 203 mIsBluetoothEnable = false; 204 if(mBleGatt != null) { 205 mBleGatt.close(); 206 mBleGatt = null; 207 } 208 super.onDestroy(); 209 } 210}
下の箇所を変えればデータが得られると考えたのですが、どの場所を変えても表示されませんでした。
java
1public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) 2 { 3 // キャラクタリスティックのUUIDをチェック(getUuidの結果が全て小文字で帰ってくるのでUpperCaseに変換) 4 if (CHARACTERISTIC_UUID.equals(characteristic.getUuid().toString().toUpperCase())) 5 { 6 // Peripheralで値が更新されたらNotificationを受ける. 7 mStrReceivedNum = characteristic.getStringValue(0); 8 // メインスレッドでTextViewに値をセットする. 9 mBleHandler.sendEmptyMessage(MESSAGE_NEW_RECEIVEDNUM); 10 } 11 }
java
1 2 public class SendDataTimer extends TimerTask{ 3 @Override 4 public void run() { 5 if(mIsBluetoothEnable) 6 { 7 // 設定時間ごとに0~999までの乱数を作成. 8 mStrSendNum = String.valueOf(mRandom.nextInt(1000)); 9 // UIスレッドで生成した数をTextViewにセット. 10 mBleHandler.sendEmptyMessage(MESSAGE_NEW_SENDNUM); 11 // キャラクタリスティックに値をセットして、Writeリクエストを送信. 12 mBleCharacteristic.setValue(mStrSendNum); 13 mBleGatt.writeCharacteristic(mBleCharacteristic); 14 } 15 } 16 }
機器の選択についてはListViewを使おうと考えたのですが、スキャンの前に入れて見ても反応しませんでした。
回答よろしくお願いします。
あなたの回答
tips
プレビュー