【问题标题】:How to open file save dialog in android?如何在android中打开文件保存对话框?
【发布时间】:2011-12-21 08:08:16
【问题描述】:

我有一个网络服务,它根据图像 id 给我一个 byte[] 数组。我想将这些字节 [] 转换为文件并将文件存储在 android 上,用户希望在其中保存文件对话框,文件格式与其完全相同。

【问题讨论】:

    标签: android android-layout android-widget


    【解决方案1】:

    由于这是您搜索该主题时在 google 中的最高结果,并且在我研究它时让我很困惑,我想我为这个问题添加了一个更新。 从 Android 19 开始,有一个内置的保存对话框。您不需要任何权限来执行此操作(甚至不需要 WRITE_EXTERNAL_STORAGE)。 它的工作方式非常简单:

    //send an ACTION_CREATE_DOCUMENT intent to the system. It will open a dialog where the user can choose a location and a filename
    
    Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("YOUR FILETYPE"); //not needed, but maybe usefull
    intent.putExtra(Intent.EXTRA_TITLE, "YOUR FILENAME"); //not needed, but maybe usefull
    startActivityForResult(intent, SOME_INTEGER);
    
    ...
    
    //after the user has selected a location you get an uri where you can write your data to:
    
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
      if(requestCode == SOME_INTEGER && resultCode == Activity.RESULT_OK) {
        Uri uri = data.getData();
    
        //just as an example, I am writing a String to the Uri I received from the user:
    
        try {
          OutputStream output = getContext().getContentResolver().openOutputStream(uri);
    
          output.write(SOME_CONTENT.getBytes());
          output.flush();
          output.close();
        }
        catch(IOException e) {
          Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
        }
      }
    }
    

    更多: https://developer.android.com/guide/topics/providers/document-provider

    【讨论】:

    • 我的印象是 OutputStream.close() 会自动执行 flush()。但显然它没有。谢谢生病编辑它:D
    • intent.setType("/") 是我需要的。否则我得到“没有找到处理 Intent 的活动 - android.intent.action.OPEN_DOCUMENT”
    • intent.setType("/") ;
    【解决方案2】:

    Android SDK 不提供自己的文件对话框,因此您必须自己构建。

    【讨论】:

      【解决方案3】:

      您无法创建保存文件对话框,但您可以借助以下链接将文件从您的应用程序保存到 android sd 卡

      http://android-er.blogspot.com/2010/07/save-file-to-sd-card.html

      http://www.blackmoonit.com/android/filebrowser/intents#intent.pick_file.new

      【讨论】:

      • 请提供一个可用的链接,用户可以在其中选择他想要存储文件的位置。
      • 在您的应用程序中创建编辑文本或使用编辑文本创建对话框。在编辑文本中写入您要保存文件的路径。使用 getText() 获取路径并放置对象在文件中文件=新文件(extStorageDirectory,“er.PNG”);在 er.PNG.Than 的最后一段代码将是 File file = new File(extStorageDirectory, "OBJECT");
      【解决方案4】:

      首先,您应该创建一个用于保存文件的对话框意图,用户选择后,您可以在该目录上写入并指定文件,而无需任何读/写权限。 (自 Android 19 起)

      来源:https://developer.android.com/training/data-storage/shared/documents-files#create-file

         // Request code for creating a PDF document.
          private final int SAVE_DOCUMENT_REQUEST_CODE = 0x445;
          private File targetFile;
       
         private void createFile() {
                  Uri reportFileUri = FileProvider.getUriForFile(getApplicationContext(), getPackageName() + ".provider", targetFile);
              Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
              intent.addCategory(Intent.CATEGORY_OPENABLE);
              intent.setType("application/pdf");
              intent.putExtra(Intent.EXTRA_TITLE, targetFile.getName());
          
              // Optionally, specify a URI for the directory that should be opened in
              // the system file picker when your app creates the document.
              intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri);
              startActivityForResult(intent, SAVE_DOCUMENT_REQUEST_CODE );
          }
      
         
              @Override
              protected void onActivityResult(int requestCode, int resultCode, @Nullable 
                  Intent data) {
                  super.onActivityResult(requestCode, resultCode, data);
                  if (requestCode == SAVE_DOCUMENT_REQUEST_CODE && resultCode == RESULT_OK){
                      Uri uri = data.getData();
                      saveFile(uri);
                  }
              }
           
               private void saveFile(Uri uri) {
                      try {
                          OutputStream output = getContentResolver().openOutputStream(uri);
                          FileInputStream fileInputStream = new FileInputStream(targetFile);
                          byte[] bytes = new byte[(int) targetFile.length()];
                          fileInputStream.read(bytes, 0, bytes.length);
                          output.write(bytes);
                          output.flush();
                          output.close();
                          Log.i(TAG, "done");
                      } catch (IOException e) {
                          Log.e(TAG, "onActivityResult: ", e);
                      }
                  }
      

      【讨论】:

        【解决方案5】:

        @JodliDev 已经提供了接受的答案,但是 startActivityForResult 现在已被弃用,所以我想在这里使用 registerForActivityResult(ActivityResultContracts.CreateDocument()) 提供我的解决方案

        首先注册一个 ActivityResultLauncher,您可以在其中定义结果应该发生的情况。我们将取回可用于 OutpuStream 的 uri。但一定要一开始就初始化,否则会得到:

        片段必须在创建之前调用 registerForActivityResult()(即初始化、onAttach() 或 onCreate())。

        private var ics: String? = null
        private val getFileUriForSavingICS = registerForActivityResult(ActivityResultContracts.CreateDocument()) { uri ->
            if(ics.isNullOrEmpty())
                return@registerForActivityResult
            try {
                val output: OutputStream? =
                    context?.contentResolver?.openOutputStream(uri)
                output?.write(ics?.toByteArray())
                output?.flush()
                output?.close()
            } catch (e: IOException) {
                Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show()
            }
        }
        

        然后只需在需要的地方使用 .launch(...) 调用您的 ActivityResultLauncher。

        getFileUriForSavingICS.launch("filename.txt")
        

        就是这样 ;-) 您还可以仔细查看 ActivityResultContracts.CreateDocument()。此方法提供文档保存对话框,但内部还有其他有用的功能(例如用于启动相机意图)。退房: https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContracts 对于可能的 ActivityResultContracts

        https://developer.android.com/training/basics/intents/result 获取更多培训材料以及如何创建自定义合同的一些信息!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-19
          • 1970-01-01
          • 2021-11-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多