gpt4 book ai didi

java - 使用 MediaScanner 连接和从 TreeUri 获取的 DocumentFile URI(对于 Lollipop 版本)刷新图库

转载 作者:行者123 更新时间:2023-12-01 19:25:20 30 4
gpt4 key购买 nike

您好,我正在尝试通过启动扫描来刷新图库。对于运行 Kitkat 及更高版本的设备,我使用 mediascannerconnection。但 mediaScannerConnection 需要绝对路径来进行扫描。我拥有的是一个 DocumentFile ,它似乎没有任何方法来获取它的绝对路径。

下面是我正在使用的代码:

要获得使用新的 Lollipop API 写入文件夹的权限-->将选定的 URI 保存到全局变量--->隐藏逻辑(创建/删除“.nomedia”文件)。

// Calling folder selector.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 42);
..............
@SuppressLint("NewApi") @Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (resultCode == RESULT_OK && requestCode == 42) {
Uri treeUri = resultData.getData();
getContentResolver().takePersistableUriPermission(treeUri,
// Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION |
Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
path = treeUri.getPath();
}

}
..........
public void hide(boolean hide){
DocumentFile pickedDir = DocumentFile.fromTreeUri(this,Uri.parse(path));
if(hide){
if(pickedDir.findFile(".nomedia")==null){
pickedDir.createFile(null, ".nomedia");
tellgallery(pickedDir.findFile(".nomedia").getUri().getPath());
}
}
else{
DocumentFile filetodelete = pickedDir.findFile(".nomedia");
if(filetodelete!=null){
filetodelete.delete();
tellgallery(filetodelete.getPath());
}
}
}

上面的代码运行良好,并在所需文件夹中创建/删除“.nomedia”文件。

现在,当我尝试告诉库该文件夹的文件已更改时。图库无法选择更改。

下面是刷新/请求扫描的代码。

private void tellgallery(String path) {
pathtonomedia = path;
if(path!=null){
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
mediaScannerConnection = new MediaScannerConnection(con,mediaScannerConnectionClient);
mediaScannerConnection.connect();
}
else{
this.sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + path)));
}
}

}

MediaScanner 类如下:

private MediaScannerConnectionClient mediaScannerConnectionClient = 
new MediaScannerConnectionClient() {

@Override
public void onMediaScannerConnected() {
mediaScannerConnection.scanFile(pathtonomedia, null);
}

@Override
public void onScanCompleted(String path, Uri uri) {
if(path.equals(pathtonomedia))
mediaScannerConnection.disconnect();

}
};

但是代码不会刷新图库,我仍然可以在图库中看到该文件夹​​。然而,该文件夹可能会在 10 到 20 分钟后因系统刷新而消失。

最后我想要的是

  • 我是否可以获得 DocumentFile 实例的路径?这样我就可以直接将它传递到 mediascanner 路径

  • 或者还有其他方法可以请求扫描 Lollipop 中的特定文件夹。特定文件夹位于 SDCARD 中,我只知道它的 URI,而不是实际路径。

非常感谢任何帮助。

最佳答案

正如您所注意到的,删除不会触发媒体扫描,并且 DocumentFile Uri 不适用于 MediaScanner,因此在删除文件之前,您必须查询 MediaScanner 以获得有效路径。我所做的是迭代所有 DocumentFile 对象并对其调用 .getLastPathSegment() 。这将返回一个值,例如:

E25A-3848:Pictures/appname/images/foo.jpg

在我的测试中,该值始终有一个冒号将某些设备特定值与路径尾部分隔开。如果用户选择内部存储而不是 E25A-3838,他们将得到类似 primary 的单词,但这并不相关。重要的是您想要获取冒号后面的所有内容,因此我像这样迭代需要删除的文档:

String temp = document.getUri().getLastPathSegment();
final int lastColon = temp.lastIndexOf(":");
if (lastColon > 0) {
boolean deletionSuccess = document.delete();
if (deletionSuccess) {
Log.d(TAG, "Deleted " + document.getUri());
segmentsToDelete.add(temp.substring(lastColon + 1));
}
}

在此循环之后,文档将消失,并且 segmentsToDelete 数组列表将包含需要从 MediaScanner 中清除的所有尾随路径。因此,我执行另一个循环,要求 MediaScanner 删除具有相同值的所有结尾条目:

final Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
for (String lastPathSegment : segmentsToDelete) {
final int result = contentResolver.delete(uri,
MediaStore.MediaColumns.DATA + " LIKE ? ESCAPE '\\'",
new String[]{"%" + escapedLike(lastPathSegment)}
);
Log.d(TAG, "Media deletion for " + lastPathSegment + " was " + result);
}

.delete() 调用将返回已删除的行数,因此您可以在那里放置一个断言以确保它始终返回 1。如果由于某种原因文档从未创建过,则可能会返回更少的值不过它进入媒体扫描仪。 escapedLike() 方法是一个自定义函数,用于确保 SQLITE like pattern matching不匹配错误的路径:

static String escapedLike(@NonNull String text)
{
return text.replace("%", "\\%").replace("_", "\\_");
}

当然,如果你想删除整个目录,上面的方法是一样的。在这种情况下,您不需要运行循环,您可以首先在目录的 DocumentFile 上调用 .delete() ,然后在构建删除查询时使用尾随 % 用于 sql LIKE 参数,该参数应返回大量删除(与媒体扫描仪中注册的文件一样多)。

使用 LIKE 匹配而不是精确的完整路径的原因是因为从 DocumentFile 获取的先前值永远不会匹配完整路径。 E25A-3848:Pictures/appname/images/foo.jpg 之类的内容稍后将由 MediaScanner 数据库返回,例如 /storage/sdcard1/Pictures/appname/图片/foo.jpg。遗憾的是删除操作没有在内部调用 MediaScanner...

关于java - 使用 MediaScanner 连接和从 TreeUri 获取的 DocumentFile URI(对于 Lollipop 版本)刷新图库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33089649/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com