Android 意图,操作创建文档,多次打开文件资源管理器创建重复的 0b 文件
Android Intent, Action Create Document, Opens the file explorer multiple times creating duplicate 0b files
我正在开发一个用于填写 pdf 表单的应用程序,我将 pdf 保存到内部存储,然后使用 intent ACTION_CREATE_DOCUMENT 共享它。这个意图 return 是一个 URI,然后我将我的本地 pdf 复制到其中。
所有这一切工作正常,但是意图打开一个文件资源管理器弹出窗口,以便用户可以选择保存 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
}
}
再次
我希望用户启动保存意图并让文件选择器弹出,一旦让用户命名文件并选择保存位置,按保存,然后 return 到我的 pdf 所在的应用程序被复制到他们指定的位置
如果有人 knows/has 遇到过这个问题或认为他们知道可能会发生什么,那么很高兴收到您的来信。
每次调用 startActivityForResult
或 startActivity
都会启动一个新的 Activity.
所以我在您的示例代码中计算了其中的 4 个,但实际上只有 2 个调用会 return 导致写入文件的结果。
要解决此问题,只需删除所有 startActivityForResult
或 startActivity
,除了您更改为 startActivityForResult(chooserIntent,WRITE_REQUEST_CODE);
的第三个
这有效(已测试)但提供了非常糟糕的 UI 体验,因为您必须知道 select Files
应用程序才能保存文档。
最好将它们拆分为不同类型的操作,分别放在单独的菜单项、按钮、浮动操作按钮中,或者让用户使用 "Share or Save",因为您可以提供更好的 UI 比 Intent 选择器。
我正在开发一个用于填写 pdf 表单的应用程序,我将 pdf 保存到内部存储,然后使用 intent ACTION_CREATE_DOCUMENT 共享它。这个意图 return 是一个 URI,然后我将我的本地 pdf 复制到其中。
所有这一切工作正常,但是意图打开一个文件资源管理器弹出窗口,以便用户可以选择保存 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
}
}
再次
我希望用户启动保存意图并让文件选择器弹出,一旦让用户命名文件并选择保存位置,按保存,然后 return 到我的 pdf 所在的应用程序被复制到他们指定的位置
如果有人 knows/has 遇到过这个问题或认为他们知道可能会发生什么,那么很高兴收到您的来信。
每次调用 startActivityForResult
或 startActivity
都会启动一个新的 Activity.
所以我在您的示例代码中计算了其中的 4 个,但实际上只有 2 个调用会 return 导致写入文件的结果。
要解决此问题,只需删除所有 startActivityForResult
或 startActivity
,除了您更改为 startActivityForResult(chooserIntent,WRITE_REQUEST_CODE);
这有效(已测试)但提供了非常糟糕的 UI 体验,因为您必须知道 select Files
应用程序才能保存文档。
最好将它们拆分为不同类型的操作,分别放在单独的菜单项、按钮、浮动操作按钮中,或者让用户使用 "Share or Save",因为您可以提供更好的 UI 比 Intent 选择器。