【问题标题】:How to write a file using Intent.ACTION_CREATE_DOCUMENT如何使用 Intent.ACTION_CREATE_DOCUMENT 编写文件
【发布时间】:2019-09-30 10:32:06
【问题描述】:

简单来说,我想将视图组转换为 jpg 图像文件。由于Environment.getExternalStorageDirectory 已弃用,我使用此意图Intent.ACTION_CREATE_DOCUMENT

private void createFile(String mimeType, String fileName) {
        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);
    }

onActivityResult(); 中,我得到了结果返回的 Uri。 我的问题是getExternalStorage() 我会使用

Bitmap bitmap = Bitmap.createBitmap(
                    containerLayout.getWidth(),
                    containerLayout.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            containerLayout.draw(canvas);
            FileOutputStream fileOutupStream = null;


            try {
                fileOutupStream = new FileOutputStream(fileName);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutupStream);
                fileOutupStream.flush();
                fileOutupStream.close();
                Toast.makeText(this, "saved " + fileName, Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                Toast.makeText(this, "something went wrong" + e.getMessage(), Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }

现在我得到了结果返回的 Uri,但是我不知道如何将所需的位图写入这个 Uri

@Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            if (resultCode == RESULT_OK && requestCode == WRITE_REQUEST_CODE) {
                Uri resultUri = data.getData();
//need help

}
}

【问题讨论】:

    标签: android android-intent bitmap fileoutputstream


    【解决方案1】:

    你需要使用getContentResolver().openOutputStream

            @Override
            protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
                if (resultCode == RESULT_OK && requestCode == WRITE_REQUEST_CODE) {
                    FileOutputStream fileOutupStream = getContentResolver().openOutputStream(data.getData());
                try {
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutupStream);
                    fileOutupStream.flush();
                    fileOutupStream.close();
                    Toast.makeText(this, "saved " + fileName, Toast.LENGTH_LONG).show();
                } catch (Exception e) {
                    Toast.makeText(this, "something went wrong" + e.getMessage(), Toast.LENGTH_SHORT).show();
                    e.printStackTrace();
                }
    
    }
    }
    

    【讨论】:

    • 在第 4 行分配 fileOutupStream 后,为什么要在第 6 行重新创建它?
    • 我认为这是复制粘贴错误,我只是将其从问题中的代码中保留下来
    • getContentResolver().openOutputStream(data.getData()) 这将创建一个 OutputStream,而不是 FileOutputStream
    【解决方案2】:

    这是在旧 API(API 21 之前)上使用 Intent.ACTION_CREATE_DOCUMENT 将文件从一个位置复制到另一个位置的最小示例。如有必要,您应该添加请求代码和结果代码处理。

        ...
        // Intent creation
        int REQUEST_CODE_ARBITRARY = 1;
        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
        // will trigger exception if no  appropriate category passed
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        // or whatever mimeType you want
        intent.setType("*text/plain");
        intent.putExtra(Intent.EXTRA_TITLE, "file_name_to_save_as");
        startActivityForResult(intent, REQUEST_CODE_ARBITRARY);
    
        // Handling result
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            // Example file to copy
            File sourceFile = getDatabasePath("MyDatabaseName");
    
            InputStream is = null;
            OutputStream os = null;
    
            // Note: you may use try-with resources if your API is 19+
            try {
                // InputStream constructor takes File, String (path), or FileDescriptor
                is = new FileInputStream(sourceFile);
                // data.getData() holds the URI of the path selected by the picker
                os = getContentResolver().openOutputStream(data.getData());
    
                byte[] buffer = new byte[1024];
                int length;
                while ((length = is.read(buffer)) > 0) {
                    os.write(buffer, 0, length);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    is.close();
                    os.close();
                } catch (IOException e) {
                    //
                }
            }
        }
    

    API 19+ 上更短的 try-catch:

                try (InputStream is = new FileInputStream(sourceFile); OutputStream os = getContentResolver().openOutputStream(data.getData())) {
                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = is.read(buffer)) > 0) {
                        os.write(buffer, 0, length);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-03
      • 2011-09-17
      • 2013-04-22
      • 2017-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多