其他分享
首页 > 其他分享> > Android-录音功能直接拿去用(1),不可多得的干货

Android-录音功能直接拿去用(1),不可多得的干货

作者:互联网

             .putString("audio_name", mFileName)
            .putString("audio_path", mFilePath)
            .putLong("elpased", mElapsedMillis)
            .apply();
    if (mIncrementTimerTask != null) {
        mIncrementTimerTask.cancel();
        mIncrementTimerTask = null;
    }

    mRecorder = null;
}

```
###二、显示录音界面的 RecordAudioDialogFragment

用户进行的时候,总不能让 App 跳转到另外一个界面吧,这样用户体验并不是很好,比较好的方法是显示一个对话框,让用户进行操作,既然要用对话框,必然离不开 DialogFragment。

public class RecordAudioDialogFragment extends DialogFragment {
 
    private boolean mStartRecording = true;
 
    long timeWhenPaused = 0;
 
    private FloatingActionButton mFabRecord;
    private Chronometer mChronometerTime;
 
    public static RecordAudioDialogFragment newInstance(int maxTime) {
        RecordAudioDialogFragment dialogFragment = new RecordAudioDialogFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("maxTime", maxTime);
        dialogFragment.setArguments(bundle);
        return dialogFragment;
    }
 
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_record_audio, null);
 
        mFabRecord.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(getActivity()
                            , new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, 1);
                }else {
                    onRecord(mStartRecording);
                    mStartRecording = !mStartRecording;
                }
            }
        });
 
        builder.setView(view);
        return builder.create();
    }
 
    private void onRecord(boolean start) {
        Intent intent = new Intent(getActivity(), RecordingService.class);
        if (start) {
            File folder = new File(Environment.getExternalStorageDirectory() + "/SoundRecorder");
            if (!folder.exists()) {
                folder.mkdir();
            }
 
            mChronometerTime.setBase(SystemClock.elapsedRealtime());
            mChronometerTime.start();
            getActivity().startService(intent);
 
        } else {
            mChronometerTime.stop();
            timeWhenPaused = 0;
            getActivity().stopService(intent);
        }
    }
}

可以看到在 RecordAudioDialogFragment 有一个 newInstance(int maxTime) 的静态方法供外部调用,如果想设置录音的最大时长,直接传参数进去就行了。

好的,敲黑板,重点来了,其实这个对话框的重点部分就是在 onCreateDialog()中,我们先加载了我们自定义的对话框的布局,当点击录音的按钮的时候,先进行相关权限的申请,这里有个巨坑,录音权限 android.permission.RECORD_AUDIO 在不久前还是普通权限的,不知道什么时候突然变成了危险权限,需要我们进行申请,Google 真是会玩。

public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_record_audio, null);
 
        mFabRecord.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(getActivity()
                            , new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, 1);
                }else {
                    onRecord(mStartRecording);
                    mStartRecording = !mStartRecording;
                }
            }
        });
 
        builder.setView(view);
        return builder.create();
    }
 ```
申请好权限之后便会调用 onRecord() 这个方法,然后将 boolean mStartRecording 进行反转,这样就不用写难看的 if else 了,直接改变 mStartRecording 的值,然后在onRecord() 里面进行处理

接下来看下 onRecord 干了什么

private void onRecord(boolean start) {
Intent intent = new Intent(getActivity(), RecordingService.class);
if (mStartRecording) {
File folder = new File(Environment.getExternalStorageDirectory() + “/SoundRecorder”);
if (!folder.exists()) {
folder.mkdir();
}

        mChronometerTime.setBase(SystemClock.elapsedRealtime());
        mChronometerTime.start();
        getActivity().startService(intent);

    } else {
        mChronometerTime.stop();
        timeWhenPaused = 0;
        getActivity().stopService(intent);
    }
}
好吧,其实并没有干了什么大事,只是创建了保存录音文件的文件夹,然后根据mStartRecording 的值进行 RecordingService 的启动和关闭罢了。在启动时还顺便开始了 mChronometer 的计时显示,这是一个 Android 原生的显示计时的一个控件。

###三、播放录音的 PlaybackDialogFragment

其实,如果只是录音这一块的话,写个 MediaPlayer 就可以了,然而还要写播放的时间进度,以及显示一个稍微好看点的进度条,我能怎样,我也很烦啊。

外部调用这个对话框的时候,只需要传入一个包含录音文件信息的 RecordingItem,因为包含的信息比较多,所以最好将 RecordingItem 进行序列化。

public static PlaybackDialogFragment newInstance(RecordingItem item) {
PlaybackDialogFragment fragment = new PlaybackDialogFragment();
Bundle bundle = new Bundle();
bundle.putParcelable(ARG_ITEM, item);
fragment.setArguments(b);
return fragment;
}

好,重点又来了,来看看 onCreateDialog() 方法,在加载了布局之后,给 mSeekBar 设置监听,mSeekBar 是一个显示进度条的控件,当开始播放录音时候,将录音文件的时长,设置进 mSeekBar 里面,播放录音的同时,运行 mSeekBar,通过监听 mSeekBar 的进度,刷新显示的播放进度。

public Dialog onCreateDialog(Bundle savedInstanceState) {

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_media_playback, null);

    mTvFileLength.setText(String.valueOf(mFileLength));
    mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if(mMediaPlayer != null && fromUser) {
                mMediaPlayer.seekTo(progress);
                mHandler.removeCallbacks(mRunnable);

                long minutes = TimeUnit.MILLISECONDS.toMinutes(mMediaPlayer.getCurrentPosition());
                long seconds = TimeUnit.MILLISECONDS.toSeconds(mMediaPlayer.getCurrentPosition())
                        - TimeUnit.MINUTES.toSeconds(minutes);
                mCurrentProgressTextView.setText(String.format("%02d:%02d", minutes,seconds));

                updateSeekBar();

            } else if (mMediaPlayer == null && fromUser) {
                prepareMediaPlayerFromPoint(progress);
                updateSeekBar();
            }
        }

    });

    mPlayButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onPlay(isPlaying);
            isPlaying = !isPlaying;
        }
    });

    mTvFileLength.setText(String.format("%02d:%02d", minutes,seconds));
    builder.setView(view);
    return builder.create();
}
当点击播放录音的按钮之后,会调用 onPlay() 方法,然后根据 isPlaying(标识当前是否播放录音)的值,来调用不同的方法

private void onPlay(boolean isPlaying){
if (!isPlaying) {
if(mMediaPlayer == null) {
startPlaying(); //start from beginning
}
} else {
pausePlaying();
}
}

我们最关心的,莫过于 startPlaying() 这个方法,这个方法便是来开启播放录音的,我们首先将外部传入的有关的录音信息,设置给 MediaPlayer,然后开始调用mMediaPlayer.start() 进行录音的播放,然后调用 updateSeekbar() 实时更新进度条的内容。当 MediaPlayer 的内容播放完成后,调用 stopPlaying() 方法,关闭mMediaPlayer。

private void startPlaying() {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(item.getFilePath());
mMediaPlayer.prepare();
mSeekBar.setMax(mMediaPlayer.getDuration());

    mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mMediaPlayer.start();
            }
        });

    mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            stopPlaying();
        }
    });
    updateSeekBar();
}

```
以上便是本文的全部内容,喜欢的可以关注
###四.写在最后

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家

CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》
那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家**

[外链图片转存中…(img-5BDcMQx5-1630903838623)]

[外链图片转存中…(img-agEpKK4s-1630903838625)]

CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》

标签:mMediaPlayer,mStartRecording,录音,getActivity,干货,不可多得,new,Android,public
来源: https://blog.csdn.net/m0_61072747/article/details/120131789