【问题标题】:Implementing Call recording in React Native在 React Native 中实现通话录音
【发布时间】:2021-04-24 12:40:33
【问题描述】:

我正在创建一些东西来记录我的反应原生应用程序中的呼叫。 为此,我使用 ReactNative Headless 任务来获取电话的状态,并使用 react-native-audio-recorder-player 来录制通话,但最后我得到了一个没有声音的文件。

react-native-audio-recorder-player 在我不在通话时使用它时它的工作正常,但它在通话期间保存一个没有声音的文件。

这是我的 index.js



import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
import { AudioRecorder, AudioUtils } from 'react-native-audio'
import AudioRecorderPlayer from 'react-native-audio-recorder-player';
const audioRecorderPlayer = new AudioRecorderPlayer();

// const audioPath = AudioUtils.DocumentDirectoryPath + '/record.aac'
const Rec = async (data) => {
console.log(data.state)
try{
    if (data.state === 'extra_state_offhook') {
      
        const result= await audioRecorderPlayer.startRecorder().then(result=>console.log("started")).catch(err=>console.log(err))
         audioRecorderPlayer.addRecordBackListener((e) => {
            console.log('Recording . . . ', e.current_position);
            return;
           
          });
          console.log(result);
        
    } else if (data.state === 'extra_state_idle') {

        const result = await audioRecorderPlayer.stopRecorder();
        audioRecorderPlayer.removeRecordBackListener()
        console.log(result);
        console.log('Stopped')
    }
}catch(err ){
console.log(err)
}
}
AppRegistry.registerHeadlessTask('Rec', () => Rec)

AppRegistry.registerComponent(appName, () => App);
 

这是我的 AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cadric">

  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CALL_PHONE" />


<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.STORAGE"/>                                                                                                                                                
<uses-permission android:name="android.permission.CALL_PHONE"/>                                                                                                                                                
<uses-permission android:name="android.permission.READ_CALL_LOG"/>                                                                                                                                                

  
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
   <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
   <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

  <application android:requestLegacyExternalStorage="true"  android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:usesCleartextTraffic="true" android:theme="@style/AppTheme">
    <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>                          

      </intent-filter>
    
      <intent-filter>
        <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" />
      </intent-filter>
      
    </activity>
    <service android:name="com.cadric.service.RecService"  android:enabled="true" android:exported="true" />
<receiver android:name="com.cadric.receiver.RecReceiver" android:enabled="true" android:exported="true" android:permission="android.permission.BIND_DEVICE_ADMIN">
  <intent-filter android:priority="0">
    <action android:name="android.intent.action.PHONE_STATE" />
    <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
  </intent-filter>
</receiver>

  </application>
</manifest>

这是我的 RecReciever.java 文件

package com.cadric.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;

import com.cadric.service.RecService;
import com.facebook.react.HeadlessJsTaskService;
public final class RecReceiver extends BroadcastReceiver {
    public final void onReceive(Context context, Intent intent) {
  Boolean incomingCall=false;

        Intent recIntent = new Intent(context, RecService.class);
        if (intent.getAction().equals("android.intent.action.PHONE_STATE")) {
  recIntent.putExtra("action", "phone_state");
  String phoneState = intent.getStringExtra("state");
  if (phoneState.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
    String phoneNumber = intent.getStringExtra("incoming_number");
    System.out.println(phoneNumber);
    incomingCall = true;
    recIntent.putExtra("state", "extra_state_ringing");
    recIntent.putExtra("incoming_call", true);
    recIntent.putExtra("number", phoneNumber);
  } else if (phoneState.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
    if (incomingCall) {
      incomingCall = false;
    }
    recIntent.putExtra("state", "extra_state_offhook");
    recIntent.putExtra("incoming_call", false);
  } else if (phoneState.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
    if (incomingCall) {
      incomingCall = false;
    }
    recIntent.putExtra("state", "extra_state_idle");
    recIntent.putExtra("incoming_call", false);
  }
} else {
  recIntent.putExtra("action", "new_outgoing_call");
}
        context.startService(recIntent);
        HeadlessJsTaskService.acquireWakeLockNow(context);
    }
}

这是我的 RecService.java 文件

package com.cadric.service;
import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.HeadlessJsTaskService;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
import javax.annotation.Nullable;
public class RecService extends HeadlessJsTaskService {
    @Nullable
    protected HeadlessJsTaskConfig getTaskConfig(Intent intent) {
        Bundle extras = intent.getExtras();
        return new HeadlessJsTaskConfig(
          "Rec",
          extras != null ? Arguments.fromBundle(extras) : null,
          5000);
    }
}

请帮助我,我已经被卡住了,已经投入了 20 多个小时。

【问题讨论】:

    标签: android react-native kotlin mobile-development


    【解决方案1】:

    Android 对通话录音有严格的保护。见here

    语音通话 + 普通应用 如果音频模式,则语音通话处于活动状态 AudioManager.getMode() 返回的是 MODE_IN_CALL 或 MODE_IN_COMMUNICATION。

    Android 根据以下规则共享输入音频:

    通话始终接收音频。该应用程序可以捕获音频,如果它是 无障碍服务。该应用程序可以捕获语音呼叫,如果它是 具有 CAPTURE_AUDIO_OUTPUT 权限的特权(预安装)应用程序。

    要捕获语音呼叫的上行链路 (TX)、下行链路 (RX) 或两者, 应用程序必须指定音频源 MediaRecorder.AudioSource.VOICE_UPLINK 或 MediaRecorder.AudioSource.VOICE_DOWNLINK,和/或设备 AudioDeviceInfo.TYPE_TELEPHONY。

    尝试使用无障碍服务。我也在尝试使用 Native Android Kotlin,但还没有成功

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-29
      • 1970-01-01
      • 2023-03-09
      • 2020-01-03
      • 1970-01-01
      • 2022-10-21
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多