71.android 简单的电话录音并保存到本地(来电和去电都支持)

导读:本篇文章讲解 71.android 简单的电话录音并保存到本地(来电和去电都支持),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

71.android 简单的电话录音并保存到本地(来电和去电都支持)

 //第一步 先加权限 在AndroidManifest.xml里:

//有打电话的权限,读写权限,还有录音权限。 

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

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

//在AndroidManifest.xml里再声明自定义的Service:<service android:name=”.TelService”/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />

        </intent-filter>
    </activity>

    <service android:name=".TelService"/>
</application>

 

//第二步 自定义TelService类继承Service:

 //来电录音或去电录音

//既然来电录音,当然要开启一个后台服务。

//所以先写一个TelService,然后得到TelephonyManager。

public class TelService extends Service {
    TelListener telListener;
    TelephonyManager manager;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("TAG——TelService", "启动了。。。。。。。。。。。。。。。。。。。。。。。。。。。====------》》》》》》");
        if (manager == null) {
            manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        }
        if (telListener == null) {
            telListener = TelListener.getInstense(this);
        }
        telListener.setRecordState(true);
        manager.listen(telListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    @Override
    public void onDestroy() {
        Log.e("TAG——TelService", "销毁了。。。。。。。。。。。。。。。。。。。。。。。。。。。====------》》》》》》");
        telListener.setRecordState(false);
        super.onDestroy();
    }
    
}

//第三步 写个TelListener类继承PhoneStateListener:

//这个监听是继承PhoneStateListener,里面有个方法onCallStateChanged,这个方法一直在监听电话的状态。

//一般来电是用到三个状态CALL_STATE_IDLE:空闲

//CALL_STATE_RINGING:来电 

//CALL_STATE_OFFHOOK:接通,

//一般来电的电话状态的变化是:空闲-》来电-》接通-》空闲,这是其整个过程。

//而去电时是没有CALL_STATE_RINGING: 来电这个状态的。

public class TelListener extends PhoneStateListener {
    private MediaRecorder mediaRecorder;
    private String recordPath;
    static boolean recordState = false;// 是否开启了服务
    private boolean isRecording = false;// 时候正在录音
    private boolean isOffhooked = false;// 是否已经接通
    //    private boolean isRinging = false;// 来电标识
    private Context context;
    private String number = "";
    private String createTime;
    private static TelListener telListener;

    private TelListener(Context context) {
        this.context = context;
    }

    public static TelListener getInstense(Context context) {
        if (telListener == null) {
            telListener = new TelListener(context);
        }
        return telListener;
    }

    public void setRecordState(boolean state) {
        recordState = state;
    }

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        super.onCallStateChanged(state, incomingNumber);
        if (recordState) {
            if (!TextUtils.isEmpty(incomingNumber)) {
                number = incomingNumber;
            }
            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:// 空闲
                    Log.e("TAG1", "===============CALL_STATE_IDLE空闲==============");
                    // 音频数据上传到服务器
                    if (isRecording) {
                        stopRecord(mediaRecorder);
                        isRecording = false;
                        if (!TextUtils.isEmpty(recordPath) && isOffhooked) {
                            isOffhooked = false;
                            //这里可以写一些录完音之后的一些后学操作
                            //也可以写一个回调
                        }
                    }
//                    isRinging = false;
                    break;

                case TelephonyManager.CALL_STATE_RINGING:// 来电
                    Log.e("TAG2", "===============CALL_STATE_RINGING来电==============");
//                    isRinging = true;
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:// 接通
                    Log.e("TAG3", "===============CALL_STATE_OFFHOOK接通==============");
                    if (!isRecording) {
                        startRecordAudio(number);
                        number = "";
                        isRecording = true;
                        isOffhooked = true;
                    }
                    break;
                default:
                    break;
            }
        }
    }


    /**
     * 描述:开始录音
     */
    private void startRecordAudio(String number) {
        mediaRecorder = new MediaRecorder();
        // 存放的文件路径
        File soundFile = null;
        try {
            soundFile = new File(Environment.getExternalStorageDirectory()
                    .getCanonicalPath() + "/song");
            createTime = MessageFormat.format("{0,date,yyyy-MM-dd-HH-mm-ss}",
                    new Object[]{new Date(System.currentTimeMillis())});
            //把号码值空
            if (TextUtils.isEmpty(number)) {
                number = "";
            }
            File file = new File(soundFile, number + "电话录音" + createTime
                    + ".amr");
            recordPath = file.getAbsolutePath();
            // 录音
            new MediaRecordUtil(context).StartMediaRecord(file, mediaRecorder);
            Log.e("TAGXX", file.length() + "-------------------" + recordPath.length() + "-----------------" + soundFile.length());
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (!soundFile.exists()) {
            try {
                soundFile.mkdirs();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 停止录音
     *
     * @param mediaRecorder
     */
    private void stopRecord(MediaRecorder mediaRecorder) {
        if (mediaRecorder != null) {
            new MediaRecordUtil(context).StopmediaRecorder(mediaRecorder);
        }
    }
}

//第四步 写个MediaRecordUtil类继承Activity:

 //接下来这个就是录音类,这里是使用的MediaRecorder,这个录音类在接通状态下执行。

 

public class MediaRecordUtil extends Activity {
    private Context mContext;

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

    public void StartMediaRecord(File soundFile, MediaRecorder mediaRecorder) {
        // 先检测下是否含有SDCard
        if (!Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            Toast.makeText(mContext, "SD卡不存在,请插入SD卡", Toast.LENGTH_LONG)
                    .show();
            return;
        }
        try {
            // 创建音频输出的文件路径soundFile
            // 设置录音的来源为麦克风
            //       华为,酷派可以
            //----------------------------------重要-------------------------------------------------
            //VOICE_CALL:语音呼叫,VOICE_COMMUNICATION:语音通信,MIC:麦克风,VOICE_RECOGNITION:语音识别。
            // VOICE_DOWNLINK:语音下行链路,VOICE_UPLINK:语音上行链路。
            //经过我的测试发现以下问题,测试手机:红米note4。
            //小米手机设置MediaRecorder.AudioSource设置调用的时候,
            // 调用MIC可以正常保存录音,VOICE_COMMUNICATION也可以,VOICE_RECOGNITION也可以,
            // 但是设置为VOICE_CALL就不行,VOICE_DOWNLINK也不行,VOICE_UPLINK也不行。
            //如果设置成VOICE_CALL,那么保存后的文件大小会为0b,就是为空。
            //例如:mediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
            //------------------------------------------------------------------------------------------
            if ("xiaomi".equalsIgnoreCase(android.os.Build.BRAND)) {
                mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            } else {
                mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            }
            // 设置录制的声音输出格式
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
            // 设置声音的编码格式
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            // 设置录音的输出文件路径
            mediaRecorder.setOutputFile(soundFile.getAbsolutePath());
            // 做预期准备
            mediaRecorder.prepare();
            // 开始录音
            mediaRecorder.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止录音
     **/
    public void StopmediaRecorder(MediaRecorder mediaRecorder) {
        try {
            if (mediaRecorder != null) {
                mediaRecorder.stop();
                // 释放资源
                mediaRecorder.release();
                mediaRecorder = null;
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除录音文件
     **/
    public void DeleteAudio(File soundFile) {
        if (soundFile.exists()) { // 判断文件是否存在
            if (soundFile.isFile()) { // 判断是否是文件
                soundFile.delete(); // delete()方法 你应该知道 是删除的意思;
            }
        }
    }

}

 

 //第五步 在Activity里去电(来电时)使用:

 //Activity里我写了个Button按钮,点击就打电话,并且开启这个监听的服务。在Button按钮的点击事件里,我注释了一些代码,它可以用来关闭掉这个监听服务。

 

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btn_recorder;
    //拨号请求码
    public static final int REQUEST_CALL_PERMISSION = 10111;
    //布尔值用来点击按钮开启或者关闭录音
    boolean isOpening = false;

    //录音权限初始化
    private static final int READ_PHONE_STATE = 1;
    private static String[] CALLS_STATE = {
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.RECORD_AUDIO,
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        //调用请求6.0录音权限的方法
        verifyStoragePermissions(this);
    }

    private void initView() {
        btn_recorder = (Button) findViewById(R.id.btn_recorder);

        btn_recorder.setOnClickListener(this);
    }

    //点击事件,点击开始拨打10086,并且启动了录音监听服务
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_recorder:
                call("tel:" + "10086");
                Intent intent = new Intent(MainActivity.this, TelService.class);
                startService(intent);
//                if (isOpening) {
//                    stopService(intent);
//                    btn_recorder.setText("开启");
//                    isOpening = false;
//                    Toast.makeText(this, "关闭录音功能", Toast.LENGTH_SHORT).show();
//                } else {
//                    startService(intent);
//                    btn_recorder.setText("关闭");
//                    isOpening = true;
//                    Toast.makeText(this, "打开录音功能", Toast.LENGTH_SHORT).show();
//                }
                break;
        }
    }

    //打电话申请权限,
    public boolean checkReadPermission(String string_permission, int request_code) {
        boolean flag = false;
//已有权限
        if (ContextCompat.checkSelfPermission(this, string_permission) == PackageManager.PERMISSION_GRANTED) {
            flag = true;
        } else {
//申请权限
            ActivityCompat.requestPermissions(this, new String[]{string_permission}, request_code);
        }
        return flag;
    }

    //逻辑判断,是否允许打电话权限
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
//拨打电话
            case REQUEST_CALL_PERMISSION:
//失败,吐司
                if (permissions.length != 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "请允许拨号权限后再试", Toast.LENGTH_SHORT).show();
                } else {
//成功,直接调用开始拨打方法
                    call("tel:" + "10086");
                }
                break;
        }
    }

    //申请到权限后打电话
    public void call(String telPhone) {
        if (checkReadPermission(Manifest.permission.CALL_PHONE, REQUEST_CALL_PERMISSION)) {
            Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(telPhone));
            startActivity(intent);
        }
    }

    //6.0录音动态权限
    public static void verifyStoragePermissions(Activity activity) {
        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_PHONE_STATE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity, CALLS_STATE, READ_PHONE_STATE);
        }

    }

}

//我的Activity布局,就一个Button按钮:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.hasee.a926luyin.MainActivity">



    <Button
        android:id="@+id/btn_recorder"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="录音"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

//最后我的这个录音的文件是存到我手机存储里了,因为我手机里SD卡,如果有SD卡那么你就去SD卡的song文件夹里找这个录音文件,如果没有SD卡,那么就去你手机存储里找这个song文件夹。   话说现在的手机应该都不装SD卡了吧!

//—————————————————————-完———————————————————————–

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/118323.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!