質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

解決済

2回答

4398閲覧

ボタンを押すことなく、受信Characteristicの値を常時表示したい (BluetoothLeGattの改変)

tmn

総合スコア13

Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2017/11/20 17:27

編集2017/11/21 06:00

###前提・実現したいこと
Android StuioのサンプルにあるBluetoothLeGattを改変し、Genuino101とBLE通信を行うアプリを作成しています。
GenuinoのCharacteristicの値を適当な時間ごとに変化させるように設定し、Android側でNotificationをセットしています。
現在はAndroid側からGenuino側に送信はできていますが、受信した値を表示することができていません。その値をボタンを押すことなく表示したいと考えています。
Notificationの設定方法等アドバイスお願いします。

###LeGattとの主な変更点
BluetoothLeService部のonServicesDiscoverd実行時にNotificationを設定。
ControlActivity部のdisplayGattServices、servicesListClickListner等の消去。
標準で用意されている心拍数の測定・表示等に関する部分の消去。

###BluetoothLeService.javaを改変したもの(抜粋)

java

1/* resDataTextにCharacteristicの値を入れたい 2 Genuino_UUIDはサービスUUID Genuino_Readは受信UUID Genuino_Writeは送信UUIDとしています */ 3 4 private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { 5 @Override 6 public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { 7 String intentAction; 8 if (newState == BluetoothProfile.STATE_CONNECTED) { 9 intentAction = ACTION_GATT_CONNECTED; 10 broadcastUpdate(intentAction); 11 Log.e(TAG, "Connected to GATT server."); 12 Log.e(TAG, "Attempting to start service discovery:" + mBluetoothGatt.discoverServices()); 13 14 } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { 15 intentAction = ACTION_GATT_DISCONNECTED; 16 Log.e(TAG, "Disconnected from GATT server."); 17 broadcastUpdate(intentAction); 18 } 19 } 20 21 @Override 22 public void onServicesDiscovered(BluetoothGatt gatt, int status) { 23 if (status == BluetoothGatt.GATT_SUCCESS) { 24 broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); 25 BluetoothGattService myService = mBluetoothGatt.getService(UUID.fromString(Genuino_UUID)); 26 BluetoothGattCharacteristic characteristic = myService.getCharacteristic(UUID.fromString(Genuino_Read)); 27 mBluetoothGatt.setCharacteristicNotification(characteristic, true); 28 29 BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG)); 30 descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 31 mBluetoothGatt.writeDescriptor(descriptor); 32 } else { 33 Log.e(TAG, "onServicesDiscovered received: " + status); 34 } 35 } 36 37 @Override 38 public void onCharacteristicRead(BluetoothGatt gatt, 39 BluetoothGattCharacteristic characteristic, 40 int status) { 41 if (status == BluetoothGatt.GATT_SUCCESS) { 42 broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 43 } 44 } 45 46 @Override 47 public void onCharacteristicChanged(BluetoothGatt gatt, 48 BluetoothGattCharacteristic characteristic) { 49 broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 50 } 51 }; 52 53 private void broadcastUpdate(final String action) { 54 final Intent intent = new Intent(action); 55 sendBroadcast(intent); 56 } 57 58 private void broadcastUpdate(final String action, 59 final BluetoothGattCharacteristic characteristic) { 60 final Intent intent = new Intent(action); 61 if (UUID.fromString(Genuino_Read).equals(characteristic.getUuid())) { 62 final byte[] data = characteristic.getValue(); 63 if (data != null && data.length > 0) { 64 intent.putExtra(EXTRA_DATA, data); 65 } 66 } 67 sendBroadcast(intent); 68 } 69 70 71 public void readCharacteristic(BluetoothGattCharacteristic characteristic) { 72 if (mBluetoothAdapter == null || mBluetoothGatt == null) { 73 Log.w(TAG, "BluetoothAdapter not initialized"); 74 return; 75 } 76 mBluetoothGatt.readCharacteristic(characteristic); 77 } 78 79 public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, 80 boolean enabled) { 81 if (mBluetoothAdapter == null || mBluetoothGatt == null) { 82 Log.w(TAG, "BluetoothAdapter not initialized"); 83 return; 84 } 85 mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); 86 87 if (Genuino_UUID.equals(characteristic.getUuid())) { 88 BluetoothGattDescriptor descriptor = characteristic.getDescriptor( 89 UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG)); 90 descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 91 mBluetoothGatt.writeDescriptor(descriptor); 92 } 93 } 94 95 public void sendData(byte[] bytes){ 96 BluetoothGattService myService = mBluetoothGatt.getService(UUID.fromString(Genuino_UUID)); 97 BluetoothGattCharacteristic characteristic = myService.getCharacteristic(UUID.fromString(Genuino_Write)); 98 characteristic.setValue(bytes); 99 mBluetoothGatt.writeCharacteristic(characteristic); 100 } 101} 102

###DeviceControlActivity.javaを改変したもの(抜粋)

java

1 private final ServiceConnection mServiceConnection = new ServiceConnection() { 2 @Override 3 public void onServiceConnected(ComponentName componentName, IBinder service) { 4 mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService(); 5 if (!mBluetoothLeService.initialize()) { 6 Log.e(TAG, "Unable to initialize Bluetooth"); 7 finish(); 8 } 9 mBluetoothLeService.connect(mDeviceAddress); 10 } 11 @Override 12 public void onServiceDisconnected(ComponentName componentName) { 13 mBluetoothLeService = null; 14 } 15 }; 16 17 private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { 18 @Override 19 public void onReceive(Context context, Intent intent) { 20 final String action = intent.getAction(); 21 if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) { 22 invalidateOptionsMenu(); 23 } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { 24 invalidateOptionsMenu(); 25 } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { 26 27 } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { 28 byte[] rsvData = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA); 29 if (rsvData != null) { 30 int sensorValue = convByteToInt(rsvData[0]); 31 resDataText.setText("[" + String.valueOf(sensorValue) + "]"); 32 } 33 } 34 } 35 }; 36 37 @Override 38 protected void onResume() { 39 super.onResume(); 40 registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter()); 41 if (mBluetoothLeService != null) { 42 final boolean result = mBluetoothLeService.connect(mDeviceAddress); 43 Log.d(TAG, "Connect request result=" + result); 44 } 45 } 46 47 48 private static IntentFilter makeGattUpdateIntentFilter() { 49 final IntentFilter intentFilter = new IntentFilter(); 50 intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED); 51 intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); 52 intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); 53 intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); 54 return intentFilter; 55 } 56 57 class ButtonClickListener implements OnClickListener { 58 @Override 59 public void onClick(View v) { 60 switch (v.getId()) { 61 case R.id.genuino_send0: 62 byte[] off = new byte[8]; 63 off[0] = 0; 64 mBluetoothLeService.sendData(off); //送信 65 break; 66 67 case R.id.genuino_send1: 68 byte[] on = new byte[8]; 69 on[0] = 1; 70 mBluetoothLeService.sendData(on); //送信 71 break; 72 73 default: 74 break; 75 } 76 } 77 } 78} 79

###試したこと
いくつかLogで確認したところ、BluetoothLeServiceの中のbroadcastUpdate(ACTION_DATA_AVAILABLE, characteristic)がうまく機能していないことは確認ができました。
が、どういじればいいか分からない状況です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

onServicesDiscoveredの
mBluetoothGatt.writeDescriptor(descriptor);
の次の行に
Log.d(TAG, "Notification UUID = " + characteristic.getUuid());
を入れると
正しいUUIDが取れていますか?

投稿2017/11/30 23:58

hillacken

総合スコア359

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tmn

2017/12/01 13:21 編集

回答ありがとうございます。 ご指摘の修正加えてLogを確認してみましたが、UUIDどころかLogが出てきません。 onServicesDiscoverdの各行間でLogを出力しチェックすると、 BluetoothGattCharacteristic characteristic = myService.getCharacteristic(UUID.fromString(Genuino_Read));の後ろ BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));の後ろ mBluetoothGatt.setCharacteristicNotification(characteristic, true);の後ろ ではLogが出力され正しいUUIDを確認しました。 しかしそれ以外の部分ではLogが出力されなかったです。
hillacken

2017/12/04 02:44

各行でチェックはいいですね ということは、ログが出なくなった行があやしいですが なにかエラー出ていませんか? descriptor.setValue()でエラーだとすると、 descriptor.setValue()の前に、 descriptor.getPermissions()で値を見てみるとか。 ちなみに、提示のソースコードは、 私の知識では問題なさそうに見えますので、 Genuino101側の設定かなーと思っています。 GooglePlayのBLEScannerとかnRF Connectとか 既存のアプリを使用して、 Genuino101のNotificationを受け取れますか?
tmn

2017/12/04 10:11

何度もご回答ありがとうございます。 ご指摘箇所にdescriptor.getPermissions()を挿入し、 テストしてみるとなぜか値が常時更新されるようになりました。 その後はdescriptor.getPermissions()の部分を消しても動作することを確認しました。 Android Studioのアップデートや、Genuinoの設定を変更することなく 動くようになりましたので、正直どこが原因でなぜこのようになっているかは分かりません。笑 ですが、hillackenさんのご指摘のおかげで理解が深まり、解決できたと思っております。 親身に答えてくださり本当に助かりました。ありがとうございます。
hillacken

2017/12/04 13:10

動いたようでよかったです。 androidデバイス内のbluetoothモジュールに設定が残ったままだったかもしれませんね。
guest

0

broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic)がうまく機能していないことは確認ができました。

というのはどういう状況でしょうか?
BluetoothLeService.javaの、onCharacteristicReadまたはonCharacteristicChangedは呼び出されていますか?
DeviceControlActivity.javaの、onReceiveは呼び出されていますか?


if (rsvData != null) { int sensorValue = convByteToInt(rsvData[0]); resDataText.setText("[" + String.valueOf(sensorValue) + "]"); }

↑ここを↓このように変更したら何かしら表示されますか?

JAVA

1 if (rsvData != null && rsvData.length > 0) { 2 final StringBuilder stringBuilder = new StringBuilder(rsvData.length); 3 for (byte byteChar : rsvData) { 4 stringBuilder.append(String.format("%02X ", byteChar)); 5 } 6 resDataText.setText(stringBuilder.toString()); 7 }

投稿2017/11/30 07:03

hillacken

総合スコア359

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tmn

2017/11/30 09:14

回答ありがとうございます。 BluetoothLeService.java内のonCharacteristicReadとonCharacteristicChangedの部分が実行されていません。 上記の部分が実行されないので、onReceiveは呼び出されますが、ACTION_DATA_AVAILABLEに変わることがないので、DeviceControlActivity.javaのonReceive内の } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { 部分が実行されていないです。 そのためご指摘いただいた修正を加えても表示が変わることはありません。 Notify?Notification?の使い方が誤っているとは思っているのですが、正しい記述方法が分からない状態です。 分かりにくい書き方で申し訳ございませんが、ご指導お願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問