javascript - 未处理的承诺拒绝:错误:无权使用后台定位服务
问题描述
我在托管流程中使用 expo。另外,我正在使用 expo-task-Manager 和 expo-location。我正在使用世博会文档,但我不知道为什么当我在后台时出现错误提示:
[未处理的承诺拒绝:错误:未授权使用后台位置服务。] promiseMethodWrapper node_modules/@unimodules/react-native-adapter/build/NativeModulesProxy 中的 node_modules/react-native/Libraries/BatchedBridge/NativeModules.js:103:50。 native.js:15:23 在 moduleName.methodInfo.name node_modules/expo-location/build/Location.js: 在 startLocationUpdatesAsync node_modules/regenerator-runtime/runtime.js:63:36 在 tryCatch node_modules/regenerator-runtime/runtime。 js:293:29 in invoke node_modules/regenerator-runtime/runtime.js:63:36 in tryCatch node_modules/regenerator-runtime/runtime.js:154:27 in invoke
我的代码如下:
import React from 'react';
import {connect} from 'react-redux';
import {View, TouchableHighlight, Text, StyleSheet} from 'react-native';
import { activateSearch, actualLocation, arriveToken, logging, localFound, arriveShop, arriveShops } from '../redux/actions';
import { Alert, Platform } from 'react-native'
import * as Permissions from 'expo-permissions';
import * as Linking from 'expo-linking';
import * as Notifications from 'expo-notifications';
import * as Location from 'expo-location';
import * as TaskManager from 'expo-task-manager';
import axios from 'axios';
import {baseURL} from '../consts/url';
const LOCATION_TASK_NAME = 'background-location-tasks'
const hasNotificationPermission = async () => {
try {
const { status: existingStatus } = await Permissions.getAsync(Permissions.NOTIFICATIONS);
let finalStatus = existingStatus;
if (finalStatus === 'granted') return true;
if (finalStatus !== 'granted') {
Alert.alert(
'Warning',
'You will not receive notifications if you do not enable push notifications. If you would like to receive notifications, please enable push notifications for Fin in your settings.',
[
{ text: 'Cancel'},
// we can automatically open our app in their settings
// so there's less friction in turning notifications on
{ text: 'Enable Notifications', onPress: () => Platform.OS === 'ios' ? Linking.openURL('app-settings:') : Linking.openSettings() }
]
)
return false;
}
} catch (error) {
Alert.alert(
'Error',
'Something went wrong while check your notification permissions, please try again later.'
);
return false;
}
}
const hasGeolocationPermission = async () => {
try {
const { status } = await Location.requestPermissionsAsync();
let finalStatus = status
if (finalStatus === 'granted') return true;
if (finalStatus !== 'granted') {
Alert.alert(
'Warning',
'You will not search if you do not enable geolocation in this app. If you would like to search, please enable geolocation for Fin in your settings.',
[
{ text: 'Cancel'},
// we can automatically open our app in their settings
// so there's less friction in turning geolocation on
{ text: 'Enable Geolocation', onPress: () => Platform.OS === 'ios' ? Linking.openURL('app-settings:') : Linking.openSettings() }
]
)
return false;
}
} catch (error) {
Alert.alert(
'Error',
'Something went wrong while check your geolocation permissions, please try again later.'
);
return false;
}
}
const checkIfLocationEnabled = async () => {
let enabled = await Location.hasServicesEnabledAsync();
if (!enabled){
alert('Location service not enabled, please enable it to continue')
}
else {
return enabled;
}
}
class IndexScreen extends React.Component {
async componentDidMount() {
hasNotificationPermission()
hasGeolocationPermission()
this.registerForPushNotificationsAsync()
Notifications.addNotificationReceivedListener(notification => {
Alert.alert(notification.request.content.title, notification.request.content.body)
console.log(notification)
this.props.navigation('App');
})
Notifications.addNotificationResponseReceivedListener( response => {
console.log(response);
this.props.navigation('App');
}) /*cuando el usuario pulsa encima, cambia de pantalla*/
this.getShops()
this.myInterval = setInterval(async () => {
if (this.props.activated){
let Notpermission = await hasNotificationPermission();
let Geopermission = await hasGeolocationPermission();
let EnableLocation = await checkIfLocationEnabled();
if (Notpermission && Geopermission && EnableLocation){
this.getPosition();
} //Si cambia algo de los permisos, se deja de enviar.
else {return}
}
}, 5000)
this.myInterval2 = setInterval(async () => {
if (this.props.activated){
let Notpermission = await hasNotificationPermission();
let Geopermission = await hasGeolocationPermission();
let EnableLocation = await checkIfLocationEnabled();
if (Notpermission && Geopermission && EnableLocation){
this.sendLocation();
} //Si cambia algo de los permisos, se deja de enviar.
else {return}
}
}, 35000)
}
async componentWillUnmount(){
clearInterval(this.myInterval)
clearInterval(this.myInterval2)
}
activate = async () => {
let Notpermission = await hasNotificationPermission();
let Geopermission = await hasGeolocationPermission();
let EnableLocation = await checkIfLocationEnabled();
if (Notpermission && Geopermission && EnableLocation){
if (!this.props.activated){
this.props.dispatch(activateSearch());
this.getPosition();
this.sendLocation();
const { status } = await Location.requestPermissionsAsync();
if (status === 'granted') {
console.log("Entra aquí")
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
accuracy: Location.Accuracy.BalancedHighest,
timeInterval: 10000,
foregroundService: {
notificationTitle: "BackgroundLocation Is On",
notificationBody: 'To turn off, go back to the app and switch something off.',
}});
}
}
else
this.props.dispatch(activateSearch())
if (this.props.locationdetected)
this.props.dispatch(localFound());
//this.deleteToken()
}
else{
return
}
}
render() {
if (this.props.logged){
return(
<View style={{ flex:1, flexDirection: 'column', alignItems:'center', justifyContent:'space-around'}}>
<Text style={{flex:1, fontSize: 35 }}> Welcome {this.props.username} to this demo App </Text>
<Text style={{flex:1, fontSize: 35 }}> Press 'Start Search'</Text>
<TouchableHighlight style={styles.button} onPress = {() => this.activate()}>
<Text> {this.props.activated ? "Stop Search" : "Start Search"}</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.button} onPress = {() => this.logout()}>
<Text>Logout</Text>
</TouchableHighlight>
</View>
)
}
else{
return(
<View style={{ flex:1, flexDirection: 'column', alignItems:'center', justifyContent:'space-around'}}>
<Text style={{flex:1, fontSize: 35 }}> You need to be logged </Text>
</View>
)
}
}
async registerForPushNotificationsAsync() {
try{
let token = (await Notifications.getExpoPushTokenAsync()).data;
this.props.dispatch(arriveToken(token))
this.sendToken(token);
if (Platform.OS === 'android') {
Notifications.setNotificationChannelAsync('default', { /*en Android es necesario poner un canal por defecto*/
name: 'default',
importance: Notifications.AndroidImportance.MAX,
vibrationPattern: [0, 250, 250, 250],
lightColor: '#FF231F7C',
});
}
return token;
}
catch(error){
console.log("No se ha podido obtener el token para push notifications")
}
}
async getPosition() {
try{
const { coords } = await Location.getCurrentPositionAsync({});
let position = coords;
this.props.dispatch(actualLocation(position.latitude, position.longitude))
console.log(this.props.latitud)
}
catch (error) {
console.log("getPosition -> error", error);
}
}
async sendLocation(){
let response = await fetch(baseURL+'/location', {
method: 'POST',
headers: {
Accept: 'application/json',
'Accept-encoding': 'gzip, deflate',
'Content-Type': 'application/json',
},
//credentials: 'include',
body: JSON.stringify({latitud: this.props.latitud, longitud: this.props.longitud, shopfind: this.props.locationdetected}),
});
let responsed = await response.json();
if (response.status == 401){
alert('La sesión ha finalizado por exceso de espera. Vuelva a hacer Log in.')
if(this.props.activated && this.props.logged){
if(this.props.locationdetected){
this.props.dispatch(localFound())
}
this.props.dispatch(activateSearch());
this.props.dispatch(logging(''));
}
}
else if (responsed.shop && !this.props.locationdetected) {
this.props.dispatch(localFound())
let placementsreformed = responsed.shop.placements.map(item => {
return {...item,
quantity: 0}
})
responsed.shop.placements = placementsreformed;
this.props.dispatch(arriveShop(responsed.shop))
console.log("tienda enviada")
}
else {
if (this.props.locationdetected && !responsed.shop){
this.props.dispatch(localFound())
console.log("Se ha dejado de encontrar tiendas")
}
else{
return;
}
}
}
}
TaskManager.defineTask(LOCATION_TASK_NAME, async ({ data: {locations}, error }) => {
if (error) {
// Error occurred - check `error.message` for more details.
return;
}
const [location] = locations;
console.log(location);
try{
await axios.post(baseURL+'/location', {location})
}catch (err) {
console.log(err)
}
});
const styles = StyleSheet.create({
button: {
height: 60,
width: 100,
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: 'red',
fontSize: 25,
textAlign: 'center',
padding: 10
}
}
);
function mapStateToProps(state) {
return {
...state
};
}
//export default App;
export default connect(mapStateToProps)(IndexScreen);
解决方案
推荐阅读
- javascript - 在任何给定时间突出显示列表中的一项(默认为索引 0)
- azure-devops - 发布管道中缺少“启用系统诊断”
- mysql - 如何使用sql查询获取依赖数据
- ios - 非'@objc' 方法不满足'@objc' 协议的要求
- c# - 将 Property Attributes 的 TypeOf 值标识为现有类名
- ios - UIView 动画选项重复计数
- wordpress - 为什么 WordPress 为我的单作者页面创建分页?
- c - “llvm/libexec/clang-cc”有什么作用?
- node.js - 为什么 sequelize-cli 不在模型文件中包含 ID?
- playframework - 如何使用 Play 1.2.5 与 Mavan 同步