You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo Location在Android跳转地图页面时崩溃问题求助

Expo Location + MapView Android端Expo Go崩溃修复方案

问题场景

使用Expo Location获取当前坐标后跳转至地图页面,需求是点击按钮定位到当前位置并设置合适缩放级别。iOS端代码正常运行,但Android端在Expo Go中持续崩溃。

原Map组件代码

export default function Map({ route, navigation }) {
  const { location } = route.params;
    
  return (
    <View style={styles.container}>
      <MapView style={styles.map} 
        initialRegion={{ 
          latitude: location?.coords.latitude,
          longitude: location?.coords.longitude
        }}
        zoomEnabled={true}
        showsUserLocation={true}
      /> 
    </View>
  );
}

原权限校验与跳转逻辑

const [locationPermissionInformation, requestPermission] = useForegroundPermissions();

const verifyPermissions = async () => {
  if (locationPermissionInformation.status === PermissionStatus.UNDETERMINED) {
    const permissionResponse = await requestPermission();
    return permissionResponse.granted;
  }

  if (locationPermissionInformation.status === PermissionStatus.DENIED) {
    Alert.alert('You need to allow this app to get your location for a good use')
    return false;
  }

  return true;
}

const handlePickupLocationOnMap = async () => {
  let hasPermssion = await verifyPermissions();
  if (!hasPermssion) return;
        
  const location = await getCurrentPositionAsync();
  location && navigation.navigate('MapView', { location });
};

崩溃核心原因

  1. MapView初始化参数不完整:Android端initialRegion必须包含latitudeDelta和longitudeDelta(缩放级别参数),仅传经纬度会导致组件初始化失败崩溃,iOS端有默认值兼容但Android没有。
  2. 定位结果未做异常处理:getCurrentPositionAsync可能因超时、信号差返回空值,直接传递会引发后续解构错误。
  3. 权限校验边界场景缺失:未处理权限状态未加载完成的情况,可能导致权限判断逻辑失效。

修复方案

1. 补全MapView的initialRegion参数

添加缩放级别参数,同时处理location为空的兜底逻辑:

export default function Map({ route, navigation }) {
  const { location } = route.params;
  
  // 生成合法的初始区域,默认缩放至城市级别
  const initialRegion = location?.coords ? {
    latitude: location.coords.latitude,
    longitude: location.coords.longitude,
    latitudeDelta: 0.01, // 数值越小缩放越近
    longitudeDelta: 0.01
  } : {
    // 定位失败时的默认区域(可自定义)
    latitude: 39.9042,
    longitude: 116.4074,
    latitudeDelta: 0.1,
    longitudeDelta: 0.1
  };

  return (
    <View style={styles.container}>
      <MapView 
        style={styles.map} 
        initialRegion={initialRegion}
        zoomEnabled={true}
        showsUserLocation={true}
      /> 
    </View>
  );
}

2. 完善定位请求的异常处理

添加超时、精度配置,捕获定位失败的异常:

const handlePickupLocationOnMap = async () => {
  let hasPermssion = await verifyPermissions();
  if (!hasPermssion) return;
        
  try {
    const location = await getCurrentPositionAsync({
      accuracy: Location.Accuracy.High,
      timeout: 5000, // 5秒超时
      maximumAge: 0 // 禁用缓存,获取实时位置
    });
    
    if (location?.coords) {
      navigation.navigate('MapView', { location });
    } else {
      Alert.alert('定位失败', '无法获取当前位置,请检查定位服务是否开启');
    }
  } catch (error) {
    Alert.alert('定位错误', error.message || '获取位置时发生异常');
  }
};

3. 优化权限校验逻辑

补充权限状态未加载的处理分支:

const verifyPermissions = async () => {
  // 权限状态未初始化时主动请求
  if (!locationPermissionInformation) {
    const permissionResponse = await requestPermission();
    return permissionResponse.granted;
  }

  if (locationPermissionInformation.status === PermissionStatus.UNDETERMINED) {
    const permissionResponse = await requestPermission();
    return permissionResponse.granted;
  }

  if (locationPermissionInformation.status === PermissionStatus.DENIED) {
    Alert.alert('需要位置权限', '请在系统设置中开启位置权限以使用该功能');
    return false;
  }

  return true;
};

内容的提问来源于stack exchange,提问作者daniel sas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:07:09