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;
 }

}

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

(0)

相关推荐

  • Android实现语音播放与录音功能

    本文实例为大家分享了Android实现语音播放与录音的具体代码,供大家参考,具体内容如下 项目用到的技术点和亮点 语音录音 (单个和列表) 语音播放(单个和列表) 语音录音封装 语音播放器封装 语音列表顺序播放 语音列表单个播放 复用问题处理 因为安装原生录音不能录mp3格式文件 而mp3格式是安卓和ios公用的,所以我们需要的是能直接录取mp3文件或者录完的格式转成mp3格式 下面添加这个库 能直接录mp3文件,我觉得是最方便的 compile 'com.czt.mp3recorder:lib

  • Android开发四大组件之实现电话拦截和电话录音

    一.问题描述 使用BordercastReceiver和Service组件实现下述功能: 1.当手机处于来电状态,启动监听服务,对来电进行监听录音. 2.设置电话黑名单,当来电是黑名单电话,则直接挂断. 当拨打电话或电话状态发生改变时,系统就会发出有序广播,因此我们可以使用BordercastReceiver接受广播,因BordercastReceiver执行时间短不能执行耗时任务也不能使用子线程,因此我们应启动一个Service来监听电话并进行处理 二.加入AIDL文件 Android没有对外

  • Android实现录音方法(仿微信语音、麦克风录音、发送语音、解决5.0以上BUG)

    先给大家展示下效果图,如果大家感觉不错,请参考使用方法, 效果图如下所示: 使用方法: 录音工具类:AudioRecoderUtils.java,代码如下: public class AudioRecoderUtils { //文件路径 private String filePath; //文件夹路径 private String FolderPath; private MediaRecorder mMediaRecorder; private final String TAG = "fan&q

  • Android音频录制MediaRecorder之简易的录音软件实现代码

    使用MediaRecorder的步骤:1.创建MediaRecorder对象2.调用MediRecorder对象的setAudioSource()方法设置声音的来源,一般传入MediaRecorder.MIC3.调用MediaRecorder对象的setOutputFormat()设置所录制的音频文件的格式4.调用MediaRecorder对象的setAudioRncoder().setAudioEncodingBitRate(int bitRate).setAudioSamlingRate(i

  • 详解Android开发录音和播放音频的步骤(动态获取权限)

    步骤: 配置权限: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.work.mediaplay"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> <us

  • Android应用开发:电话监听和录音代码示例

    在oncreate 中执行: 复制代码 代码如下: public void onCreate() {  super.onCreate();  Log.i("TAG", "服务启动了"); // 对电话的来电状态进行监听  TelephonyManager telManager = (TelephonyManager) this    .getSystemService(Context.TELEPHONY_SERVICE);  // 注册一个监听器对电话状态进行监听 

  • Android简单的利用MediaRecorder进行录音的实例代码

    复制代码 代码如下: package com.ppmeet; import java.io.IOException; import android.app.Activity;  import android.graphics.PixelFormat;  import android.media.MediaRecorder;  import android.os.Bundle;  import android.view.View;  import android.view.View.OnClick

  • Android App调用MediaRecorder实现录音功能的实例

    MediaRecorder Android的MediaRecorder包含了Audio和video的记录功能,在Android的界面上,Music和Video两个应用程序都是调用MediaRecorder实现的. MediaRecorder在底层是基于OpenCore(PacketVideo)的库实现的,为了构建一个MediaRecorder程序,上层还包含了进程间通讯等内容,这种进程间通讯的基础是Android基本库中的Binder机制. 以开源的Android为例MediaRecorder的

  • Android 实现电话来去自动录音的功能

    我们在使用Android手机打电话时,有时可能会需要对来去电通话自动录音,本文就详细讲解实现Android来去电通话自动录音的方法,大家按照文中的方法编写程序就可以完成此功能. 来去电自动录音的关键在于如何监听手机电话状态的转变: 1)来电的状态的转换如下(红色标记是我们要用到的状态) 空闲(IDEL)--> 响铃(RINGING)--> 接听(ACTIVE)--> 挂断(经历DISCONNECTING--DISCONNECTED)--> 空闲(IDEL) 或者  空闲(IDEL)

  • Android实现录音功能实现实例(MediaRecorder)

    本文介绍了Android实现录音的实例代码(MediaRecorder),分享给大家,具体如下: Android提供了两个API用于录音的实现:MediaRecorder 和 AudioRecord,各有优劣. 1.MediaRecorder 已经集成了录音.编码.压缩等,支持少量的录音音频格式,大概有.aac(API = 16) .amr .3gp 优点:大部分已经集成,直接调用相关接口即可,代码量小 缺点:无法实时处理音频:输出的音频格式不是很多,例如没有输出mp3格式文件 2.AudioR

随机推荐