【问题标题】:How to name columns in custom content provider如何在自定义内容提供程序中命名列
【发布时间】:2014-04-06 18:35:27
【问题描述】:

我应该如何调用从自定义 ContentProvider 返回的 Cursor 中的列,以允许其他应用从中读取数据。

我在 ProviderContract 中声明了所有列,但第三个应用程序不知道这一点。 这有记录吗?

我特别想做的是让用户将数据(文件 - 图像和 pdf)从我的应用程序共享到其他应用程序.. 出于安全考虑,所有数据都在外部 sd 存储上加密。所以我需要通过我的应用程序代理它们来解密它们。 Android 安全系统应处理用户选择共享文件后仅允许其他应用从内容提供者读取的问题。没关系,但我有其他应用程序不知道如何从我的光标读取数据的问题。

我只是觉得 Android 会有一些机制来做到这一点:)要么通过标准化的列名,要么通过一些适配器机制。

这是我的查询方法的代码..

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    MatrixCursor c = new MatrixCursor(SecuredFileContract.Files.PROJECTION_ALL);
    String name = uri.getLastPathSegment();
    File file = new File(name);
    byte[] fileContents = mStorageProxy.getFileContents(file);
    c.addRow(new Object[]{1, uri.getLastPathSegment(), fileContents, 0});
    return c;
}

【问题讨论】:

    标签: android android-contentprovider android-cursor


    【解决方案1】:

    让第 3 方应用知道如何从我的 Contract 类中获取它们的标准。

    这就是所谓的“网页”,或某种其他形式的文档。

    例如,您知道 SDK 提供的提供程序的列名的原因是因为这(在某种程度上)记录在 JavaDocs 中。

    您需要记录:

    • 您所期望的 Uri 模式,尤其是键 Uri 值(例如,CONTENT_URI 查询值)

    • 可以在投影中请求的列名

    • 关于如何将 selectionselectionArgssortOrder 参数解释为 query 的“游戏规则”(例如,可以将这些视为使用您的列名的普通 SQL 吗? )

    您是否以网页、PDF 文件、培训视频或其他形式提供此文档,取决于您。


    更新基于编辑:

    我特别想做的是让用户将数据(文件 - 图像和 pdf)从我的应用程序共享到其他应用程序

    那么你需要一个支持openFile()openAssetFile()ContentProvider。理想情况下,它还支持query(),但专门针对the OpenableColumns projection,而不是任意的东西。

    This sample project 演示了您的 ContentProvider 需要做什么,尽管您需要用您的 read-the-encrypted-file-and-decrypt-it 逻辑替换我的 read-the-file-from-assets 逻辑.

    【讨论】:

    • 我怎么会错过 openFile() 方法..无论如何,最后一个问题:) openFile 返回 ParcelFileDescriptor 我认为它不适合我,因为我没有文件的解密版本随时盘。我刚刚发现 MediaStore.MediaColumns developer.android.com/reference/android/provider/… 这不正是我需要的吗?我需要发送一个字节数组而不是 ParcelFileDescriptor。
    • @simekadam:“openFile 返回 ParcelFileDescriptor,我认为它不适合我,因为我在任何时候都没有磁盘上文件的解密版本”——你可以创建一个管道 @ 987654339@。这显示在the sample project 中。 “这不正是我需要的吗?” -- 你没有实现MediaStore。 “我需要发送一个字节数组而不是 ParcelFileDescriptor”——请点击指向 the sample project 的链接。
    • 如果支持 API 8 级就好了。我猜拥有史前手机的人不会共享文件。我不会放弃这种优雅的解决方案。
    • @simekadam:是的,抱歉,createPipe() 从 API 级别 9 开始。在此之前,您唯一的支持是将文件解密为文件(可能在内部存储中)并使用 open()ParcelFileDescriptor。这并不安全,特别是因为安全擦除闪存的方式不像对磁性介质那样有效。 OTOH,它还为您提供了更兼容的流,因为createPipe() 的一个缺点是流不可搜索,而文件支持的流是。
    • 是的,我想我们可以接受这个。2.2 用户群远低于 1%(对于这个特定的应用程序)。我只需要编写逻辑来隐藏那里不支持的功能。虽然不是一个大问题.. 我喜欢管道的是它是非阻塞的(如果我像你那样实现),我只返回它的一个尾部,另一个应用程序可以立即开始从中读取数据。我还发现了许多 API 级别 19 的附加方法,我敢打赌这是因为新的 DocumentProvider,它使用 ParcelFileDescriptors 作为其支持技术。 (至少它的开发者是这么说的,我没有检查来源)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多