将 Activity 上下文传递给单例会影响 getContentResolver() 吗?

Does passing the Activity Context to an singleton affect the getContentResolver()?

**问题:**我正在将应用程序更新到 Android 11 (API 30),但我无法让 getContentResolver() 在以下实例中工作,尽管它在别处工作。

在本论坛的帮助下并阅读应用程序其他地方的 Scoped Storage 文档,以下代码在 Actiities 它们所在的位置内工作;其中包括使用 getContentResolver() 从共享下载文件夹输入和输出。文件类型多种多样。

我正在尝试做的事情:此应用程序还允许用户(具有批准的权限)附加各种文件(例如文档、音频、视频等) .) 到数据库中的注释。在这种情况下,PDF。但是,文件信息会传递给 Singleton class,以避免其他 activities 中的相同代码出现冗余,所以我只在需要时传递 Context

正如我所提到的,这段代码在包含在 Activity 中时工作正常,我看到的唯一区别是上下文被传递给了一个单例 class。我希望有人能看到我没有看到的东西。

我知道 URI 没有被传递(参见 resultLauncher 代码,但我不认为这真的很重要,我可以获取文件路径并将其更改为 URI,我已成功多次。除了传递给单例 class,这是与我的其他代码相比的唯一区别(我可以看到)。

我可能会离开这里,第一个应用程序和所有。用户需要有附加多种文件类型的选项。

**INTENT**
 btnAddFile.setOnClickListener(v -> {
     Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
     intent.addCategory(Intent.CATEGORY_OPENABLE);
     intent.setType("*/*");
     resultLauncher.launch(intent);

 });

结果启动器

 resultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
     if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null){
  Uri uri = result.getData().getData();
  String util = UriUtils.getPathFromUri(this, uri);
  tableLayoutFiles.addView(BuildTableLayout.setupFilesTableRow(EditNote.this,tableLayoutFiles, util,false));
     }
 });

CODE WITHIN SINGLETON CLASS METHOD(一个TableLayout的文件和文件路径TextViews被传递了。所以下面的代码驻留在迭代 TextView(即电视)文件路径的循环。

File f = new File(tv.getText().toString());
String n = f.getName();
try {
     InputStream fis = context.getContentResolver().openInputStream(Uri.fromFile(new File(f.getPath())));
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     byte[] buf = new byte[1024];
     for (int read; (read = fis.read(buf)) != -1; ) {
  bos.write(buf, 0, read);
     }
     fis.close();

     noteFiles.add(new Files(0, n, bos.toByteArray()));
 } catch (Exception e) {
     Log.e("getContentResolver", e.toString());
     e.printStackTrace();
 }

好吧,我解决了我自己的问题,正如我所怀疑的,我必须将 Uri 直接传递给 getContentResolver().openInputStream(),并且无法使用 Uri.fromFile() 转换路径。另一个学习者的经验。

添加一个名为 fileURIs 的新变量 HashMap<String, Uri>() 到我的方法,我将文件 Uri 传递到我的方法。我使用文件路径作为键,文件的 Uri 作为键值。我在 for 循环中更新了 getContentResolver().openInputStream() 以检索正确的文件 Uri.

更新:

InputStream fis = context.getContentResolver().openInputStream(fileURIs.get(f.getPath()));

 File f = new File(tv.getText().toString());
 String n = f.getName();
 try {
     InputStream fis = context.getContentResolver().openInputStream(fileURIs.get(f.getPath()));
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     byte[] buf = new byte[1024];
     for (int read; (read = fis.read(buf)) != -1; ) {
         bos.write(buf, 0, read);
     }
     fis.close();

     noteFiles.add(new Files(0, n, bos.toByteArray()));
 } catch (Exception e) {
     Log.e("getContentResolver", e.toString());
     e.printStackTrace();
 }

而且我应该澄清一下,Uri.fromFile() 的使用确实适用于 file/directories 不是“访问被拒绝”,因此传递 cache 文件路径可以传递给 ContextResolver() 以这种方式没有问题。在我的例子中,当文件从 xml 导入时,它们被移动到缓存目录,这消除了问题以及为什么 Uri.fromFile() 有效。这是我的困惑的一部分,并且没有完全了解范围存储。