You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Expo ImagePicker.launchCameraAsync()在部分Android设备崩溃原因排查

解决Expo SDK 39 + expo-image-picker ~9.1.0 相机调用崩溃问题

这种无日志的崩溃确实挺闹心的,尤其是在生产环境还跨了好几个Android版本,结合你说的模拟器能复现、测试应用也崩、try-catch还抓不到的情况,大概率是权限配置或者SDK版本兼容的问题,我给你整理了几个排查和修复的方向:

1. 先检查Android权限配置是否齐全

Expo Image Picker在Android上依赖相机和存储权限,虽然Expo一般会自动处理,但SDK39这个旧版本可能有遗漏:

  • 打开你的app.json,确认android.permissions里已经包含以下权限:
    "android": {
      "permissions": ["CAMERA", "READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE"]
    }
    
    另外Android 11及以上可以加上ACCESS_MEDIA_LOCATION试试,有些设备可能需要这个权限来正常处理图片。

2. 升级expo-image-picker到SDK39兼容的稳定版

你用的~9.1.0是SDK39初期的版本,存在一些未修复的相机适配bug,尤其是跨Android版本的:

  • 直接升级到SDK39推荐的expo-image-picker@9.3.0,执行命令:
    expo install expo-image-picker@9.3.0
    
    很多用户反馈升级这个版本后,Android相机崩溃的问题就解决了。

3. 简化相机启动参数排查

你当前的参数同时启用了allowsEditing: truebase64: true,这两个参数组合可能在某些设备上触发原生层崩溃:

  • 先把参数简化到最基础的版本,测试是否还崩溃:
    const takeImage = async () => {
      try {
        let result = await ImagePicker.launchCameraAsync({
          mediaTypes: ImagePicker.MediaTypeOptions.Images,
          quality: 1,
        });
        if (!result.cancelled) {
          console.log(result.uri);
        }
      } catch (err) {
        console.error("相机调用错误:", err);
      }
    };
    
    如果不崩溃了,再逐个加回参数(先加base64,再加allowsEditing),就能定位到是哪个参数导致的问题。

4. 捕获原生层的崩溃日志

因为try-catch抓不到,说明崩溃发生在原生代码层面,必须拿到原生日志才能精准定位:

  • 用Android Studio打开你的项目,启动模拟器后打开Logcat,过滤你的应用包名,调用相机时就能看到崩溃的堆栈信息;
  • 如果用真实设备,连接电脑后执行adb logcat *:E,这个命令会输出所有错误级别的日志,找到你应用崩溃的具体原因(比如空指针异常、权限拒绝等)。

5. 主动检查并请求相机权限

有时候权限没有正确授予,会直接导致原生层崩溃,而不是抛出JS层面的错误:

  • 在调用相机前,先主动请求权限,确保用户已经授权:
    import * as Permissions from 'expo-permissions'; // SDK39用这个模块,新版本是expo-media-library
    
    const takeImage = async () => {
      const { status } = await Permissions.askAsync(Permissions.CAMERA);
      if (status !== 'granted') {
        alert('需要授予相机权限才能使用相机功能');
        return;
      }
      try {
        let result = await ImagePicker.launchCameraAsync({
          mediaTypes: ImagePicker.MediaTypeOptions.Images,
          allowsEditing: true,
          aspect: [4, 3],
          quality: 1,
          base64: true,
        });
        if (!result.cancelled) {
          console.log(result.uri);
        }
      } catch (err) {
        console.error("相机调用错误:", err);
      }
    };
    

按照上面的步骤逐一排查,应该能找到崩溃的根源。最优先推荐的是升级expo-image-picker的版本,旧版本的兼容性问题是这类崩溃的常见原因。

内容的提问来源于stack exchange,提问作者Quddus George

火山引擎 最新活动