问题描述
我编码使用MIC音频源的通话录音功能,因为VOICE_CALL是不是在某些设备允许的。
下面是我的code。
I am coding a call recording feature using MIC as audio source, as VOICE_CALL is not allowed in some devices.Below is my code.
但有时与空指针异常此code崩溃,有时不会停止媒体记录
我的意思是录制呼叫后也不胜枚举。
But sometimes this code crashes with Null pointer exception and sometimes does not stop the media-recorder
I mean recording goes on after the call also.
注册为广播接收器的手机状态
监听器......
Broadcast receiver registered as phone-state
listener....
任何帮助将是AP preciated。您可以在下面找到我的code。
Any help would be appreciated. You can find my code below.
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.Environment;
import android.telephony.TelephonyManager;
import android.widget.Toast;
public class TestingCallmonitor extends BroadcastReceiver{
private MediaRecorder mediaRecorder=null;
boolean flag=false;
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equalsIgnoreCase("android.intent.action.PHONE_STATE"))
{
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING))
{
//Toast.makeText(context, "ringing", Toast.LENGTH_LONG).show();
}
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE))
{
if(flag) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder=null;
}
flag=false;
}
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
{
flag=true;
Calendar c=Calendar.getInstance();
int hour=c.get(Calendar.HOUR);
int min=c.get(Calendar.MINUTE);
int sec=c.get(Calendar.SECOND);
//Toast.makeText(context, "started", Toast.LENGTH_LONG).show();
File folder = new File(Environment.getExternalStorageDirectory() + "/Callrecord");
if (!folder.exists()) {
folder.mkdir();
}
String mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/Callrecord/call"+hour+"-"+min+"-"+sec+".3gp";
mediaRecorder=new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//mediaRecorder.setAudioEncoder(MediaRecorder.getAudioSourceMax());
mediaRecorder.setAudioSamplingRate(44100);
mediaRecorder.setAudioEncodingBitRate(16);
mediaRecorder.setOutputFile(mFileName);
try{mediaRecorder.prepare();}catch(IOException e){Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();}
mediaRecorder.start();
}
}
}
}
推荐答案
在这里,我添加的通话记录样本源$ C $ c表示。请尝试,让我知道。
here i added the call recorder sample source code for. Please try and let me know.
RecordService.java
import java.io.File;
import java.io.IOException;
import java.lang.Exception;
import java.util.Date;
import java.text.SimpleDateFormat;
import android.os.IBinder;
import android.app.Service;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.preference.PreferenceManager;
import android.content.SharedPreferences;
import android.content.Context;
import android.content.Intent;
import android.media.MediaRecorder;
import android.widget.Toast;
import android.util.Log;
import java.io.InputStream;
import java.io.FileInputStream;
import java.util.Iterator;
public class RecordService
extends Service
implements MediaRecorder.OnInfoListener, MediaRecorder.OnErrorListener
{
private static final String TAG = "CallRecorder";
public static final String DEFAULT_STORAGE_LOCATION = "/sdcard/callrecorder";
private static final int RECORDING_NOTIFICATION_ID = 1;
private MediaRecorder recorder = null;
private boolean isRecording = false;
private File recording = null;;
private final int audioformat = 3;
private File makeOutputFile (SharedPreferences prefs)
{
File dir = new File(DEFAULT_STORAGE_LOCATION);
// test dir for existence and writeability
if (!dir.exists()) {
try {
dir.mkdirs();
} catch (Exception e) {
Log.e("CallRecorder", "RecordService::makeOutputFile unable to create directory " + dir + ": " + e);
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to create the directory " + dir + " to store recordings: " + e, Toast.LENGTH_LONG);
t.show();
return null;
}
} else {
if (!dir.canWrite()) {
Log.e(TAG, "RecordService::makeOutputFile does not have write permission for directory: " + dir);
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder does not have write permission for the directory directory " + dir + " to store recordings", Toast.LENGTH_LONG);
t.show();
return null;
}
}
// test size
// create filename based on call data
String prefix = "call";
//SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd_HH:MM:SS");
//prefix = sdf.format(new Date()) + "-callrecording";
// add info to file name about what audio channel we were recording
prefix += "-channel" + 1 + "-";
// create suffix based on format
String suffix = "";
switch (audioformat) {
case MediaRecorder.OutputFormat.THREE_GPP:
suffix = ".3gpp";
break;
case MediaRecorder.OutputFormat.MPEG_4:
suffix = ".mpg";
break;
case MediaRecorder.OutputFormat.RAW_AMR:
suffix = ".amr";
break;
}
try {
return File.createTempFile(prefix, suffix, dir);
} catch (IOException e) {
Log.e("CallRecorder", "RecordService::makeOutputFile unable to create temp file in " + dir + ": " + e);
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to create temp file in " + dir + ": " + e, Toast.LENGTH_LONG);
t.show();
return null;
}
}
public void onCreate()
{
super.onCreate();
recorder = new MediaRecorder();
Log.i("CallRecorder", "onCreate created MediaRecorder object");
}
public void onStart(Intent intent, int startId) {
Log.i("CallRecorder", "RecordService::onStartCommand called while isRecording:" + isRecording);
if (isRecording) return;
Context c = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
Boolean shouldRecord = prefs.getBoolean(Preferences.PREF_RECORD_CALLS, false);
if (!shouldRecord) {
Log.i("CallRecord", "RecordService::onStartCommand with PREF_RECORD_CALLS false, not recording");
//return START_STICKY;
return;
}
recording = makeOutputFile(prefs);
if (recording == null) {
recorder = null;
return; //return 0;
}
try {
// These calls will throw exceptions unless you set the
// android.permission.RECORD_AUDIO permission for your app
recorder.reset();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(audioformat);
Log.d("CallRecorder", "set output " + audioformat);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
Log.d("CallRecorder", "set encoder default");
recorder.setOutputFile(recording.getAbsolutePath());
Log.d("CallRecorder", "set file: " + recording);
//recorder.setMaxDuration(msDuration); //1000); // 1 seconds
//recorder.setMaxFileSize(bytesMax); //1024*1024); // 1KB
recorder.setOnInfoListener(this);
recorder.setOnErrorListener(this);
try {
recorder.prepare();
} catch (java.io.IOException e) {
Log.e("CallRecorder", "RecordService::onStart() IOException attempting recorder.prepare()\n");
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to start recording: " + e, Toast.LENGTH_LONG);
t.show();
recorder = null;
return; //return 0; //START_STICKY;
}
Log.d("CallRecorder", "recorder.prepare() returned");
recorder.start();
isRecording = true;
Log.i("CallRecorder", "recorder.start() returned");
updateNotification(true);
} catch (java.lang.Exception e) {
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to start recording: " + e, Toast.LENGTH_LONG);
t.show();
Log.e("CallRecorder", "RecordService::onStart caught unexpected exception", e);
recorder = null;
}
return; //return 0; //return START_STICKY;
}
public void onDestroy()
{
super.onDestroy();
if (null != recorder) {
Log.i("CallRecorder", "RecordService::onDestroy calling recorder.release()");
isRecording = false;
recorder.release();
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder finished recording call to " + recording, Toast.LENGTH_LONG);
t.show();
}
updateNotification(false);
}
// methods to handle binding the service
public IBinder onBind(Intent intent)
{
return null;
}
public boolean onUnbind(Intent intent)
{
return false;
}
public void onRebind(Intent intent)
{
}
private void updateNotification(Boolean status)
{
Context c = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
if (status) {
int icon = R.drawable.rec;
CharSequence tickerText = "Recording call from channel " + prefs.getString(Preferences.PREF_AUDIO_SOURCE, "1");
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Context context = getApplicationContext();
CharSequence contentTitle = "CallRecorder Status";
CharSequence contentText = "Recording call from channel...";
Intent notificationIntent = new Intent(this, RecordService.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(RECORDING_NOTIFICATION_ID, notification);
} else {
mNotificationManager.cancel(RECORDING_NOTIFICATION_ID);
}
}
// MediaRecorder.OnInfoListener
public void onInfo(MediaRecorder mr, int what, int extra)
{
Log.i("CallRecorder", "RecordService got MediaRecorder onInfo callback with what: " + what + " extra: " + extra);
isRecording = false;
}
// MediaRecorder.OnErrorListener
public void onError(MediaRecorder mr, int what, int extra)
{
Log.e("CallRecorder", "RecordService got MediaRecorder onError callback with what: " + what + " extra: " + extra);
isRecording = false;
mr.release();
}
}
PhoneListener.java
import android.content.Intent;
import android.content.Context;
import android.content.ComponentName;
import android.telephony.TelephonyManager;
import android.telephony.PhoneStateListener;
import android.util.Log;
public class PhoneListener extends PhoneStateListener
{
private Context context;
public PhoneListener(Context c) {
Log.i("CallRecorder", "PhoneListener constructor");
context = c;
}
public void onCallStateChanged (int state, String incomingNumber)
{
Log.d("CallRecorder", "PhoneListener::onCallStateChanged state:" + state + " incomingNumber:" + incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.d("CallRecorder", "CALL_STATE_IDLE, stoping recording");
Boolean stopped = context.stopService(new Intent(context, RecordService.class));
Log.i("CallRecorder", "stopService for RecordService returned " + stopped);
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.d("CallRecorder", "CALL_STATE_RINGING");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("CallRecorder", "CALL_STATE_OFFHOOK starting recording");
Intent callIntent = new Intent(context, RecordService.class);
ComponentName name = context.startService(callIntent);
if (null == name) {
Log.e("CallRecorder", "startService for RecordService returned null ComponentName");
} else {
Log.i("CallRecorder", "startService returned " + name.flattenToString());
}
break;
}
}
}
希望这对我来说应该you.Its有益的工作的罚款。请尝试,让我知道。
欲了解更多信息,请下载示例code形式
Hope it should helpful for you.Its working fine for me. Please try and let me know.For more info please download the sample code form
这篇关于使用audiosource MIC总是失败通话录音的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!