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

时间:2016-02-23 09:39:48

标签: android android-5.0-lollipop android-sdcard android-5.1.1-lollipop sony-xperia

我在android.media.MediaRecorder类的帮助下录制视频,该类接受输出文件(MediaRecorder.setOutputFile(String))的路径字符串,尽管有一个接受{{1}的方法版本}。

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

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

IOException

我听说4.4(也就是存储访问框架)之后对SD卡的访问有了很大的变化,但是在这种情况下如何完成工作却找不到简单明了的解释。有关简短解决方案的任何帮助吗?

带有硬编码路径的PS解决方案对我来说没关系,因为我只能在手机上使用此应用程序。

2 个答案:

答案 0 :(得分:1)

所以我必须使用上面提到的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();
        }
    }
}

此方法应在某些 Activity - 类。

中实现

改进空间

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

答案 1 :(得分:1)

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

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

/ 通常,pathArray [1]包含路径 可移动SD上的必要文件夹 卡。所以我们通常只使用pathArray [1]而不是在pathArray中用for语句搜索必要的File /

        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";

    }

如果可移动SD不存在,此方法将返回可移动SD卡或模拟存储中的文件位置

只需将此方法用作MediaRecorder.setOutputFile(String)的参数 的更新 非常重要的是,卸载应用后,将删除位于文件夹中的所有文件Context. getExternalFilesDirs(String typr)