【问题标题】:Android Intent, Action Create Document, Opens the file explorer multiple times creating duplicate 0b filesAndroid Intent, Action Create Document, 多次打开文件资源管理器创建重复的0b文件
【发布时间】:2019-11-04 23:45:21
【问题描述】:

我正在开发一个用于填写 pdf 表单的应用程序,我正在将 pdf 保存到内部存储中,然后使用意图 ACTION_CREATE_DOCUMENT 共享它。此意图返回一个 URI,然后我将本地 pdf 复制到该 URI。

所有这一切都很好,但是意图打开一个文件资源管理器弹出窗口,以便用户可以选择保存 pdf 的位置,这就是问题所在,当用户按下 SAVE 时;该应用程序在该位置创建一个 0b 文件(应该如此),但随后它重新打开文件资源管理器,提示用户再次保存,这种情况发生了两到三次,然后它最终真正关闭,此时 pdf 数据覆盖现在众多的 0b 文件中的最新版本。

public int WRITE_REQUEST_CODE=45;
   ...
           @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public void buttonExport(View view) {
        Toast.makeText(this, "Exporting - This will take around 1min", Toast.LENGTH_LONG).show();

        // Template of PDF with acrofields (template.pdf).
        // TRY to open the pdf stored in the raw res directory
        // then convert it to a file object by copying it
        try {
            //

                InputStream inputStream =null;

            if (template.equals("crfminortemplate")){
                 inputStream = getResources().openRawResource(R.raw.crfminorpdftemplat);
            }
            else   if (template.equals("crfmajortemplate")){
                 inputStream = getResources().openRawResource(R.raw.crfmajorpdftemplat);
            }
            File tempFile = new File(getFilesDir(),template);
            //
            copyFile(inputStream, new FileOutputStream(tempFile));

            // Now Questions res is tempFile ..
        } catch (IOException e) {
            throw new RuntimeException("Can't create temp file ", e);
        }


        try {
            PDFManipulation.fillPDF(view, template, fileName, Answers);
        } catch (IOException e) {
            e.printStackTrace();
        }
        catch (NullPointerException e)
        {
            e.printStackTrace();
        }

        Toast.makeText(this, "Export Complete - save to drive or email", Toast.LENGTH_LONG).show();

       sharePDF(getFilesDir()+"/"+fileName+".pdf");


    }

    private void sharePDF(String PDFPPath) {
        Uri path = FileProvider.getUriForFile(this, "com.example.cst_app_v3", new File(getFilesDir(),fileName+".pdf"));
        Intent shareIntent = new Intent();

        shareIntent.setAction(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_TEXT, "Sent from CST App Android " + PDFPPath);
        shareIntent.putExtra(Intent.EXTRA_STREAM, path);
        shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        shareIntent.setType("application/pdf");
        startActivityForResult(shareIntent,0);
        Intent saveIntent = new Intent();
        saveIntent.setAction(Intent.ACTION_CREATE_DOCUMENT);
        saveIntent.putExtra(Intent.EXTRA_TITLE,fileName+".pdf");
        saveIntent.addCategory(Intent.CATEGORY_OPENABLE);
        saveIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        saveIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        saveIntent.setType("application/pdf");
        startActivityForResult(saveIntent,WRITE_REQUEST_CODE);

        Intent chooserIntent = Intent.createChooser(shareIntent, "Share or Save ...");
        Intent[]arrayofintent = {saveIntent};
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,arrayofintent);
        startActivityForResult(chooserIntent,0);
        startActivity(chooserIntent);

        Log.d("Alert",path.getAuthority()+" "+ path.getPath());
    }


 @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

        if (resultCode == RESULT_OK && requestCode == WRITE_REQUEST_CODE) {
       //DO THE COPY PASTE FROM LOCAL to THE URI data
       }
}

再次

我希望用户启动保存意图并在让用户命名文件并选择保存位置后弹出文件选择器,按保存,然后返回我的应用程序,将 pdf 复制到他们的位置指定

如果有人知道/经历过这个问题,或者认为他们知道可能发生的事情,很高兴收到您的来信。

【问题讨论】:

  • 你能展示你startActivityForResult(saveIntent,WRITE_REQUEST_CODE);的整个方法吗?我用ACTION_CREATE_DOCUMENT很好,没有这样的问题。因为您可能会触发多个意图。您能否提供有关您正在测试的 API 级别的详细信息。
  • 用该信息更新帖子给我一秒钟找到它。

标签: java android android-studio android-intent android-fileprovider


【解决方案1】:

每次调用startActivityForResultstartActivity 都会启动一个新的Activity。

所以我在您的示例代码中计算了其中的 4 个,但只有 2 个调用实际上会返回导致写入文件的结果。

要解决此问题,只需删除所有 startActivityForResultstartActivity 除了您更改为 startActivityForResult(chooserIntent,WRITE_REQUEST_CODE); 的第三个

这可行(已测试)但提供了非常糟糕的 UI 体验,因为您必须知道选择 Files 应用程序来保存文档。

最好将这些拆分为不同类型的操作,以单独的菜单项、按钮、浮动操作按钮,或者让用户“共享或保存”,因为您可以提供比 Intent 更好的 UI选择器。

【讨论】:

  • 这个解决方案有效......我还必须添加一个 1 秒计时器,然后再用 pdf 数据覆盖 0b 文件,因为没有间隙,应用程序会随着文件资源管理器打开而挂起,现在它运行起来会造成混乱与 ui 不同的线程并一直等到 ui 被加载...感谢您的帮助我不知道 StartActivityForResult 运行了意图
猜你喜欢
  • 2011-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-11
  • 1970-01-01
相关资源
最近更新 更多