最近使った React Native のライブラリのご紹介です。
数年前、iPhone と Bluetooth 端末を接続する方法について紹介しましたが、同じことを React Native でやる方法についてです。
同じ動作をする Android アプリを作りたかったのですが、Java で書いたところ、どうやっても接続したい端末を見つけられなくて…。
いろいろ試して、React Native でコードを書く方法に落ち着きました。
ライブラリの GitHub はこちら。
GitHub – innoveit/react-native-ble-manager: React Native BLE communication module
https://github.com/innoveit/react-native-ble-manager
ライブラリのインストールは下記コマンドで行います。
npm install --save react-native-ble-manager
次に、AndroidManifest.xml に必要なパーミッションを追加します。
<uses-permission android:name="android.permission.BLUETOOTH" tools:remove="android:maxSdkVersion" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:remove="android:maxSdkVersion" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="28"/> <uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30"/> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
もしかしたら、いくつか不要なものがあるかもしれません…。
なお、今回は割愛していますが、Bluetooth や位置情報のパーミッションリクエストが必要ですので、別途実装してください。
上記を追加したら、処理を追加していきます。
下記を追加して、ライブラリをインポートしてください。
import BleManager from 'react-native-ble-manager';
まず、Bluetooth が有効かどうかを確認し、有効だったらモジュールを初期化する .start()
メソッドを呼び出します。
BleManager.enableBluetooth().then(() => { BleManager.start({showAlert: false}).then(() => { // 初期化成功時に実行したい処理を追加 }).catch(error => console.error('BeManager could not be started.', error), ); }).catch((error) => { console.error("The user refuse to enable bluetooth.", error); });
なお、.enableBluetooth()
は Android でのみ使用可能です。
また、.start()
メソッドは、1回のみ呼び出すようにしてください。
初期化に成功したら、.scan()
メソッドを使って、Bluetooth 端末を探します。
BleManager.scan([], 10, false) .then(() => { console.log('[startScan] scan promise returned successfully.'); }).catch(err => { console.error('[startScan] ble scan returned in error', err); });
ちなみに上記のコードでは、検索する端末のIDは指定なしで、10秒間検索するという設定で、検索しています。
なお、端末が見つかった場合の処理は、別途リスナーを追加する必要があります。
その処理は下記のとおりです。
import { NativeModules, NativeEventEmitter } from "react-native"; const BleManagerModule = NativeModules.BleManager; const bleManagerEmitter = new NativeEventEmitter(BleManagerModule); let result = [];
useEffect(() => { const listeners = [ bleManagerEmitter.addListener('BleManagerDiscoverPeripheral', handleDiscoverPeripheral), ]; return () => { for (const listener of listeners) { listener.remove(); } }; }, []); const handleDiscoverPeripheral = (peripheral) => { result.push(peripheral); }
上記のコードでは、とりあえず端末が見つかったら変数 result に追加するという処理を実行していますが、こちらは任意のコードに書き換えてください。
なお、この書き方だと端末の重複が発生しましたので、FlatList 等で表示する場合は、重複を削除する処理を追加する必要がありますので、そこだけご注意ください。
最後に、Bluetooth 端末と接続する処理です。
.scan()
メソッドを実行して、端末が見つかった際に取得できる peripheral.id
を使って、端末と接続します。
使用するメソッドは .connect()
です。
BleManager.connect(peripheralId) .then(() => { // Success code console.log("Peripheral Connected."); }).catch((error) => { // Failure code console.error(error); });
実装してみて、個人的な感覚だと思いますが、正直 Java で書くよりも簡単でした…!
あと、Java で書いていた時に発生した、当該の端末が見つからないということも発生しませんでした。
やっぱりライブラリは便利ですね…。
以上、React Native で Bluetooth 端末を検索~接続までの処理でした。