android之Uri使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android之Uri使用相关的知识,希望对你有一定的参考价值。

参考技术A ..

通用资源标志符(Universal Resource Identifier, 简称"URI")。

Uri代表要操作的数据,android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。

① 资源的命名机制;
② 存放资源的主机名;
③ 资源自身的名称。

Android的Uri由以下三部分组成: "content://"、数据的路径、标示ID(可选)*

例如:
所有联系人的Uri:

某个联系人的Uri:

所有图片Uri:

某个图片的Uri:

Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。

uri主要使用和ContentProvider有关。ContentProvider是Android四大组件之一,其本质上是一个标准化的数据管道,它屏蔽了底层的数据管理和服务等细节,以标准化的方式在Android 应用间共享数据。用户可以灵活实现ContentProvider所封装的数据存储以及增删改查等,所有的ContentProvider 必须实现一个对外统一的接口(URI)。

使用 FileOutputStream Android 编辑/修改 Uri 引用的文件

【中文标题】使用 FileOutputStream Android 编辑/修改 Uri 引用的文件【英文标题】:Edit/Modify Uri referenced file using FileOutputStream Android 【发布时间】:2021-11-23 13:12:05 【问题描述】:

我正在使用 ActivityResultLauncher 来获取文件的 uri。现在我想使用 fileoutputStream 修改该文件但不能,因为 fileoutputstream 需要路径字符串。这是我用来获取文件 Uri 的代码:

ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() 
            @Override
            public void onActivityResult(ActivityResult result) 
                if (result.getResultCode() == Activity.RESULT_OK) 
                    // There are no request codes
                    Intent data = result.getData();
                    Uri uri = data.getData();//this gets me URI
                    

                
            
      );

public void openFileChooser()

    Intent data = new Intent(Intent.ACTION_GET_CONTENT);
    data.addCategory(Intent.CATEGORY_OPENABLE);
    data.setType("*/*");
    data = Intent.createChooser(data, "Choose a file");
    Intent intent = Intent.createChooser(data, "Choose a file");
    someActivityResultLauncher.launch(intent);

该代码非常适合选择和读取文件。但我无法使用下面提到的函数来编写相同的文件:

static void writeToFile(String path,String data,Context context) 
    try 
        FileOutputStream output = null;
        output = new FileOutputStream(path, false);
        output.write(data.getBytes());
        output.close();
        Toast.makeText(getApplicationContext(),"SAVED",Toast.LENGTH_LONG).show();
    
    catch (IOException e) 
        Toast.makeText(getApplicationContext(),"File write failed: " + e.toString(),Toast.LENGTH_LONG).show();
    

我尝试了 uri.getPath(),但它返回 /document/msf:21。那是一些复杂的 uri 字符串,不能用作文件路径。我也一直在尝试使用 stackflow 和其他论坛中提到的 realPath 函数,但发现它不起作用(它们可能起作用,但它们取决于 API 级别,这使得它们不可靠)。那么,究竟想问什么:

1- 有没有其他方法可以选择文件来获取实际路径?

2- 如果无法选择路径,如何使用直接 Uri 写入文件?并且不使用 getpath 或路径字符串。

3- 在这种只有 Uri 可用的情况下,有没有办法将 fileoutstream 与 Uri 一起使用?

谢谢

【问题讨论】:

【参考方案1】:
OutputStream os = getContentResolver().openOutputStream(data.getData());

【讨论】:

虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。您可以在帮助中心找到更多关于如何写好答案的信息:***.com/help/how-to-answer。祝你好运?【参考方案2】:

您需要通过输入流和缓冲区读取器将其传递给输出流。

在启动意图上试试这个

Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/pdf");
intent.putExtra(Intent.EXTRA_TITLE, "JWI.pdf");
startActivityForResult(intent, CREATE_FILE);

在活动结果上试试这个

try 
uri = _data.getData();
muri = uri.toString();
t.edit().putString("Uri", muri).commit();
        
final int takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION | 
Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 
getContentResolver().takePersistableUriPermission(uri, takeFlags);
        
        
DocumentFile doc = DocumentFile.fromSingleUri(this, uri);
boolean doo = doc.exists();
if (!doo) 
DocumentFile f = doc.createFile("pdf/plain", "JAMZ.pdf");
        
ContentResolver cr = getContentResolver(); OutputStream output =
cr.openOutputStream(uri); 
java.io.InputStream asset = getAssets().open("JWI.pdf");


final byte[] buffer = new byte[1024];

int size;

while ((size = asset.read(buffer)) != -1) 

output.write(buffer, 0, size);



asset.close();

output.close();
 catch (Exception e) 

【讨论】:

以上是关于android之Uri使用的主要内容,如果未能解决你的问题,请参考以下文章

Android之ContentProvider使用

Android系统路由之-scheme实现网页链接携带参数跳转到Activity

Android 两个Activity之间怎样使用Uri传递图片,怎样获取图片的Uri,怎样通过Uri得到图片

Android开发之深入理解Android 7.0系统权限更改相关文档

C++学习(二九五)Android的URI使用总结

使用 android play store update 更新 android URI 方案