-
React Native Android APIReact Native 2021. 1. 2. 22:47
@ React Native 0.63 버전을 기준으로 작성되었습니다.
@ 최대한 쉽게 이해할 수 있도록 작성하고자 노력했습니다.
@ 편의상 세미콜론(;)은 생략합니다. 마침표도 생략될 수 있습니다.
React Native에는 어떤 안드로이드 API가 있는지 알아보자
공통적으로 적용되는 API는 다음에 추가해보겠다.
@ API가 무엇인지 모르거나 헷갈려하는 사람들을 위해
API는 흔히 Application Programming Interface(응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스) 라고 설명하는데 처음 접하는 사람들은 이게 무슨 말이야? 한다.
나도 처음에 그랬으니까...
바꿔말하면 'RN이 제공하는 기능'이라고 보면 될 것 같다.
RN이 운영체제나 프로그래밍 언어는 아니지만 프레임워크에서 지원하는 기능으로 브라우저(윈도우에서 작업관리자를 켜면 .exe로 뜬다)에서도 동작할 수 있는 기능을 제공한다.
마찬가지로 react에서도 제공하는 API 문서를 보면 흔히 보는 onChange 같은 것들이 있다.
단순하게 ~~에서 제공하는 기능이라고 보면 되겠다.
안드로이드 API는 안드로이드 환경에서만 사용가능하다.
안드로이드 API
1] BackHandler
(요즘 휴대폰은 거의 Zero Bezel이어서 뒤로가기 버튼을 뒤로가기 UI라고 하겠다)
뒤로가기 UI를 눌렀을 때 기본동작을 무시할지를 결정한다.
대표적인 사용사례는 뒤로가기 UI를 2번 눌러야 앱이 종료된다거나 내비게이션(차량 내비가 아님)을 사용했을 때
뒤로가기 UI에 대한 동작을 새로이 구성할 때 사용한다.
사용법
BackHandler.addEventListener(event: 'hardwareBackPress', handler: () => boolean): NativeEventSubscription BackHandler.addEventListener('hardwareBackPress', () => { return true })
뒤로가기 UI를 2번 눌렀을 때 앱을 종료
import React, { useEffect, useRef } from 'react' import { View, BackHandler } from 'react-native' export default function App() { let count = useRef(0) const backAction = () => { if (count.current === 0) { count.current += 1 } if (count.current >= 1) { BackHandler.exitApp() } return true // true를 반환하면 기본 동작 무시, false 기본동작 } useEffect(() => { BackHandler.addEventListener('hardwareBackPress', backAction) return BackHandler.removeEventListener('hardwareBackPress', backAction) }, []); return ( <View /> ); } // 더 간단하게 사용가능한 방법 export function App1() { // backAction은 위의 코드에서 그대로 사용 useEffect(() => { const back = BackHandler.addEventListener('hardwareBackPress', backAction); return () => back.remove(); }, [backAction]); return ( <View /> ); }
@ Modal 컴포넌트에서는 BackHandler가 작동하지 않으니 BackHandler 코드가 작성되어있다면 지우고
Modal 컴포넌트에 onRequestClose props를 쓰자
2] ToastAndroid
그림 밑에 설명
공식문서에 나와있는 예제를 안드로이드 기기에서 직접 실행해본 것이다.
화면 하단에 'A pikachu appeared nearby !'라고 나와있는 문구가 ToastAndroid이다.
공식문서의 예제를 그대로 가져와보면
import React from "react"; import { View, ToastAndroid, Button } from "react-native"; const App = () => { const showToast = () => { ToastAndroid.show("A pikachu appeared nearby !", ToastAndroid.SHORT); }; const showToastWithGravity = () => { ToastAndroid.showWithGravity( "All Your Base Are Belong To Us", ToastAndroid.SHORT, ToastAndroid.CENTER ); }; const showToastWithGravityAndOffset = () => { ToastAndroid.showWithGravityAndOffset( "A wild toast appeared!", ToastAndroid.LONG, ToastAndroid.BOTTOM, 25, 50 ); }; return ( <View> <Button title="Toggle Toast" onPress={() => showToast()} /> <Button title="Toggle Toast With Gravity" onPress={() => showToastWithGravity()} /> <Button title="Toggle Toast With Gravity & Offset" onPress={() => showToastWithGravityAndOffset()} /> </View> ); };
// ToastAndroid methods (message: 보여주고 싶은 메시지, duration: ToasdAndroid property) ToastAndroid.show(message, duration) ToastAndroid.showWithGravity(message, duration, gravity) ToastAndroid.showWithGravityAndOffset(message, duration, gravity, xoffset, yoffset) // ToastAndroid properties ToastAndroid.SHORT: 짧은 시간동안 보여줌 ToastAndroid.LONG: 길게 보여줌 ToastAndroid.TOP: 화면 위쪽에 보여줌 ToastAndroid.BOTTOM: 화면 아래쪽에 보여줌 ToastAndroid.CENTER: 화면 중앙에 보여줌
3] PermissionsAndroid
안드로이드는 파일을 저장하거나 카메라를 이용하거나 내비게이션 앱을 사용할 때 위치를 이용한다거나 할 때,
앱이 권한을 얻어야 한다.
앱이 기능 사용 권한이 있는지에 대한 확인, 권한에 대한 요청을 할 수 있게 해주는 것이 PermissionsAndroid다
요청과 확인이 있으니 당연하게도 비동기함수로 작성해야 한다.
// PermissionsAndroid methods // (permission: 아래 property, rationale: { // title: string, // message: string // buttonPositive: string // buttonNegative: string // buttonNeutral: string // }) PermissionsAndroid.check() // check(permission) PermissionsAndroid.request() // request(permission: Permission, rationale?: Rationale) PermissionsAndroid.requestMultiple() // requestMultiple(permission: Permission[]) // PermissionsAndroid.PERMISSIONS properties // ex) PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE // ex) PermissionsAndroid.result에는 // { GRANTED: 'granted', DENIED: 'denied', NEVER_ASK_AGAIN: 'never_ask_again' } 객체가 들어있다. // 위의 객체는 'granted': 성공, 'denied': 거절, 'never_ask_again': 권한 요청을 다시 묻지 않음이란 뜻이다. READ_CALENDAR WRITE_CALENDAR CAMERA READ_CONTACTS WRITE_CONTACTS GET_ACCOUNTS ACCESS_FINE_LOCATION ACCESS_COARSE_LOCATION RECORD_AUDIO READ_PHONE_STATE CALL_PHONE READ_CALL_LOG WRITE_CALL_LOG ADD_VOICEMAIL USE_SIP PROCESS_OUTGOING_CALLS BODY_SENSORS SEND_SMS RECEIVE_SMS READ_SMS RECEIVE_WAP_PUSH RECEIVE_MMS READ_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE
// 공식문서 예제 코드 import React from "react"; import { Text, View, PermissionsAndroid, Button } from "react-native"; const requestCameraPermission = async () => { try { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.CAMERA, { title: "Cool Photo App Camera Permission", message: "Cool Photo App needs access to your camera " + "so you can take awesome pictures.", buttonNeutral: "Ask Me Later", buttonNegative: "Cancel", buttonPositive: "OK" } ); if (granted === PermissionsAndroid.RESULTS.GRANTED) { console.log("You can use the camera"); } else { console.log("Camera permission denied"); } } catch (err) { console.warn(err); } }; const App = () => ( <View> <Text>Try permissions</Text> <Button title="request permissions" onPress={requestCameraPermission} /> </View> ); export default App;
1. 버튼을 누르면 카메라 권한 요청을 하는 grarequestCameraPermission함수가 실행되고 결과를 granted에 할당
2. grarequestCameraPermission함수를 실행하는 도중에 에러가 발생하면 try 구문 내에 로직은 실행하지 않고 catch 구문으로 넘어가 에러를 경고창에 출력한다.
3. grarequestCameraPermission함수를 실행하고 에러가 발생하지 않았을 때, granted가 'granted' 이면 카메라 권한을 획득했다는 것을 console에 출력하고 그렇지 않으면 획득하지 못했다는 것을 console에 출력한다.
@ 추가적으로 실질적으로 권한을 획득하려면 android/app/main/AndroidManifest.xml 파일에서
manifest 태그 내부에 다음 코드를 작성한다.
// android:name속성에 있는 문자열은 위에 PermissionsAndroid.PERMISSIONS를 소문자로 변경하고 // 대문자로 PermissionsAndroid.PERMISSIONS property를 입력해주면 된다. // 그러면 앱을 실행했을 때 자동으로 안드로이드가 앱 권한을 사용자에게 요청하는 창을 띄워준다 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
@@@@@
'React Native' 카테고리의 다른 글
React Native 새로운 아키텍처 (0) 2021.01.18 React Native Component (0) 2021.01.02