Android多媒体功能开发(3)——调用系统Activity录制、选择、播放音频

一、音频录制

音频录制动作为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多媒体功能开发-调用系统Activity的例子

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nanoage

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值