将 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()
有效。这是我的困惑的一部分,并且没有完全了解范围存储。
**问题:**我正在将应用程序更新到 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()
有效。这是我的困惑的一部分,并且没有完全了解范围存储。