7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

React Native BLEペリフェラルをスキャンする

Posted at

はじめに

React Nativeアプリケーションで、BLEペリフェラルデバイスのスキャンを行います。Androidでのみ動作確認していますが、Androidのみで動作可能なAPIは利用していないので、iOSでも動作可能かと思います。OSSはBLE Managerを利用します。

初期セットアップ

まず通常通りアプリケーションの雛形を作り、それからyarn addでBLE Managerをインストールします。

$ react-native init BLESample
$ cd BLESample
$ yarn add react-native-ble-manager

Androidのマニフェスト(android/app/src/main/AndroidManifest.xml)に以下の3つのパーミッションを設定する。


    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

src/screens/MainScreen.jsを作成して、App.jsからはMainScreenを呼び出すようにしておきます。

// Appjs
import React from 'react';

import MainScreen from './src/screens/MainScreen'

const App: () => React$Node = () => {
  return (
    <MainScreen/>
  );
};

export default App;

スマートフォンのBluetooth ON/OFFを取得する

BLE Managerは利用する前にまずstartを呼び出す必要があります。Componentの初期化時のcomponentDidMountで呼び出します。BLE Managerの初期化の後にBluetoothの状態(スマートフォンのBluetooth ON/OFF設定)を確認します。

Bluetoothの状態はBleManager.checkState()で取得できますが、その前にListenerの登録が必要です。Bluetoothの状態を以下のように単純にTextで表示します。スマートフォンのBluetoothの設定に応じてon/offが切り替わります。

class MainScreen extends React.Component {
  state = {
    bt_status: 'on',
  }

  componentDidMount() {
    BleManager.start({showAlert: false})
    .then(() => {
      console.log('BleManager initialized')
      bleManagerEmitter.addListener(
        'BleManagerDidUpdateState',
        (args) => {
            this.setState({bt_status: args.state})
        }
      );
      BleManager.checkState()
    })
    .catch((error) => {
        console.log(error)
    });
  }
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.status_text}>Bluetooth: {this.state.bt_status}</Text>
      </View>
    );
  }
}

ペリフェラルをスキャンする

ペリフェラルのスキャンはscan() APIを利用します。結果は、BleManagerDiscoverPeripheralリスナーで返却されます。事前にリスナーを登録します。

bleManagerEmitter.addListener(
    'BleManagerDiscoverPeripheral',
    (args) => {
    }
);

ペリフェラルのスキャン結果は、以下のデータで返されます。

id - String - the id of the peripheral
name - String - the name of the peripheral
rssi - Number - the RSSI value
advertising - JSON - the advertising payload, here are some examples:
    isConnectable - Boolean
    serviceUUIDs - Array of String
    manufacturerData - JSON - contains the raw bytes and data (Base64 
    encoded string)
    serviceData - JSON - contains the raw bytes and data (Base64 encoded string)
    txPowerLevel - Int

スキャンした結果をリストで表現するコードを以下のように実装します。ComponentのstateにperipheralListを設定します。BleManagerDiscoverPeripheralのリスナーでペリフェラルの情報が通知された時点で、リストに追加します。stateに設定しているので、ペリフェラルが見つかる毎にUIがリフレッシュされます。

class MainScreen extends React.Component {
  state = {
    bt_status: 'on',
    peripheralList: [],
  };

  componentDidMount() {
    BleManager.start({showAlert: false})
    .then(() => {
      console.log('BleManager initialized');
      bleManagerEmitter.addListener(
        'BleManagerDidUpdateState',
        (args) => {
            this.setState({bt_status: args.state});
        }
      );
      bleManagerEmitter.addListener(
        'BleManagerDiscoverPeripheral',
        (args) => {
          peripheral = { 'id': args.id, 'name': args.name };
          this.state.peripheralList.push(peripheral);
          this.setState(this.state.peripheralList);
        }
      );
      BleManager.checkState();
    })
    .catch((error) => {
        console.log(error);
    });
  }

  scan() {
    BleManager.scan([], 5, false)
    .then(() => {
      console.log('Scan started');
      this.setState({peripheralList: []});
    })
    .catch((error) => {
      console.log(error);
    });
  }

  renderPeripheral({ item }) {
    return (
      <View style={styles.peripheralList}>
        <Text style={styles.id_text}>{item.id}</Text>
        <Text style={styles.id_text}>{item.name}</Text>
      </View>
    );
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.status_text}>Bluetooth: {this.state.bt_status}</Text>
        <Button title="Scan" onPress={this.scan.bind(this)} />
        <FlatList data={this.state.peripheralList} renderItem={this.renderPeripheral.bind(this)} />
      </View>
    );
  }
}
スクリーンショット 2020-04-25 21.14.37.png
7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?