#react-native #webview #react-native-android #react-native-ios
Вопрос:
Введение:
Эй, ребята! Я разрабатываю проект, который в основном состоит из веб-представления со встроенной навигацией и экраном входа в систему, однако это веб-представление за два времени выполнения должно считывать qr-код или штрих-код. Используя разрешения android и ios перед открытием webview, я смог получить доступ к камере, выполняющей библиотечные реализации только на стороне сервера, однако я обнаружил, что на ios камера разбилась в safari, и мой веб-просмотр не был обнаружен, на Android он работал нормально, хотя и не мог отображать имена камер.
Что я думал:
Я думал найти библиотеку считывателей QR и штрих-кодов, совместимую с JAVA и Primefaces 8 с поддержкой webview, развертываемую на стороне сервера или во время выполнения webview, определить URL-адрес, по которому будет использоваться считывание QR, приостановить webview и открыть собственную библиотеку react для сканирования QR-кода, после чего приложение вернется в webview, перефразируя страницу, передавая необходимые параметры в URL-адресе.
Проблема:
Проблема со всем этим заключается в том, что я понятия не имею, как реализовать это переключение между библиотеками react native scanner и webview. Я также беспокоюсь о навигации, после того как чтение было выполнено, я не могу повторно активировать сканер, но возвращаюсь на предыдущую страницу, то есть на страницу перед сканером. Другая проблема-это сеанс пользователя, который я не могу потерять, пользователь должен оставаться в системе.
Мой Код:
Эта страница получает URL-адрес веб-сервисов на моей странице входа:
/* import * as React from 'react'; */
import React, { useState, useEffect, useRef } from 'react';
import { Text, View, StyleSheet, BackHandler, Alert, StatusBar, Platform, Linking } from 'react-native';
import { WebView } from 'react-native-webview';
import { ActivityIndicator } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import {check, PERMISSIONS, request, RESULTS} from 'react-native-permissions';
export default function WebViewUsrLogado(props:any) {
/* ==========================> Variaveis utilizadas <========================= */
const propriedade = props.route.params.url
const webViewRef = useRef<any | null>(null)
const statusBarRef = useRef<any | null>(null)
const [cameraGranted, setCameraGranted] = useState(false);
const [newurl, setNewUrl] = useState<any | null>(null);
const navigation = useNavigation();
const isIOS = Platform.OS === 'ios' ? true : false
; const Spinner = () => (
<View style={styles.activityContainer}>
<ActivityIndicator size="large" color="#f29900" />
</View>
);
const handleCameraPermission = async () => {
const permission = Platform.OS === 'ios' ? PERMISSIONS.IOS.CAMERA : PERMISSIONS.ANDROID.CAMERA
console.log(permission)
const res = await check(permission);
if (res === RESULTS.GRANTED) {
setCameraGranted(true);
} else if (res === RESULTS.DENIED) {
const res2 = await request(permission);
res2 === RESULTS.GRANTED ? setCameraGranted(true) : setCameraGranted(false);
}
};
const handleAcessExternalStoragePermission = async () => {
const permission = Platform.OS === 'ios' ? PERMISSIONS.IOS.PHOTO_LIBRARY : PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE
console.log(permission)
const res = await check(permission);
if (res === RESULTS.GRANTED) {
setCameraGranted(true);
} else if (res === RESULTS.DENIED) {
const res2 = await request(permission);
res2 === RESULTS.GRANTED ? setCameraGranted(true) : setCameraGranted(false);
}
};
const handlePhotoLibraryAddPermission = async () => {
const permission = PERMISSIONS.IOS.PHOTO_LIBRARY_ADD_ONLY
console.log(permission)
const res = await check(permission);
if (res === RESULTS.GRANTED) {
console.log( `Permitido`)
setCameraGranted(true);
} else if (res === RESULTS.DENIED) {
const res2 = await request(permission);
res2 === RESULTS.GRANTED ? setCameraGranted(true) : setCameraGranted(false);
}
};
const handleMicrophonePermission = async () => {
const permission = PERMISSIONS.IOS.MICROPHONE
console.log(permission)
const res = await check(permission);
if (res === RESULTS.GRANTED) {
setCameraGranted(true);
} else if (res === RESULTS.DENIED) {
const res2 = await request(permission);
res2 === RESULTS.GRANTED ? setCameraGranted(true) : setCameraGranted(false);
}
};
/* ==============================> Observaveis <============================= */
//Verificação de permissão
useEffect(() => {
handleCameraPermission();
handleAcessExternalStoragePermission();
if (Platform.OS == `ios`) {
handlePhotoLibraryAddPermission();
handleMicrophonePermission();
}
}, []);
//Botão voltar
useEffect(() => {
const backAction = () => {
const url = webViewRef.current.startUrl;
if (url.includes('/home.xhtml')) {
console.log('Peguei')
alerta();
}
webViewRef.current.goBack();
return true;
};
const backHandler = BackHandler.addEventListener('hardwareBackPress', backAction);
return () => backHandler.remove();
}, []);
/* ===============================> Funcções <=============================== */
const backButtonHandler = () => {
console.log(newurl)
if (webViewRef.current) {
if (newurl.includes('/home.xhtml')) {
alerta()
} else {
webViewRef.current.goBack()
}
}
}
function alerta(){
Alert.alert(
"Deseja Sair?",
"Caso deseja sair sua sessão e atividades serão encerradas.",
[
{
text: "Cancel",
onPress: () => console.log("Cancel Pressed"),
style: "cancel"
},
{ text: "OK", onPress: () => logOut() }
]
);
}
//Verifica se a url é igual a url de login, caso falso chama logout
function voltar(url: any){
setNewUrl(url)
if (url == 'https:/myurl/login.xhtml') {
console.log('iGUAL');
logOut();
} else if (url.includes(`http://fileurl/`)){
console.log(`opa peguei <==================================================`)
Linking.openURL(url);
webViewRef.current.goBack();
} else {
console.log(url)
}
}
//Verifica se existe item na pilha navegação e retira
function logOut(){
let canGoBack = navigation.canGoBack();
if (canGoBack) {
navigation.goBack();
} else{
console.log('tENTOU FAZER AÇÃO MAIS DE UMA VEZ')
}
}
/* ========================> Retorno de Visualização <======================== */
if (cameraGranted) {
return (
<View style={styles.container}>
<StatusBar backgroundColor="#1c4154" />
{
isIOS amp;amp;
<Text onPress={backButtonHandler}>Voltar</Text>
}
<WebView
source={{ uri: propriedade }}
ref={webViewRef}
style={styles.view}
originWhitelist={['*']}
allowsInlineMediaPlayback
javaScriptEnabled
scalesPageToFit
mediaPlaybackRequiresUserAction={false}
javaScriptEnabledAndroid
useWebkit
startInLoadingState={true}
renderLoading={Spinner}
onNavigationStateChange={(event)=>{
voltar(event.url)
}}
/>
</View>
);
} else {
return <Text>No access to camera</Text>;
}
}
/* ==============================> Estilização <============================= */
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor:'#1c4154',
paddingTop:20
},
activityContainer: {
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
top: 0,
left: 0,
backgroundColor: '#fff',
height: '100%',
width: '100%'
},
view: {
borderColor: 'red',
}
});
Android Manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" />
<uses-permission android:name="android.permission.CAMERA" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Среда разработки:
Веб-сайт: JAVA 8 и Primefaces 8
ПРИЛОЖЕНИЕ: «реагировать»: «17.0.1», «реагировать-родной»: «0.64.2»,