使用新的存储访问框架(SAF)将视频录制到外部SD卡时出现IllegalStateException

时间:2016-06-07 20:17:41

标签: android android-sdcard android-mediarecorder android-external-storage

我有以下方法,它适用于Android 4.3或更早版本的内部存储和外部SD卡:

    public void Recorder_Prepare() {        
        recorder = new MediaRecorder();
        recorder.setPreviewDisplay(holder.getSurface());
        mCamera.unlock();
        recorder.setCamera(mCamera);
        recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        recorder.setProfile(camcorderProfile);
        recorder.setVideoSize(ResolutionWidth, ResolutionHeight);

        File DirectoryExistCheck = new File(VideoFolderAbsolutePATH);
        if(!DirectoryExistCheck.exists()) {
            DirectoryExistCheck.mkdir();
        }

        String VideoPath = VideoFolderAbsolutePATH + separator + "Video.mp4"; 
        File NewVideoFile = new File(VideoPath);
        recorder.setOutputFile(NewVideoFile.getAbsolutePath());

        recorder.setVideoFrameRate(camcorderProfile.videoFrameRate);

          try {
              recorder.prepare();
          } 
          catch (IllegalStateException e) {
              Log.e("MyTag", "IllegalStateException : " + Log.getStackTraceString(e)); }        
          catch (IOException e) { 
              Log.e("MyTag", "IOException : " + Log.getStackTraceString(e)); } 

            recorder.start();
    }

........

........

现在我正在使用适用于Android 5.0 +的新存储访问框架选择一个文件夹:

    public void FolderSelection_Lollipop() {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
        startActivityForResult(intent, PICK_FOLDER_CODE_Lollipop);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent resultData) {  
        if(requestCode == PICK_FOLDER_CODE_Lollipop) {
            if(resultCode == RESULT_OK) {
                // Get Uri from Storage Access Framework.
                Uri Uri_Lollipop = resultData.getData();    
                VideoFolderAbsolutePATH = Uri_Lollipop.getPath();
                //also tried:
                VideoFolderAbsolutePATH = Uri_Lollipop.toString();

                // Persist access permissions.
                this.getContentResolver().takePersistableUriPermission(Uri_Lollipop,
                        Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            }
        }
    }

Recorder_Prepare()方法没有用,因为它在Android 5.0+上给我IllegalStateException: - (

我也尝试按照此链接中的步骤操作:

Saving a video file with FileDesriptor

结果相同......

新的SAF似乎对我来说是一团糟,尽管我已经尝试过在线进行研究。

有没有人知道解决方法或解决方案?

非常感谢你的帮助和善意的时间。

...

更新:2016年6月8日上午10:41

上面的链接确实有效。这是Recorder_Prepare()的一个错误,所以我只是移动了一些东西并且工作了。

1 个答案:

答案 0 :(得分:2)

首先,选择一个文件夹并使用新的Storage Access Framework API授予其权限:

# adds ability to dynamically create instance vars & attr_accessors
module Attributable
  def create_method(name, &block)
    self.class.send(:define_method, name.to_sym, &block)
  end

  def create_setter(m)
    create_method("#{m}=".to_sym) { |v| instance_variable_set("@#{m}", v) }
  end

  def create_getter(m)
    create_method(m.to_sym) { instance_variable_get("@#{m}") }
  end

  def set_attr(method, value)
    create_setter method
    send "#{method}=".to_sym, value
    create_getter method
  end
end

...

......

public void FolderSelection_Lollipop() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    startActivityForResult(intent, PICK_FOLDER_CODE_Lollipop);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {  
    if(requestCode == PICK_FOLDER_CODE_Lollipop) {
        if(resultCode == RESULT_OK) {
            // Get Uri from Storage Access Framework.
            Uri Uri_Lollipop = resultData.getData();    
            // Persist access permissions.
            this.getContentResolver().takePersistableUriPermission(Uri_Lollipop,
                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        }
    }
}

与我在问题中发布的方法没有太大区别。我只是移动了东西,它只是工作。我希望它可以帮助别人。 感谢Artem Pelenitsyn和CommonsWare的评论。