将视频文件存储在 SD 卡中 Android 5

Store video files on SD card in Android 5

我正在借助 android.media.MediaRecorder class 录制视频,它接受输出文件的路径字符串 (MediaRecorder.setOutputFile(String)),尽管有一个版本的方法可以接受FileDescriptor.

我需要存储巨大的视频文件,所以我想使用SD卡。为了获得相关目录的路径,我使用 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)。事实证明,生成的路径是针对“模拟”存储(/sdcard/…)而不是真正的 SD 卡(在我的 Xperia Z3 Compact 上是 /sdcard1/,Android 5.1.1)。

我尝试对 /sdcard1/(以及 /storage/sdcard1)进行硬编码,但得到一个 IOException 谈论权限拒绝。当然,我有

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

我听说 4.4(又名存储访问框架)后对 SD 卡的访问发生了巨大变化,但找不到足够简单明了的解释来说明在这种情况下如何完成工作。对此的简短解决方案有帮助吗?

PS 具有硬编码路径的解决方案对我来说是可以的,因为我打算仅将此应用程序与我的 phone.

一起使用

所以我不得不按照上面提到的 Storage Access Framework.

进行“完整的循环”

第 1 步:请求创建文件

注意:下面的 fileName 是文件本身的字面名称,没有完整的(所需的)路径。例如。 myvideo.mp4.

private void createFile(String fileName) {
    String mimeType = "video/mp4";
    Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);

    intent.addCategory(Intent.CATEGORY_OPENABLE);

    intent.setType(mimeType);
    intent.putExtra(Intent.EXTRA_TITLE, fileName);
    startActivityForResult(intent, WRITE_REQUEST_CODE /* is some random int constant*/);
}

第 2 步:处理目录选择的回调

调用 createFile 后(参见第 1 步),将向用户提供一个系统对话框,用于选择存储文件的目录。在他们做出选择后,将使用新文件所需的 URI 触发处理程序。我们可以把它变成 FileDescriptor 并使用相应版本的 MediaRecorder.setOutputFile.

@Override
public void onActivityResult(int requestCode, int resultCode,
                             Intent resultData) {

    if (requestCode == WRITE_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        if (resultData != null) {
            URI outputFileUri = resultData.getData();
            FileDesriptor outputFileDescriptor = getContentResolver().openFileDescriptor(outputFileUri, "w").getFileDescriptor()
            mMediaRecorder.setOutputFile(outputFileDescriptor);
            mMediaRecorder.start();
        }
    }
}

这个方法应该在someActivity-class.

里面实现

改进空间

因此用户每次开始新视频时都必须在系统菜单中单击 Save。当我的应用程序可以自行决定目录时,恢复 KitKat 之前的状态会很好。考虑到我的经验,如果使用“专业”应用程序,这确实是可能的。例如。 “ES Explorer”仅要求用户明确授予对SD卡的操作权限一次(使用类似的系统对话框)。

此代码应该可以解决您的问题:

 public String createVideoFilePath() {
        String time = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File[] pathsArray = getExternalFilesDirs(Environment.DIRECTORY_DCIM);

/通常,pathArray[1] 包含路径到 可移动 SD 上的必要文件夹 卡片。所以我们通常可以只使用 pathArray[1] 而不是使用 for statement/

在 pathArray 中搜索必要的文件
        for (File f : pathsArray) {
            if ((f != null) && (Environment.isExternalStorageRemovable(f))) {
                return f.getPath() + File.separator +"video_"+ time + ".mp4";
            }
        }

        return pathsArray[0].getPath() + File.separator +"video_"+ time + ".mp4";

    }

此方法 returns 文件在可移动 SD 卡或模拟存储中的位置(如果可移动 SD 不存在)

只需将此方法用作 MediaRecorder.setOutputFile(String) 的参数即可 更新: 非常重要的一点是,所有位于文件夹中的文件,通过 Context. getExternalFilesDirs(String typr) 获取的文件都将在卸载您的应用程序后被删除。