React native camera not working as expected with expo - react-native

I want to make a qrcode reader with react native,and i'm using expo.I'm following the guide based on the official documentation here : react-native-qrcode-scanner
I've installed react-native-camera succesfully by running npm install react-native-camera --save and the following is the commande react-native link react-native-camera in the console,and it gives me the following error:
By reading the doc if find that many things depend on react-native link like react-native link react-native-qrcode-scanner
react-native link react-native-permissions an also after that there are some configurations like <uses-permission android:name="android.permission.VIBRATE"/> that i cannot do because i don't use react-native-cli.

Expo already has what you want. expo-barcode-scanner
If your version of Expo is 33, you should download it individually.
You can run expo install expo-barcode-scanner
You must request permission to access the user's camera before attempting to get it. To do this, you will want to use the Permissions API. You can see this in practice in the following example.
Basic Example
import * as React from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import Constants from 'expo-constants';
import * as Permissions from 'expo-permissions';
import { BarCodeScanner } from 'expo-barcode-scanner';
export default class BarcodeScannerExample extends React.Component {
state = {
hasCameraPermission: null,
scanned: false,
};
async componentDidMount() {
this.getPermissionsAsync();
}
getPermissionsAsync = async () => {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({ hasCameraPermission: status === 'granted' });
};
render() {
const { hasCameraPermission, scanned } = this.state;
if (hasCameraPermission === null) {
return <Text>Requesting for camera permission</Text>;
}
if (hasCameraPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View
style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-end',
}}>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : this.handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
/>
{scanned && (
<Button title={'Tap to Scan Again'} onPress={() => this.setState({ scanned: false })} />
)}
</View>
);
}
handleBarCodeScanned = ({ type, data }) => {
this.setState({ scanned: true });
alert(`Bar code with type ${type} and data ${data} has been scanned!`);
};
}
props
onBarCodeScanned (function)
Callback that is invoked when a bar code has been successfully scanned. The callback is provided with an object of the shape { type: BarCodeScanner.Constants.BarCodeType, data: string }, where the type refers to the bar code type that was scanned and the data is the information encoded in the bar code (in this case of QR codes, this is often a URL). See BarCodeScanner.Constants.BarCodeType for supported values.
barCodeTypes (Array)
An array of bar code types. Usage: BarCodeScanner.Constants.BarCodeType.<codeType> where codeType is one of the listed above. Default: all supported bar code types. For example:
barCodeTypes={[BarCodeScanner.Constants.BarCodeType.qr]}
type (string)
-- Camera facing. Use one of BarCodeScanner.Constants.Type. Use either Type.front or Type.back. Same as Camera.Constants.Type. Default: Type.back.
Note: Passing undefined to the onBarCodeScanned prop will result in no scanning. This can be used to effectively "pause" the scanner so that it doesn't continually scan even after data has been retrieved.

if you are using expo, you will have npx. You can run any react-native command with npx. Hence:
npx react-native link react-native-camera

Related

Is there a Share library like this one out there? for React native

I have been seeing this Share library in many new Apps and I was wondering if there is one like it already. if not, how does one trigger opening WhatsApp and Facebook in React Native? thank you
You can use import { Share} from 'react-native'
import React from 'react';
import { Share, View, Button } from 'react-native';
const ShareExample = () => {
const onShare = async () => {
try {
const result = await Share.share({
message:
'React Native | A framework for building native apps using React',
});
if (result.action === Share.sharedAction) {
if (result.activityType) {
// shared with activity type of result.activityType
} else {
// shared
}
} else if (result.action === Share.dismissedAction) {
// dismissed
}
} catch (error) {
alert(error.message);
}
};
return (
<View style={{ marginTop: 50 }}>
<Button onPress={onShare} title="Share" />
</View>
);
};
export default ShareExample;
or
react-native-share library
npm i react-native-share --save to get your desired result.
One solution is to use Linking.openURL and social_icon together
(A) For social icons, you may install and use by referring to this official link:
https://reactnativeelements.com/docs/social_icon/
(B) For opening social media / email, etc thru Linking.openURL, the following are some examples:
Linking.openURL('fb://page/PAGE_ID');
Linking.openURL('http://instagram.com/_u/USER_NAME');
Linking.openURL('http://instagram.com/_p/PICTURE');
Linking.openURL('mailto:support#example.com')
Note: you have to import Linking , such as follows:
import { Button, Linking, View } from 'react-native';

react-native-image-picker vs expo ImagePicker

I have tried many attempts to get react-native-image-picker up and working with my RN app. I am using Expo and VS Code and am not running the app with Xcode or Android Studio. There seems to be many options to getting the camera roll available in an app and I am not sure which is the best path to take. None seem to be working for me so I would like to pick the best path and focus on making that one route work.
I am following the documentation: https://github.com/react-native-community/react-native-image-picker
Things I have tried:
React Native Camera Roll
Expo ImagePicker
expo-image-picker
react-native-image-picker
react-images-upload
react-native-photo-upload
My code:
import React, {useState, useEffect} from 'react';
import {StyleSheet, View, TextInput, TouchableOpacity, Text, CameraRoll } from 'react-native'
import ImagePicker from 'react-native-image-picker';
// import * as ImagePicker from 'expo-image-picker';
import Constants from 'expo-constants';
const PicturesScreen = ({navigation}) => {
const [pictures, setPictures] = useState([]);
getPermissionAsync = async () => {
if (Constants.platform.ios) {
const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
if (status !== 'granted') {
alert('Sorry, we need camera roll permissions to make this work!');
}
}
};
useEffect(() => {
getPermissionAsync();
}, []);
selectPhotoTapped = () => {
const options = {
quality: 1.0,
maxWidth: 500,
maxHeight: 500,
storageOptions: {
skipBackup: true,
},
};
ImagePicker.showImagePicker(options, response => {
if (response.didCancel) {
console.log('User cancelled photo picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
let source = {uri: response.uri};
console.log('source: ' + source);
// You can also display the image using data:
// let source = { uri: 'data:image/jpeg;base64,' + response.data };
setPictures({
picture: source
});
}
});
};
return (
<View style = {styles.container}>
<TouchableOpacity style = {styles.buttonContainerPhoto} onPress={()=> selectPhotoTapped()}>
<Text style={styles.buttonText} >
Upload Photos
</Text>
</TouchableOpacity>
<TouchableOpacity style = {styles.buttonContainer} onPress={()=> navigation.navigate('NextScreen')}>
<Text style={styles.buttonText} >
Next
</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
...
}
});
export default PicturesScreen;
I have made sure to link the packages, I have also uninstalled and reinstalled and started from scratch a few times. I have downgraded the version to make it work but I still continue to get one of these error messages:
react-native-image-picker: NativeModule.ImagePickerManager is null
or
Can not read property 'showImagePicker' of undefined.
or
undefined is not an object(evaluating 'imagepickerManager.showimagepicker')
Is it causing issues because I am using Expo? Should I just be using CameraRoll with react-native?
Use expo-image-picker if you're using Expo.
Anything that requires the use of react-native link will not work with Expo, unless stated that it is already included in Expo.
I was stuck with the same issue, and now I have resolved this. React native cli and expo cli both have some package differences. Similarly image-picker for both works differently.
For expo cli, you can check the documentation here: https://docs.expo.io/versions/latest/sdk/imagepicker/#__next
You can try for uploading image via camera using ImagePicker.launchCameraAsync and from photo library using ImagePicker.launchImageLibraryAsync.
While in react-native cli I was able to write a single function to choose from both camera and photo library but could not find a way for the same in expo yet.

How should I import AccessibilityInfo in a react native expo managed app?

I'm working on my first React Native project. It's an expo managed app with SDK 33.
I want to use the AccessibilityInfo API as described in the expo documentation here: https://docs.expo.io/versions/v33.0.0/react-native/accessibilityinfo/
The example on that page is straight forward but there's one thing missing: where do I import AccessibilityInfo from? My IDE autocomplete suggests to import {AccessibilityInfo} from "react-native-web"; but that seems wrong because I understand that react-native-web is to help bring react-native features into a web app.
So instead I do import {AccessibilityInfo} from "react-native";
But when I try to do the following in my component:
componentDidMount () {
AccessibilityInfo.isScreenReaderEnabled().then( (screenReaderEnabled) => {
console.log(screenReaderEnabled);
});
}
I get a "TypeError: _reactNative.AccessibilityInfo.isScreenReaderEnabled is not a function".
According to my IDE's autocomplete, the AccessibilityInfo module only has the following methods: addEventListener, announceForAccessibilty, fetch, removeEventListener, setAccessibilityFocus. But according to the expo documentation linked above, I should have other methods such as isScreenReaderEnabled.
My only guess is that I'm not importing the correct module. But I didn't find anything interesting while googling around. So can anyone point me in the right direction to help me solve that problem?
If you check out the github they have this example
import {AccessibilityInfo} from "react-native";
...
class ScreenReaderStatusExample extends React.Component<{}> {
state = {
screenReaderEnabled: false,
};
componentDidMount() {
AccessibilityInfo.addEventListener(
'change',
this._handleScreenReaderToggled,
);
AccessibilityInfo.fetch().done(isEnabled => {
this.setState({
screenReaderEnabled: isEnabled,
});
});
}
componentWillUnmount() {
AccessibilityInfo.removeEventListener(
'change',
this._handleScreenReaderToggled,
);
}
_handleScreenReaderToggled = isEnabled => {
this.setState({
screenReaderEnabled: isEnabled,
});
};
render() {
return (
<View>
<Text>
The screen reader is{' '}
{this.state.screenReaderEnabled ? 'enabled' : 'disabled'}.
</Text>
</View>
);
}
}
In there example all their doing is calling Fetch and not working with the variable directly
componentDidMount() {
...
AccessibilityInfo.fetch().done(isEnabled => {
this.setState({
screenReaderEnabled: isEnabled,
});
});
}
the fetch returns the IsEnabled status
so in your ComponentDidMount
change it from
AccessibilityInfo.isScreenReaderEnabled().then( (screenReaderEnabled) => {
console.log(screenReaderEnabled);
});
to
AccessibilityInfo.fetch().done(isEnabled => {
this.setState({
screenReaderEnabled: isEnabled,
});
});
and hold the isEnabled response in state.

I got a warning and couldn't use FontAwesome in React Native on Expo

Now I am trying to use FontAwesome in React Native App on Expo.
I followed the flow about how to use custom font through Expo on Expo document but these icons couldn't work and I couldn't see any fonts.
Fortunately I don't have any error but warning.
This is my code below.
Please teach me.
Thank you.
import { Font } from 'expo';
import { fontAwesome } from '../../assets/fonts/fa-solid-900.ttf';
class Help extends React.Component {
state = {
fontLoaded: false,
};
async componentDidMount() {
await Font.loadAsync({
FontAwesome: fontAwesome,
});
this.setState({ fontLoaded: true });
}
renderHelpLists() {
return HelpLists.map((value, index) => {
return (
<TouchableOpacity
key={index}
style={styles.helpListsBox}
>
<Text style={styles.helpListText}>
{value.name}
</Text>
{
this.state.fontLoaded ? (
<Text style={styles.rightIcon}>
{'\f054'}
</Text>
) : null
}
</TouchableOpacity>
);
});
}
const styles=Stylesheet.create({
rightIcon: {
fontFamily: 'FontAwesome',
},
})
I'm not yet familiar with using Font Awesome by importing TTF files in React Native.
However, could you try using the Font Awesome React Native component?
See https://github.com/fortawesome/react-native-fontawesome
I solved this problem with import Icon from 'react-native-vector-icons/FonteAwesome'.
However I am not sure how to use Expo-Icons.

Expo.FileSystem.downloadAsync do not show download notification

I am using expo FileSystem to download the pdf file. The API response lands into success function. However, I am not able to show the downloaded file to the user.
The expected behaviour should be like we usually see notification icon on the status bar and on click on icon its opens your file.
FileSystem.downloadAsync(
'https://bitcoin.org/bitcoin.pdf',
FileSystem.documentDirectory + 'Stay_Overview.xlsx'
).then(({ uri }) => {
console.log('Finished downloading to ', uri);
})
.catch(error => {
console.error(error);
});
This one had one or two tricks, but here is a solution to this using Expo that works on both iOS and Android.
In a new Expo project, amend the following two files:
App.js
import React, { Component } from 'react';
import { View, ScrollView, StyleSheet, Button, Alert, Platform, Text, TouchableWithoutFeedback } from 'react-native';
import { FileSystem, Constants, Notifications, Permissions } from 'expo';
import Toast, {DURATION} from 'react-native-easy-toast';
async function getiOSNotificationPermission() {
const { status } = await Permissions.getAsync(
Permissions.NOTIFICATIONS
);
if (status !== 'granted') {
await Permissions.askAsync(Permissions.NOTIFICATIONS);
}
}
export default class App extends Component {
constructor(props) {
super(props);
// this.toast = null;
this.listenForNotifications = this.listenForNotifications.bind(this);
// this.openFile = this.openFile.bind(this);
this.state = {
filePreviewText: ''
}
}
_handleButtonPress = () => {
let fileName = 'document.txt';
let fileUri = FileSystem.documentDirectory + fileName;
FileSystem.downloadAsync(
"https://raw.githubusercontent.com/expo/expo/master/README.md",
fileUri
).then(({ uri }) => {
console.log('Finished downloading to ', uri);
const localnotification = {
title: 'Download has finished',
body: fileName + " has been downloaded. Tap to open file.",
android: {
sound: true,
},
ios: {
sound: true,
},
data: {
fileUri: uri
},
};
localnotification.data.title = localnotification.title;
localnotification.data.body = localnotification.body;
let sendAfterFiveSeconds = Date.now();
sendAfterFiveSeconds += 3000;
const schedulingOptions = { time: sendAfterFiveSeconds };
Notifications.scheduleLocalNotificationAsync(
localnotification,
schedulingOptions
);
})
.catch(error => {
console.error(error);
Alert.alert(error);
});
};
listenForNotifications = () => {
const _this = this;
Notifications.addListener(notification => {
if (notification.origin === 'received') {
// We could also make our own design for the toast
// _this.refs.toast.show(<View><Text>hello world!</Text></View>);
const toastDOM =
<TouchableWithoutFeedback
onPress={() => {this.openFile(notification.data.fileUri)}}
style={{padding: '10', backgroundColor: 'green'}}>
<Text style={styles.toastText}>{notification.data.body}</Text>
</TouchableWithoutFeedback>;
_this.toast.show(toastDOM, DURATION.FOREVER);
} else if (notification.origin === 'selected') {
this.openFile(notification.data.fileUri);
}
// Expo.Notifications.setBadgeNumberAsync(number);
// Notifications.setBadgeNumberAsync(10);
// Notifications.presentLocalNotificationAsync(notification);
// Alert.alert(notification.title, notification.body);
});
};
componentWillMount() {
getiOSNotificationPermission();
this.listenForNotifications();
}
componentDidMount() {
// let asset = Asset.fromModule(md);
// Toast.show('Hello World');
}
openFile = (fileUri) => {
this.toast.close(40);
console.log('Opening file ' + fileUri);
FileSystem.readAsStringAsync(fileUri)
.then((fileContents) => {
// Get file contents in binary and convert to text
// let fileTextContent = parseInt(fileContents, 2);
this.setState({filePreviewText: fileContents});
});
}
render() {
return (
<View style={styles.container}>
<View style={styles.buttonsContainer}>
<Button style={styles.button}
title={"Download text file"}
onPress={this._handleButtonPress}
/>
<Button style={styles.button}
title={"Clear File Preview"}
onPress={() => {this.setState({filePreviewText: ""})}}
/>
</View>
<ScrollView style={styles.filePreview}>
<Text>{this.state.filePreviewText}</Text>
</ScrollView>
<Toast ref={ (ref) => this.toast=ref }/>
</View>
);
// <Toast
// ref={ (ref) => this.toast=ref }
// style={{backgroundColor:'green'}}
// textStyle={{color:'white'}}
// position={'bottom'}
// positionValue={100}
// opacity={0.8}
// />
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
buttonsContainer: {
flexDirection: 'row',
},
button: {
flex: 1
},
filePreview: {
flex: 1,
padding: 10,
},
toastText: {
color: 'white',
padding: 5,
justifyContent: 'flex-start',
},
});
package.json: Add the following dependency (fork of react-native-easy-toast)
"react-native-easy-toast": "git+https://github.com/SiavasFiroozbakht/react-native-easy-toast.git"
There are a couple of important notes about this solution:
Uses Expo API the most, for external local notifications and writing to / reading from files, which limits the current solution to being unable to write to other locations than Expo's own directory.
Once the file is downloaded, either a customisable toast is shown to the user if the app is active (Expo currently does not support foreground notifications), or sends a local Push Notification to let the user know the download has finished. Clicking on any of these two will show the contents of the file in a View, using the <Text> component.
The crazycodeboy/react-native-easy-toast repo has not been used directly due to a limitation of the toast, which is that the touch events are currently disregarded. The forked repo makes this functionality available before the merge request is implemented in the original. I recommend switching back to the original one once it gets patched as I will likely not maintain mine.
Although this project is also available in Snack, it will not run due to the need of using a git repository in package.json as mentioned above, and other apparent inconsistencies in variable scoping. This would be fixed by either the merge request or the new feature in Snack.
Other file types may be supported, either by Expo itself or via external packages, such as this PDF viewer. However, the code will have to be further adapted.
The toast (internal notification) is created with a TouchableWithoutFeedback component, although there are other similar ones in React Native with various differences. This component can be customised in the code (search for toastDOM), but might even be replaceable in the future by internal notifications available in Expo.
Lastly, an intentional three-second delay is applied to the notification once the file is downloaded – this allows us to test the notification when the app is in background. Feel free to remove the delay and trigger the notification immediately.
And that's it! I think this gives a good starting point for file downloading and previewing with Expo.
Codebase also available on GitHub.
DownloadManager
I believe that you are looking to use the DownloadManager for handling your downloads on Android (be aware there is no DownloadManager for iOS so you would have to handle this differently) The DownloadManager either savse the file to a shared system cache or it would save it to external storage.
However, at this time I do not believe that Expo allows you to use the DownloadManager, instead handling all the downloads itself. The reason could be that Expo doesn't allow you access to external storage, as it states in the documentation:
Each app only has read and write access to locations under the following directories:
Expo.FileSystem.documentDirectory
Expo.FileSystem.cacheDirectory
https://docs.expo.io/versions/latest/sdk/filesystem
So there would be no way to access the file in Expo once it was downloaded.
Possible Solution
A possible solution would be to use React-Native Fetch Blob. It does allow you to use the DownloadManager.
https://github.com/joltup/rn-fetch-blob#android-media-scanner-and-download-manager-support
Using the DownloadManager can be achieved in rn-fetch-blob by setting the addAndroidDownloads with the useDownloadManager key set to true.
However, that would mean ejecting your application from Expo.