使用“展览位置”查找后台位置权限错误

Using Expo Location to find background location permissions error

提问人:Saw 提问时间:8/28/2023 最后编辑:Saw 更新时间:9/6/2023 访问量:116

问:

我正在尝试使用 expo-location 和 expo-task-manager 在应用程序处于前台和后台时查找用户位置。我正在使用 expo 编译代码而不使用 Xcode。问题是我提供的代码给了我两个错误:

[Unhandled promise rejection: Error: One of the `NSLocation*UsageDescription` keys must be present in Info.plist to be able to use geolocation.]
at node_modules\@babel\runtime\helpers\construct.js:null in <global>
at node_modules\@babel\runtime\helpers\wrapNativeSuper.js:null in _wrapNativeSuper
- ... 3 more stack frames from framework internals

和:

[Unhandled promise rejection: Error: Background Location has not been configured. To enable it, add `location` to `UIBackgroundModes` in Info.plist file.]
at node_modules\@babel\runtime\helpers\construct.js:null in <global>
at node_modules\@babel\runtime\helpers\wrapNativeSuper.js:null in _wrapNativeSuper
- ... 3 more stack frames from framework internals

这些错误是指我的App.json中的 infoPlist 设置:

"infoPlist": {
        "UIBackgroundModes": ["location"],
        "NSLocationWhenInUseUsageDescription": "To allow the user to start recording a run...",
        "NSLocationAlwaysUsageDescription": "To allow the distance to be measured even when the phone is turned off"
        "NSLocationAlwaysAndWhenInUseUsageDescription": "Allow $(PRODUCT_NAME) to use your location to track your runs"
      }

即使明确设置了 UIBackgroundModes 以及 NSLocationWhenInUseUsageDescription 和 NSLocationAlwaysUsageDescription,这些错误仍会出现。

正在运行的代码:

App.js:

import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import UserLocation from "./UserLocation"

export default function App() {

  return (
    <View style={styles.container}>
      <UserLocation />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

用户位置.js:

import React from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import * as Location from 'expo-location';
import * as TaskManager from 'expo-task-manager';

const LOCATION_TRACKING = 'location-tracking';

var l1;
var l2;

export default function UserLocation() {

    const [locationStarted, setLocationStarted] = React.useState(false);

    const startLocationTracking = async () => {
        await Location.startLocationUpdatesAsync(LOCATION_TRACKING, {
            accuracy: Location.Accuracy.Highest,
            timeInterval: 5000,
            distanceInterval: 0,
        });
        const hasStarted = await Location.hasStartedLocationUpdatesAsync(
            LOCATION_TRACKING
        );
        setLocationStarted(hasStarted);
        console.log('tracking started?', hasStarted);
    };

    React.useEffect(() => {
        const config = async () => {
            let resf = await Location.requestForegroundPermissionsAsync();
            let resb = await Location.requestBackgroundPermissionsAsync();
            if (resf.status != 'granted' && resb.status !== 'granted') {
                console.log('Permission to access location was denied');
            } else {
                console.log('Permission to access location granted');
            }
        };

        config();
    }, []);

    const startLocation = () => {
      
        startLocationTracking();
    }

    const stopLocation = () => {
        setLocationStarted(false);
        TaskManager.isTaskRegisteredAsync(LOCATION_TRACKING)
            .then((tracking) => {
                if (tracking) {
                    Location.stopLocationUpdatesAsync(LOCATION_TRACKING);
                }
            })
    }

    return (
        <View>
          {locationStarted ?
              <TouchableOpacity onPress={stopLocation}>
                  <Text style={styles.btnText}>Stop Tracking</Text>
              </TouchableOpacity>
              :
              <TouchableOpacity onPress={startLocation}>
                  <Text style={styles.btnText}>Start Tracking</Text>
              </TouchableOpacity>
          }
        </View>
    );
}

const styles = StyleSheet.create({
    btnText: {
        fontSize: 20,
        backgroundColor: 'green',
        color: 'white',
        paddingHorizontal: 30,
        paddingVertical: 10,
        borderRadius: 5,
        marginTop: 10,
    },
});

TaskManager.defineTask(LOCATION_TRACKING, async ({ data, error }) => {
    if (error) {
        console.log('LOCATION_TRACKING task ERROR:', error);
        return;
    }
    if (data) {
        const { locations } = data;
        let lat = locations[0].coords.latitude;
        let long = locations[0].coords.longitude;

        l1 = lat;
        l2 = long;

        console.log(
            `${new Date(Date.now()).toLocaleString()}: ${lat},${long}`
        );
    }
});

App.js 的完整版本:

{
  "expo": {
    "name": "FinalHopefully",
    "slug": "FinalHopefully",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "userInterfaceStyle": "light",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true,
      "infoPlist": {
        "UIBackgroundModes": ["location"],
        "NSLocationWhenInUseUsageDescription": "To allow the user to start recording a run...",
        "NSLocationAlwaysUsageDescription": "To allow the distance to be measured even when the phone is turned off"
        "NSLocationAlwaysAndWhenInUseUsageDescription": "Allow $(PRODUCT_NAME) to use your location to track your runs"
      }
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#ffffff"
      }
    },
    "web": {
      "favicon": "./assets/favicon.png"
    }
  }
}

ios reactjs json react-native expo

评论

0赞 Paulw11 8/29/2023
您将需要NSLocationAlwaysandWhenInUseUsageDescription
0赞 Saw 8/30/2023
@Paulw11我做到了,但仍然没有用。
0赞 Rohit S K 8/30/2023
你应该像这样更新你的app.json
0赞 Saw 8/31/2023
@RohitSK我尝试使用插件,但仍然不起作用。我得到的只是相同的 2 条无用消息。
0赞 xgqfrms 9/1/2023
您的工作流程是什么?docs.expo.dev/archive/managed-vs-bare

答:

0赞 Gabriel Donadel Dall'Agnol 9/6/2023 #1

如果使用的是 expo-dev-client 和 EAS,则必须在进行这些更改后重新生成应用,如果要在本地生成,则需要运行以重新生成 iOS 文件并更新 Info.plistnpx expo prebuild --clean -p ios