Android实现通话自动录音

最近需要做一个类似于电话客户的功能,要求拨打电话能自动录音。所以写了一个dome,希望能够帮到大家。

主要思路就是监听手机通话状态在监听到接听时开始录音,结束停止录音。

AndroidManifest中配置

<!-- 权限 -->

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

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

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

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

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

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

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

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

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

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

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

<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />

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

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

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

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

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

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

当然了还要在清单文件中注册service

public abstract class CommonAdapter<T> extends BaseAdapter{

protected Context mContext;

protected List<T> mList;

protected int mLayoutId;

public CommonAdapter(Context context, List<T> list, int layoutId) {

mContext=context;

mList=list;

mLayoutId=layoutId;

}

//刷新数据

public void refresh(List<T> list){

mList=list;

notifyDataSetChanged();

}

@Override

public int getCount() {

return mList.size();

}

@Override

public T getItem(int position) {

return mList.get(position);

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder = ViewHolder.getHolder(mContext, mLayoutId, convertView, parent);

convertView(holder,mList.get(position));

return holder.getConvertView();

}

public abstract void convertView(ViewHolder holder,T t);

}

public class RBOutPhoneCallState {

Context ctx;

public RBOutPhoneCallState(Context ctx) {

this.ctx = ctx;

}

/**

* 前台呼叫状态

*

*/

public static final class ForeGroundCallState {

public static final String DIALING =

"com.sdvdxl.phonerecorder.FORE_GROUND_DIALING";

public static final String ALERTING =

"com.sdvdxl.phonerecorder.FORE_GROUND_ALERTING";

public static final String ACTIVE =

"com.sdvdxl.phonerecorder.FORE_GROUND_ACTIVE";

public static final String IDLE =

"com.sdvdxl.phonerecorder.FORE_GROUND_IDLE";

public static final String DISCONNECTED =

"com.sdvdxl.phonerecorder.FORE_GROUND_DISCONNECTED";

}

/**

* 开始监听呼出状态的转变,

* 并在对应状态发送广播

*/

public void startListen() {

new RBReadPhoneLog(ctx).start();

Log.d("Recorder", "开始监听呼出状态的转变,并在对应状态发送广播");

}

}

public class RBPhoneListener extends PhoneStateListener {

public RBRecorder recorder;

@Override

public void onCallStateChanged(int state, String incomingNumber) {

super.onCallStateChanged(state, incomingNumber);

switch (state) {

case TelephonyManager.CALL_STATE_IDLE: // 空闲状态,即无来电也无去电

Log.i("TelephoneState", "IDLE");

//此处添加一系列功能代码

if (recorder != null && !recorder.isCommingNumber() && recorder.isStarted()) {

Log.i("TelephoneState", "STOP RECORDER");

recorder.stop();

}

break;

case TelephonyManager.CALL_STATE_RINGING: // 来电响铃

Log.i("TelephoneState", "RINGING");

//此处添加一系列功能代码

break;

case TelephonyManager.CALL_STATE_OFFHOOK: // 摘机,即接通

Log.i("TelephoneState", "OFFHOOK");

//此处添加一系列功能代码

if (recorder == null) {

recorder = new RBRecorder();

}

if (!recorder.isStarted()) {

Log.i("TelephoneState", "START RECORDER");

if (incomingNumber != null && incomingNumber.length() >= 8) {

//CALLID

recorder.setPhoneNumber(String.valueOf(incomingNumber));

}

if (!recorder.isCommingNumber() && !recorder.isStarted()) {

recorder.start();

}

}

break;

}

Log.i("TelephoneState", String.valueOf(incomingNumber));

}

}

public class RBReadPhoneLog extends Thread {

private Context ctx;

private int logCount;

private static final String TAG = "LogInfo OutGoing Call";

/**

* 前后台电话

*

*/

private static class CallViewState {

public static final String FORE_GROUND_CALL_STATE = "mForeground";

}

/**

* 呼叫状态

*

*/

private static class CallState {

public static final String DIALING = "DIALING";

public static final String ALERTING = "ALERTING";

public static final String ACTIVE = "ACTIVE";

public static final String IDLE = "IDLE";

public static final String DISCONNECTED = "DISCONNECTED";

}

public RBReadPhoneLog(Context ctx) {

this.ctx = ctx;

}

/**

* 读取Log流

* 取得呼出状态的log

* 从而得到转换状态

*/

@Override

public void run() {

Log.d(TAG, "开始读取日志记录");

String[] catchParams = {"logcat", "InCallScreen *:s"};

String[] clearParams = {"logcat", "-c"};

try {

Process process=Runtime.getRuntime().exec(catchParams);

InputStream is = process.getInputStream();

BufferedReader reader = new BufferedReader(new InputStreamReader(is));

String line = null;

while ((line=reader.readLine())!=null) {

logCount++;

//输出所有

Log.v(TAG, line);

//日志超过512条就清理

if (logCount>512) {

//清理日志

Runtime.getRuntime().exec(clearParams)

.destroy();//销毁进程,释放资源

logCount = 0;

Log.v(TAG, "-----------清理日志---------------");

}

/*---------------------------------前台呼叫-----------------------*/

//空闲

if (line.contains(RBReadPhoneLog.CallViewState.FORE_GROUND_CALL_STATE)

&& line.contains(RBReadPhoneLog.CallState.IDLE)) {

Log.d(TAG, RBReadPhoneLog.CallState.IDLE);

}

//正在拨号,等待建立连接,即已拨号,但对方还没有响铃,

if (line.contains(RBReadPhoneLog.CallViewState.FORE_GROUND_CALL_STATE)

&& line.contains(RBReadPhoneLog.CallState.DIALING)) {

//发送广播

Intent dialingIntent = new Intent();

dialingIntent.setAction(RBOutPhoneCallState.ForeGroundCallState.DIALING);

ctx.sendBroadcast(dialingIntent);

Log.d(TAG, RBReadPhoneLog.CallState.DIALING);

}

//呼叫对方 正在响铃

if (line.contains(RBReadPhoneLog.CallViewState.FORE_GROUND_CALL_STATE)

&& line.contains(RBReadPhoneLog.CallState.ALERTING)) {

//发送广播

Intent dialingIntent = new Intent();

dialingIntent.setAction(RBOutPhoneCallState.ForeGroundCallState.ALERTING);

ctx.sendBroadcast(dialingIntent);

Log.d(TAG, RBReadPhoneLog.CallState.ALERTING);

}

//已接通,通话建立

if (line.contains(RBReadPhoneLog.CallViewState.FORE_GROUND_CALL_STATE)

&& line.contains(RBReadPhoneLog.CallState.ACTIVE)) {

//发送广播

Intent dialingIntent = new Intent();

dialingIntent.setAction(RBOutPhoneCallState.ForeGroundCallState.ACTIVE);

ctx.sendBroadcast(dialingIntent);

Log.d(TAG, RBReadPhoneLog.CallState.ACTIVE);

}

//断开连接,即挂机

if (line.contains(RBReadPhoneLog.CallViewState.FORE_GROUND_CALL_STATE)

&& line.contains(RBReadPhoneLog.CallState.DISCONNECTED)) {

//发送广播

Intent dialingIntent = new Intent();

dialingIntent.setAction(RBOutPhoneCallState.ForeGroundCallState.DISCONNECTED);

ctx.sendBroadcast(dialingIntent);

Log.d(TAG, RBReadPhoneLog.CallState.DISCONNECTED);

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

public class RBRecorder {

private String phoneNumber;

private MediaRecorder mrecorder;

private boolean started = false; // 录音机是否启动

private boolean isCommingNumber = false;// 是否是来电

private String TAG = "Recorder";

public RBRecorder(String phoneNumber) {

this.setPhoneNumber(phoneNumber);

}

public RBRecorder() {

}

public void start() {

started = true;

mrecorder = new MediaRecorder();

String fileName = new SimpleDateFormat("yy-MM-dd_HH-mm-ss")

.format(new Date(System.currentTimeMillis())) + ".mp3";

String fileSavePath = getFilePath(fileName);

File recordName = new File(fileSavePath);

try {

recordName.createNewFile();

Log.d("recorder", "创建文件" + recordName.getName());

} catch (IOException e) {

e.printStackTrace();

}

mrecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);

mrecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);

mrecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);

mrecorder.setOutputFile(recordName.getAbsolutePath());

try {

mrecorder.prepare();

} catch (IllegalStateException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

mrecorder.start();

started = true;

Log.d(TAG, "录音开始");

}

public void stop() {

try {

if (mrecorder != null) {

mrecorder.stop();

// reset

mrecorder.release();

mrecorder = null;

}

started = false;

} catch (IllegalStateException e) {

e.printStackTrace();

}

Log.d(TAG, "录音结束");

}

public void pause() {

}

public String getPhoneNumber() {

return phoneNumber;

}

public void setPhoneNumber(String phoneNumber) {

this.phoneNumber = phoneNumber;

}

public boolean isStarted() {

return started;

}

public void setStarted(boolean hasStarted) {

this.started = hasStarted;

}

public boolean isCommingNumber() {

return isCommingNumber;

}

public void setIsCommingNumber(boolean isCommingNumber) {

this.isCommingNumber = isCommingNumber;

}

private String getFilePath(String fileName) {

File sdcardDir = null;

boolean sdcardExist = Environment.getExternalStorageState().equals(

android.os.Environment.MEDIA_MOUNTED);

if (sdcardExist) {

sdcardDir = Environment.getExternalStorageDirectory();

}

String filePath = sdcardDir.toString() + "/Recorder/Recorder";

File file = new File(filePath);

if (!file.exists()) {

file.mkdirs();

}

return filePath + "/" + fileName;

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 Android实现通话自动录音 的全部内容, 来源链接: utcz.com/p/243079.html

回到顶部