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

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

ただいまの
回答率

89.99%

AndroidアプリからセンサのUUIDへの書き込み

受付中

回答 0

投稿

  • 評価
  • クリップ 1
  • VIEW 1,352

tesura

score 10

今現在Androidアプリでbluetoothを扱おうと考え触っていたのですが、詳しい仕組みがわからず困っています。現在のサンプルコードでは接続が確認されると乱数が表示されるようになっています。

やりたいこと
Androidアプリでセンサデータを読み込み表示する。

センサ SONY MESH LEDタグ
Androidのバージョンは5.0.2です。

MESHのハック方法に下記のやり方が書いてあったのですが
72C90005-57A9-4D40-B746-534E22EC9F9E (Indicate) の通知を有効にする。
72C90004-57A9-4D40-B746-534E22EC9F9E (Write) に0x00020103を書き込む。
72C90003-57A9-4D40-B746-534E22EC9F9E (Notify) の通知を有効にする。

Writeに書き込む方法がよくわかりません。
下のように入れてみましたが反応しませんでした。

public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
        {
            // キャラクタリスティックのUUIDをチェック(getUuidの結果が全て小文字で帰ってくるのでUpperCaseに変換)
            if (CHARACTERISTIC_UUID.equals(characteristic.getUuid().toString().toUpperCase()))
            {
                // Peripheralで値が更新されたらNotificationを受ける.
                mStrReceivedNum = characteristic.getStringValue(0);
                // メインスレッドでTextViewに値をセットする.
                mBleHandler.sendEmptyMessage(MESSAGE_NEW_RECEIVEDNUM);
                byte level = 2;
                BluetoothGattCharacteristic c = characteristic(SERVICE_UUID, CHARACTERISTIC_UUIDW);
                c.setValue(new byte[] { level });
                gatt.writeCharacteristic(c);
            }
        }


上のやり方で書き込みは可能でしょうか?
可能ならば場所はどこに入れれば良いでしょうか?

http://mslgt.hatenablog.com/entry/2015/05/17/212257 
こちらのサイトのソースコードを使用しています。

// 対象のサービスUUID.
    private static final String SERVICE_UUID = "72C90001-57A9-4D40-B746-534E22EC9F9E";
    // キャラクタリスティックUUID.
    private static final String CHARACTERISTIC_UUID = "72C90003-57A9-4D40-B746-534E22EC9F9E";
    private static final String CHARACTERISTIC_UUIDW ="72C90004-57A9-4D40-B746-534E22EC9F9E";
    private static final String CHARACTERISTIC_UUIDN ="72C90005-57A9-4D40-B746-534E22EC9F9E";
    // キャラクタリスティック設定UUID(固定値).
    private static final String CHARACTERISTIC_CONFIG_UUID = "00002902-0000-1000-8000-00805f9b34fb";

  // 乱数送信用.
  private Random mRandom = new Random();
  private Timer mTimer;
  private SendDataTimer mSendDataTimer;

  private final LeScanCallback mScanCallback = new BluetoothAdapter.LeScanCallback() {
    @Override
    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
      runOnUiThread(new Runnable() {
        @Override
        public void run() {
          // スキャン中に見つかったデバイスに接続を試みる.第三引数には接続後に呼ばれるBluetoothGattCallbackを指定する.
          mBleGatt = device.connectGatt(getApplicationContext(), false, mGattCallback);
        }
      });
    }
  };
  private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState)
    {
      // 接続状況が変化したら実行.
      if (newState == BluetoothProfile.STATE_CONNECTED) {
        // 接続に成功したらサービスを検索する.
        gatt.discoverServices();
      } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
        // 接続が切れたらGATTを空にする.
        if (mBleGatt != null)
        {
            mBleGatt.close();
            mBleGatt = null;
        }
        mIsBluetoothEnable = false;
      }
    }
    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status)
    {
      // Serviceが見つかったら実行.
      if (status == BluetoothGatt.GATT_SUCCESS) {
        // UUIDが同じかどうかを確認する.
        BluetoothGattService service = gatt.getService(UUID.fromString(SERVICE_UUID));
        if (service != null)
        {
          // 指定したUUIDを持つCharacteristicを確認する.
          mBleCharacteristic = service.getCharacteristic(UUID.fromString(CHARACTERISTIC_UUID));

          if (mBleCharacteristic != null) {
            // Service, CharacteristicのUUIDが同じならBluetoothGattを更新する.
            mBleGatt = gatt;

            // キャラクタリスティックが見つかったら、Notificationをリクエスト.
            boolean registered = mBleGatt.setCharacteristicNotification(mBleCharacteristic, true);

            // Characteristic の Notificationを有効化する.
            BluetoothGattDescriptor descriptor = mBleCharacteristic.getDescriptor(
                    UUID.fromString(CHARACTERISTIC_CONFIG_UUID));

            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mBleGatt.writeDescriptor(descriptor);
            // 接続が完了したらデータ送信を開始する.
            mIsBluetoothEnable = true;
          }
        }
      }
    }
    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
    {
      // キャラクタリスティックのUUIDをチェック(getUuidの結果が全て小文字で帰ってくるのでUpperCaseに変換)
      if (CHARACTERISTIC_UUID.equals(characteristic.getUuid().toString().toUpperCase()))
      {
        // Peripheralで値が更新されたらNotificationを受ける.
        mStrReceivedNum = characteristic.getStringValue(0);
        // メインスレッドでTextViewに値をセットする.
        mBleHandler.sendEmptyMessage(MESSAGE_NEW_RECEIVEDNUM);
      }
    }
  };
  private Handler mBleHandler = new Handler()
  {
    public void handleMessage(Message msg)
    {
      // UIスレッドで実行する処理.
      switch (msg.what)
      {
        case MESSAGE_NEW_RECEIVEDNUM:
          mTxtReceivedNum.setText(mStrReceivedNum);
          break;
        case MESSAGE_NEW_SENDNUM:
          mTxtSendNum.setText(mStrSendNum);
          break;
      }
    }
  };

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_central);

    mIsBluetoothEnable = false;

    // Writeリクエストで送信する値、Notificationで受け取った値をセットするTextView.
    mTxtReceivedNum = (TextView) findViewById(R.id.received_num);
    mTxtSendNum = (TextView) findViewById(R.id.send_num);

    // Bluetoothの使用準備.
    mBleManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBleAdapter = mBleManager.getAdapter();

    // Writeリクエスト用のタイマーをセット.
    mTimer = new Timer();
    mSendDataTimer = new SendDataTimer();
    // 第二引数:最初の処理までのミリ秒 第三引数:以降の処理実行の間隔(ミリ秒).
    mTimer.schedule(mSendDataTimer, 500, 1000);

    // BluetoothがOffならインテントを表示する.
    if ((mBleAdapter == null)
            || (! mBleAdapter.isEnabled())) {
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
      // Intentでボタンを押すとonActivityResultが実行されるので、第二引数の番号を元に処理を行う.
      startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    }
    else
    {
      // BLEが使用可能ならスキャン開始.
      this.scanNewDevice();
    }
  }
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Intentでユーザーがボタンを押したら実行.
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
      case REQUEST_ENABLE_BT:
        if ((mBleAdapter != null)
                || (mBleAdapter.isEnabled())) {
          // BLEが使用可能ならスキャン開始.
          this.scanNewDevice();
        }
        break;
    }
  }
  private void scanNewDevice()
  {
    // OS ver.5.0以上ならBluetoothLeScannerを使用する.
    if (Build.VERSION.SDK_INT >= SDKVER_LOLLIPOP)
    {
      this.startScanByBleScanner();
    }
    else
    {
      // デバイスの検出.
      mBleAdapter.startLeScan(mScanCallback);
    }
  }
  @TargetApi(SDKVER_LOLLIPOP)
  private void startScanByBleScanner()
  {
    mBleScanner = mBleAdapter.getBluetoothLeScanner();
    // デバイスの検出.
    mBleScanner.startScan(new ScanCallback() {
      @Override
      public void onScanResult(int callbackType, ScanResult result) {
        super.onScanResult(callbackType, result);
        // スキャン中に見つかったデバイスに接続を試みる.第三引数には接続後に呼ばれるBluetoothGattCallbackを指定する.
        result.getDevice().connectGatt(getApplicationContext(), false, mGattCallback);
      }
      @Override
      public void onScanFailed(int intErrorCode)
      {
        super.onScanFailed(intErrorCode);
      }
    });
  }
  public class SendDataTimer extends TimerTask{
    @Override
    public void run() {
      if(mIsBluetoothEnable)
      {
        // 設定時間ごとに0~999までの乱数を作成.
        mStrSendNum = String.valueOf(mRandom.nextInt(1000));
        // UIスレッドで生成した数をTextViewにセット.
        mBleHandler.sendEmptyMessage(MESSAGE_NEW_SENDNUM);
        // キャラクタリスティックに値をセットして、Writeリクエストを送信.
        mBleCharacteristic.setValue(mStrSendNum);
        mBleGatt.writeCharacteristic(mBleCharacteristic);
      }
    }
  }
  @Override
  protected void onDestroy()
  {
    // 画面遷移時は通信を切断する.
    mIsBluetoothEnable = false;
    if(mBleGatt != null) {
      mBleGatt.close();
      mBleGatt = null;
    }
    super.onDestroy();
  }
}

色々質問が多く申し訳ございません。
回答よろしくお願いします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

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

  • ただいまの回答率 89.99%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る