BABIL_PROJECT/BLE

BLE-PLX

ForteQook 2022. 1. 29. 15:03

 react-native-ble-plx가 안정적으로 동작할 수 있도록 기록을 남겨두려고 한다. constructor 와 componentDIdMount 의 lifecycle에 대해 아직 제대로 파악을 하지 못한것 같다. 하단 코드는 도움을 받아 작성한 코드로, 내용에 대한 정확한 파악은 이루어지지 않은 상태이다.

class App extends Component {
    constructor() {
        super();
        this.manager = new BleManager();
    }

    componentDidMount() {
        setTimeout( () => {
                if (Platform.OS === 'android') {
                // Calling the permission function
                const granted = PermissionsAndroid.request(
                  PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
                  {
                    title: 'Bluetooth Permissions',
                    message: 'We need access to bluetooth permissions',
                  },
                );
                if (granted === PermissionsAndroid.RESULTS.GRANTED) {
                  // Permission Granted
                  console.log('granted');
                }
            }
              this.scanAndConnect();
          }, 3000);
    }

    scanAndConnect = () => {
        this.manager.startDeviceScan(null, null, (error, device) => {
           
            let name = "BABIL";
            console.log(device)
            if (device !== null) {
                console.log(name + ' : ' + device.name)
                if (device.name == name) {
                    console.log('found' + name);
                }
            }
        })
    }
   
    render () {
        return (
            <View>
                <Text>HI</Text>
            </View>
        )
    }
}

export default App;

constructor에서 App 클래스에 BleManager 인스턴스인 manager를 선언했다.

React의 lifecycle 상으로 componentDidMount가 나중에 호출되어서 setTimeOut 없이도 사실 scanAndConnect가 호출 됐을때 device가 잘 찾아져야 하는데, 그렇지 않았다.

[React] 5 - Component > 컴포넌트의 생명주기 (velog.io)

 

[React] 5 - Component > 컴포넌트의 생명주기

goalcomponent 생명주기의 모든 것모든 컴포넌트는 여러 종류의 “lifecycle methods”를 가지며, 이 메서드를 오버라이딩하여 특정 시점에 코드가 실행되도록 설정할 수 있다.=> when an instance of a component

velog.io

따라서 임시로 setTimeOut내에 scanAndConnect()를 넣어두고, 블루투스 권한 팝업창을 띄워주도록 해뒀다.

 

하단에는 여기서 생긴 의문을 적어둔다.

 

1. new 가 느려서 생기는 문제인건지? 어째서 setTimeOut 없이는 componentDidMount 에서 호출되는 scanAndConnect()가 constructor에서 선언되는 this.manager보다 빠르게 발동하는가?

 

2. 분명

                const granted = PermissionsAndroid.request(
                  PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
                  {
                    title: 'Bluetooth Permissions',
                    message: 'We need access to bluetooth permissions',
                  },
                );

까지는 제대로 작동해서, startDeviceScan 자체도 권한 요청 없이는 device를 찾지 않는다.

그런데,

                if (granted === PermissionsAndroid.RESULTS.GRANTED) {
                  // Permission Granted
                  console.log('granted');
                }

위 condition은 제대로 만족 되지 않아 log가 보이지 않는것을 확인했다.

 

우선 android에서 bluetooth에 관한 문서를 읽어볼 필요가 있다고 생각했다.

저전력 블루투스 개요  |  Android 개발자  |  Android Developers

 

저전력 블루투스 개요  |  Android 개발자  |  Android Developers

저전력 블루투스 개요 Android 4.3(API 레벨 18)에서는 저전력 블루투스(BLE)에 대한 플랫폼 내 지원을 핵심적 역할로 도입하고 앱이 기기를 검색하고, 서비스를 쿼리하고, 정보를 전송하는 데 사용할

developer.android.com

ble-plx공식 문서에 써있던것 처럼, AndroidManifest.xml 에 권한 설정을 해야한다는 내용을 확인했다.

또 공식문서에 <uses-sdk/>를 업데이트 하라는 말이 있었다.

<uses-sdk>  |  Android 개발자  |  Android Developers

 

<uses-sdk>  |  Android 개발자  |  Android Developers

Lets you express an application's compatibility with one or more versions of the Android platform, by means of an API Level integer. The API Level expressed by an application will be compared to the API Level of a given Android system, which may vary…

developer.android.com

Liroo/react-native-ble-plx - Giters

 

Liroo/react-native-ble-plx

Liroo Pierre ᵈᵉᵛ react-native-ble-plx: React Native BLE library

giters.com

하지만 uses-sdk 역시 그냥 min으로 설정한 api 보다 낮은 사용자들이 앱설치 하는것을 방지해주는 역할을 할 뿐, 여전히 권한 요청 팝업창에서 요청을 안하면 ble-plx가 정상적으로 작동하지 않았다.

따라서 react-native의 permission android 항목을 읽어보았다.

PermissionsAndroid · React Native

 

PermissionsAndroid · React Native

Project with Native Code Required

reactnative.dev

Manifest.permission  |  Android Developers

 

Manifest.permission  |  Android Developers

android.widget

developer.android.com

However, "dangerous" permissions require a dialog prompt.

공식문서에 따르면, "dangerous"한 권한들은 팝업창이 반드시 필요하고, 확인해보니 ACCESS_FINE_LOCATION 은 dangerous로 설정되어 있었다. 그러다보니 당연히 팝업창이 필요했던 것이였다.

 

    componentDidMount() {
        this.requestLocationPermission();
    }

    requestLocationPermission = async () => {
        if (Platform.OS === 'android') {
            try {
                const granted = await PermissionsAndroid.request(
                  PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
                  {
                    title: "Location Permission",
                    message:
                      "We need access to location permissions",
                    buttonNeutral: "Ask Me Later",
                    buttonNegative: "Cancel",
                    buttonPositive: "OK"
                  }
                );
                if (granted === PermissionsAndroid.RESULTS.GRANTED) {
                  console.log("Granted!");
                  this.scanAndConnect();
                } else {
                  console.log("Denied!");
                }
            } catch (err) {
                console.warn(err);
            }
        }
    }

이렇게 해도 정상적으로 작동하는 것을 확인했다.

 

`new NativeEventEmitter()` was called with a non-null argument without the required `addListener` method.

`new NativeEventEmitter()` was called with a non-null argument without the required `removeListeners` method.

 

위와 같은 warning이 계속 뜨는데, 찾아봐도 원인을 잘 파악할 수 없다...

 

 

'BABIL_PROJECT > BLE' 카테고리의 다른 글

BLE  (0) 2022.06.18
BLE_WRITE  (0) 2022.04.26
BLE_SCAN 액션 수정 (main/index.js)  (0) 2022.04.11
BLE_SCAN 액션 수정 (babilScan.js)  (0) 2022.04.10
React 와 Redux 불변성 (Immutability in React and Redux)  (0) 2022.03.31