java - 拨出电话时的媒体记录器故障
问题描述
我正在尝试在扩展 BroadcastReceiver 的班级中记录拨出电话,但我看到两个失败:
- 这个出现在开始录音功能之后——
E/MediaRecorder:启动失败:-38
- 在我调用准备函数后出现此错误 -
E/Media_APM :: isCalledPackage 返回 false
我必须提到,当我在模拟器上运行它时,我看不到这些错误(但你不能在模拟器上测试电话录音),我只在三星 Galaxy 8 上运行应用程序时看到这些错误(使用 Android Pie 已安装)和三星 Note 20(安装了 Android Pie)。当我在小米米 A9(安装了 Android Q)上运行它时,它不会失败,但也不会录制任何内容 - 我看到音频文件,它的长度正确,但它是空的)。
这是我的代码:
public class CallBr extends BroadcastReceiver {
Bundle bundle;
String state;
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onReceive(Context context, Intent intent) {
if (Objects.equals(intent.getAction(), ACTION_IN)) {
if ((bundle = intent.getExtras()) != null) {
state = bundle.getString(TelephonyManager.EXTRA_STATE);
if (state != null && state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (shouldStartRecording) {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
File callAudioFile = null;
try {
File downloadsDir = context.getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
callAudioFile = File.createTempFile("deTuCelRecord", ".amr", downloadsDir);
} catch (IOException e) {
e.printStackTrace();
}
assert callAudioFile != null;
audioFilePath = callAudioFile.getAbsolutePath();
recorder.setOutputFile(audioFilePath);
try {
recorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {
@Override
public void onError(MediaRecorder mr, int what, int extra) {
Log.e("MediaRecorder", "MediaRecorder error " + what + " " + extra);
}
});
recorder.prepare();
} catch (Error e) {
Log.e("RecPrep", "So there was an error ...");
e.printStackTrace();
Log.d("RecPrep", "Did you get what that error was?");
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
Log.e("RecPrep", "startRecording: ", e);
}
recorder.start();
recordStarted = true;
shouldStartRecording = false;
}
shouldStartRecording = true;
}
if (state != null && state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
if (recordStarted) {
recorder.stop();
recorder.release();
convertToAmr();
compareAudioFiles(context);
recordStarted = false;
}
}
}
}
}
}
解决方案
推荐阅读
- android - 为特定元素更新 kotlin 类中的 layout_margin
- sequelize.js - Sequelize - 查询对象及其子对象
- java - 在 Windows 上获取执行的 .jar 名称
- android - Recyclerview Android中的用户配置文件布局
- vue.js - 计算属性不会在只读输入上更新
- html - css打字机效果,显示所有文本然后启动效果
- reactjs - 如何使用 Immutable.js 处理 Redux-Form FieldArrays 的验证?
- java - 我试图了解如何使用 FocusListener 控制 JInternalFrames
- c# - 与属性相比,使用 kernel32 dll 的共享文件夹上的磁盘空间
- javascript - 内容安全策略实际上如何防止攻击?