概述
一、音频录制
音频录制动作为MediaStore.Audio.Media.RECORD_SOUND_ACTION。这个动作不支持通过EXTRA_OUTPUT属性设置目标音频文件(拍照和视频录制动作支持设置目标文件),只能从返回的Intent中获得生成的音频在MediaStore中的Uri。音频的Uri格式为:
content://media/external/audio/media/202300
最后的数字是音频在MediaStore中的ID,再通过MediaStore的ContentProvider可得到文件位置等信息。再根据需要进行处理,比如可以将文件拷贝到应用的目录下。
下面是具体的启动录制音频界面的代码:
Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
startActivityForResult(intent, RECORD_AUDIO);
启动后的界面如下图:
录音完成退出录音界面后,会调用主活动的onActivityResult方法。所以在该方法中,对新录制的音频进行处理。录制音频返回新生成的音频,Uri格式,一般将文件拷贝到需要的目录。代码如下:
if(requestCode==RECORD_AUDIO && resultCode==RESULT_OK) {
Uri uri = data.getData(); // 获得生成音频的uri
Toast.makeText(this, "录制音频成功, uri=" + uri, Toast.LENGTH_LONG).show();
Log.i("zzk", "录制音频成功, uri=" + uri);
String srcPath = getAudioPathFromUri(uri); // 从MediaStore查到音频文件存放位置
File source = new File(srcPath);
if(!FileUtil.copyFile(source, audioFile)) { // 将音频文件拷贝到audioFile
Toast.makeText(this, "文件拷贝失败", Toast.LENGTH_LONG).show();
}
}
其中的getAudioPathFromUri方法从MediaStore查到音频文件存放位置,代码如下:
String getAudioPathFromUri(Uri uri){
// 根据uri,查询MediaStore
Cursor cursor = this.getContentResolver().query(uri, new String[]{MediaStore.Audio.Media.DATA}, null, null, null);
if (cursor != null) {
cursor.moveToFirst(); // 取查询结果的第一条记录
int index = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);
String path = cursor.getString(index); // 取该记录的MediaStore.Audio.Media.DATA字段,即为文件路径
return path;
}
return null;
}
目标文件audioFile定义在应用自己的文件目录下的test子目录中。Android 6以后不允许在根目录下创建目录,只允许在应用自己的文件目录下创建目录。应用自己的文件目录通过getExternalFilesDir(null)获得,实际为:Android/data/<package-name>/files/。代码如下:
File path = new File(getExternalFilesDir(null),"test/");
if(!path.exists())path.mkdirs();
audioFile = new File(path, "audio.aac");
文件拷贝的代码单独写到了FileUtil类的copyFile方法中,流程是循环读取源文件的内容写入到目标文件。
二、音频选择
音频选择采用通用的文档选择动作Intent.ACTION_GET_CONTENT,只选择音频文件只需将类型设置为audio/*。返回的Intent中有选中音频的Uri,但该Uri有两种格式需要分别处理:
1)Android4.4及更高版本返回文档类型的uri,格式为:
content://com.android.providers.media.documents/document/audio:610
处理时需要先把最后的音频id取出来,上面的例子中为610;再根据id查询MediaStore获得音频文件的存放路径等信息。
2)低于Android4.4的版本返回音频在MediaStore中的uri,格式为:
content://media/external/audio/media/610
处理时直接用这个uri去查询MediaStore即可获得音频文件的存放路径等信息。
有了音频文件的存放路径,就可以再根据需要进一步处理,比如可以将文件复制到应用的目录下。
下面是具体的启动音频选择界面的代码:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("audio/*");
startActivityForResult(intent, PICK_AUDIO);
调用后会打开音频选择界面,如下图:
用户选择音频后会返回一个已有的音频,所以后续操作一般是将文件复制到需要的目录。需要注意返回的音频Uri分两种格式分别处理,具体代码如下:
if (requestCode == PICK_AUDIO && resultCode == RESULT_OK) {
Uri uri = data.getData();
Toast.makeText(this, "选择音频成功, uri=" + uri, Toast.LENGTH_LONG).show();
Log.i("zzk", "选择音频成功, uri=" + uri);
String filePath = null; // 以下代码从uri中获取音频文件的路径
if(DocumentsContract.isDocumentUri(this, uri)){ // Android4.4 及以上版本的uri格式
String docId = DocumentsContract.getDocumentId(uri); // docId格式为:audio:610
String id = docId.split(":")[1]; // 获得文件id,即:后的部分,上例中为610
// 根据文件id查询MediaStore
Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,
MediaStore.Audio.Media._ID+"="+id, null, null);
// 从查询结果中获得文件路径
if(cursor!=null) {
if(cursor.moveToFirst()){
int columnId = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);
filePath = cursor.getString(columnId);
}
cursor.close();
}
} else { // Android 4.4 之前版本的uri格式
filePath = getAudioPathFromUri(uri); // 从MediaStore查到音频文件存放位置
}
File source = new File(filePath);
if(!FileUtil.copyFile(source, audioFile)) { // 将音频文件拷贝到audioFile
Toast.makeText(this, "文件拷贝失败", Toast.LENGTH_LONG).show();
}
}
三、音频播放
音频播放采用通用的文件查看动作Intent.ACTION_VIEW,将类型设置为audio/*,并将要播放的音频文件以uri格式放入Data中。以Android 7版本为分界,Uri格式分为“file://”格式和FileProvider格式两种。
具体的调用播放音频界面的代码如下:
File path = new File(getExternalFilesDir(null),"test/"); // 值为Android/data/<package-name>/files/test/
audioFile = new File(path, "audio.aac"); // 要播放的音频文件
if(Build.VERSION.SDK_INT>=24){ // Android 7 以后不能直接在intent中向其他应用传递文件,要使用FileProvider
fileProviderAuthority = getPackageName() + ".fileProvider";
audioUri = FileProvider.getUriForFile(MainActivity.this, fileProviderAuthority, audioFile);
} else { // Android 7 以前可以直接在intent中向其他应用分享文件
audioUri = Uri.fromFile(audioFile);
}
Intent intent = new Intent(Intent.ACTION_VIEW); // 查看文件动作
intent.setDataAndType(audioUri, "audio/*"); // 要查看的音频文件由audioUri指定,文件类型为音频
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 授予对方读取媒体文件的权限
startActivity(intent); // 调用播放音频应用
调用后,如果系统中有多个可以播放音频的应用,则会弹出一个选择界面,选择其中一个应用(比如“音乐”)后,就会用该应用播放音频。
对于播放音频界面没有需要处理的返回信息。
最后
以上就是闪闪耳机为你收集整理的Android多媒体功能开发(3)——调用系统Activity录制、选择、播放音频的全部内容,希望文章能够帮你解决Android多媒体功能开发(3)——调用系统Activity录制、选择、播放音频所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复