android 解决通话录音时无法返回挂断状态的bug

据了解,安卓6.0开始不再支持通话录音,除非修改系统、系统放开权限、root,这也可以理解,毕竟这涉及到隐私问题,万一我一个亿的银行密码被人窃听了呢?

最近有个定制的系统有个需求--------通话录音,一切就绪后,发现一个BUG,普通手机都可以正常监听到通话的3个状态,but,这个破手机 TelephonyManager.CALL_STATE_IDLE 不返回,

最后用一个无法用理论解释的代码解决此问题,自定义一个service去录音,上代码:

package com.c.test.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.blankj.utilcode.util.ToastUtils;
import java.io.File;
import com.c.base.MyApplication;
import com.c.base.bean.BaseResp;
import com.c.base.http.OnHttpResultListener;
import com.c.base.http.ResponseHandler;
import com.c.test.ui.model.MobileModel;
import com.c.test.utils.AudioRecordUtil;


/**
 * 录音服务(用于录取通话记录)
 */
public class AudioRecordService extends Service {

    private String id;

    private TelephonyManager manager;
    private CustomPhoneStateListener phoneStateListener;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        // 注册通话状态监听
        manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        phoneStateListener = new CustomPhoneStateListener();
        manager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        id = intent.getStringExtra("id");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 注销电话状态监听
        manager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
        phoneStateListener = null;
    }

    /**
     * 通话状态监听器
     */
    public class CustomPhoneStateListener extends PhoneStateListener {

        @Override
        public void onCallStateChanged(int state, String phoneNumber) {
            super.onCallStateChanged(state, phoneNumber);
            Toast.makeText(getApplicationContext(), "state:" + state, Toast.LENGTH_SHORT).show();
            switch (state) {
                case TelephonyManager.CALL_STATE_RINGING:
                    // 响铃状态
                    ToastUtils.showShort("响铃状态");
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    // 接通状态,开始录音
                    ToastUtils.showShort("接通状态,开始录音");
                    AudioRecordUtil.getInstance(MyApplication.getInstance()).record(phoneNumber);
                    // 此handler就是解决问题的关键,目前无法用理论解释,望路过大神指教下
                    new Handler().post(new Runnable() {
                        @Override
                        public void run() {
                        }
                    });
                    break;
                case TelephonyManager.CALL_STATE_IDLE:
                    // 空闲状态,停止录音
                    ToastUtils.showShort("空闲状态,停止录音");
                    AudioRecordUtil.getInstance(MyApplication.getInstance()).release();
                    // 关闭自身服务
                    stopSelf();
                    break;
            }
        }
    }

}

录音工具类:

package com.c.test.utils;

import android.content.Context;
import android.media.MediaRecorder;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * 录音工具类
 */
public class AudioRecordUtil {

    private Context mContext;

    private MediaRecorder mediaRecorder;
    private static AudioRecordUtil mInstance;
    private File file;

    public static AudioRecordUtil getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new AudioRecordUtil(context);
        }

        return mInstance;
    }

    public AudioRecordUtil(Context context) {
        mContext = context;
    }

    /**
     * 开始录音
     * @param phoneNumber 拨打的号码
     */
    public void record(String phoneNumber) {
        if (mediaRecorder == null) {
            mediaRecorder = new MediaRecorder();
            if (phoneNumber == null) {
                phoneNumber = "null_";
            }
            // 录音存储路径
            String filePath = mContext.getExternalFilesDir(null).getAbsolutePath() + File.separator + "audioRecord";
            File directory = new File(filePath);
            if (!directory.exists()) {
                directory.mkdir();
            }
//            String date = new SimpleDateFormat("yyyy.MM.DD HH:mm:ss", Locale.getDefault()).format(new Date());
            file = new File(filePath + File.separator  + phoneNumber + "_" + System.currentTimeMillis() + ".3gp");
            try {
                if (!file.exists()) {
                    file.createNewFile();
                }
                mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                mediaRecorder.setOutputFile(file.getAbsolutePath());
                mediaRecorder.prepare();
                mediaRecorder.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void release() {
        if (mediaRecorder != null) {
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
        }
    }

    public File getFile() {
        return file;
    }
}

好了,又可以愉快玩耍了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值