React Native不能直接获取通话时长,须要经过iOS和安卓的原生代码写桥接文件获取通话时长
iOS 经过CXCallObserver设置一个代理来随时捕获电话信息的更新,里边有呼叫中、接听、挂断等状态,记录通话时长,而后传递给JS,代码以下:
#import "RNCallBridgeModule.h"
#import <CallKit/CXCallObserver.h>
#import <CallKit/CXCall.h>
@interface RNCallBridgeModule()<CXCallObserverDelegate>
@property (nonatomic, strong) CXCallObserver *callObserver;
@property (nonatomic, strong) NSDate * startDate; //记录开始时间
@property (nonatomic, strong) NSDate * endDate; //记录结束时间
@property (nonatomic, copy) NSString *phoneNumber; //呼叫的手机号
@property (nonatomic, copy) RCTPromiseResolveBlock passCallTimeResolve; //通话后返回给JS的回调函数
@property (nonatomic, copy) RCTPromiseRejectBlock passCallTimeRejecter;
@end
@implementation RNCallBridgeModule
RCT_EXPORT_MODULE();
// 打电话 设置代理来随时捕获电话信息的更新
RCT_EXPORT_METHOD(call:(NSString *)phone)
{
dispatch_async(dispatch_get_main_queue(), ^{
NSString *phoneStr = [NSString stringWithFormat:@"telprompt://%@",phone];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneStr] options:@{} completionHandler:^(BOOL success) {
NSLog(@"success");
if (!success) return;
self.phoneNumber = phone;
self->_callObserver = [[CXCallObserver alloc] init];
[self->_callObserver setDelegate:self queue:dispatch_get_main_queue()];
}];
});
}
// 打电话代理 监听通话状态
- (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call {
if (call.outgoing && call.hasConnected && !call.hasEnded) {
_startDate = [NSDate date];
}
if (call.outgoing && call.hasConnected && call.hasEnded) {
_endDate = [NSDate date];
NSDate* dat = [NSDate dateWithTimeInterval:0 sinceDate:_startDate];
NSTimeInterval a=[dat timeIntervalSinceNow];
NSString *timeString = [NSString stringWithFormat:@"%0.f",fabs(a)];//转为字符型
[self passCallTime:timeString];
self.phoneNumber = nil;
self.startDate = nil;
self.endDate = nil;
}
}
// 存储回调函数
RCT_REMAP_METHOD(passCallTime,
passCallTimeResolve:(RCTPromiseResolveBlock)passCallTimeResolve
passCallTimeRejecter:(RCTPromiseRejectBlock)passCallTimeRejecter)
{
self.passCallTimeResolve = passCallTimeResolve;
self.passCallTimeRejecter = passCallTimeRejecter;
}
// 传递通话时长
- (void)passCallTime:(NSString*)time
{
NSString *startStampTime = [NSString stringWithFormat:@"%lf", [self.startDate timeIntervalSince1970]];
NSString *endStampTime = [NSString stringWithFormat:@"%lf", [self.endDate timeIntervalSince1970]];
self.passCallTimeResolve(@{@"callTime": time, @"phoneNumber": self.phoneNumber, @"startTime":startStampTime, @"endTime":endStampTime});
}
@end
复制代码
JS调用原生桥接方法
const CallModule = NativeModules.RNCallBridgeModule
CallModule.call(phone)
const dic = await CallModule.passCallTime()
// dic.callTime 就是通话时长
复制代码
Android
//安卓的权限
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
public class RNCallBridgeModule extends ReactContextBaseJavaModule {
private Promise callPromise;
private ReactApplicationContext reactContext;
public RNCallBridgeModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "RNCallBridgeModule";
}
@ReactMethod
public void passCallTime(Promise callPromise) {
this.callPromise = callPromise;
}
@ReactMethod
public void call(String phoneNumber) {
if (getCurrentActivity() instanceof MainActivity) {
((MainActivity) getCurrentActivity()).startCallPhone(phoneNumber, this);
}
}
@ReactMethod
public void endCall(CallEntity callEntity) {
if (callEntity == null) {
callEntity = new CallEntity();
}
String startDate = callEntity.getStartDate() == null ? null : String.valueOf(callEntity.getStartDate().getTime());
String endDate = callEntity.getEndDate() == null ? null : String.valueOf(callEntity.getEndDate().getTime());
WritableMap map = Arguments.createMap();
map.putInt("callTime", callEntity.getDuration());
map.putString("phoneNumber", callEntity.getPhone());
map.putString("startTime", startDate);
map.putString("endTime", endDate);
this.callPromise.resolve(map);
System.out.println(callEntity.toString());
}
}
复制代码