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

使用react-native-call-log在Expo环境中遇加载错误求助

问题根源与解决方案

react-native-call-log是依赖原生代码的模块,Expo Managed Workflow(托管环境)不支持这类未纳入Expo官方SDK的原生模块,这就是你遇到CallLog为null、方法不可用的核心原因。以下是具体解决步骤:

1. 切换到Expo Bare Workflow

如果当前是托管环境,先转为裸工作流,生成原生项目文件:

expo prebuild

2. 配置权限

Android端

在android/app/src/main/AndroidManifest.xml中添加权限声明:

<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />

iOS端

在ios/[你的项目名]/Info.plist中添加权限说明:

<key>NSCallKitUsageDescription</key>
<string>应用需要访问通话记录以展示历史记录</string>

3. 确保模块正确链接

Expo Bare Workflow支持自动链接,但如果仍有问题,手动在MainApplication.kt中注册包:

// 顶部导入包
import com.wscodelabs.calllog.CallLogPackage;

// 修改getPackages方法
override fun getPackages(): List<ReactPackage> =
    PackageList(this).packages.apply {
        add(CallLogPackage()) // 手动添加CallLog包
    }

4. 修复代码:先请求权限再调用接口

调用通话记录接口前必须先获取权限,修改你的Call.js:

import React, { useEffect, useState } from 'react';
import { View, Text, PermissionsAndroid, Platform } from 'react-native';
import CallLog from 'react-native-call-log';
import { request, PERMISSIONS } from 'react-native-permissions';

const CallsScreen = () => {
  const [callLogs, setCallLogs] = useState([]);

  useEffect(() => {
    requestPermissionsThenFetch();
  }, []);

  const requestPermissionsThenFetch = async () => {
    let hasPermission = false;
    // Android权限请求
    if (Platform.OS === 'android') {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.READ_CALL_LOG,
        {
          title: '通话记录权限申请',
          message: '需要访问您的通话记录以展示历史',
          buttonPositive: '允许'
        }
      );
      hasPermission = granted === PermissionsAndroid.RESULTS.GRANTED;
    } 
    // iOS权限请求
    else if (Platform.OS === 'ios') {
      const { status } = await request(PERMISSIONS.IOS.CALL_LOGS);
      hasPermission = status === 'granted';
    }

    if (hasPermission) {
      fetchCallLogs();
    } else {
      console.error('未获得通话记录权限');
    }
  };

  const fetchCallLogs = async () => {
    try {
      if (CallLog?.load) {
        const logs = await CallLog.load(50);
        setCallLogs(logs);
      } else {
        console.error('CallLog.load 方法不可用,请检查模块链接');
      }
    } catch (error) {
      console.error('获取通话记录失败:', error);
    }
  };

  return (
    <View style={{ padding: 16 }}>
      <Text style={{ fontSize: 18, marginBottom: 12 }}>通话记录:</Text>
      {callLogs.map((log, index) => (
        <View key={index} style={{ marginVertical: 8, padding: 8, borderBottomWidth: 1, borderBottomColor: '#eee' }}>
          <Text>号码: {log.number}</Text>
          <Text>类型: {log.type === 1 ? '来电' : log.type === 2 ? '去电' : '未接'}</Text>
          <Text>时间: {new Date(log.timestamp).toLocaleString()}</Text>
        </View>
      ))}
    </View>
  );
};

export default CallsScreen;

5. 清理缓存并重新构建

# 清除npm缓存
npm cache clean --force
# 清除Expo缓存
expo r -c
# 重新构建Android项目
cd android && ./gradlew clean && cd .. && expo run:android

内容的提问来源于stack exchange,提问作者Utsav Maji

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:37:46