Android 将敏感应用程序数据作为电子邮件附件发送时,正确的权限处理是什么?

Android 将敏感应用程序数据作为电子邮件附件发送时,正确的权限处理是什么?,android,Android,我无法为我创建的应用授予“反向权限” 希望以受控方式提供敏感数据 我的应用程序是一个时间跟踪器,因为时间跟踪日志 可以被视为个人信息,我已经创建了权限 用于访问它并为其分配了android.permission- group.PERSONAL\u信息权限组 要从手机中导出时间日志,我正在添加发送功能 将日志作为电子邮件附件保存。附件由 受我新添加的权限保护的内容提供商。我的 发送电子邮件的代码如下所示: String email = "someone@example.com"; Ur

我无法为我创建的应用授予“反向权限” 希望以受控方式提供敏感数据

我的应用程序是一个时间跟踪器,因为时间跟踪日志 可以被视为个人信息,我已经创建了权限 用于访问它并为其分配了android.permission- group.PERSONAL\u信息权限组

要从手机中导出时间日志,我正在添加发送功能 将日志作为电子邮件附件保存。附件由 受我新添加的权限保护的内容提供商。我的 发送电子邮件的代码如下所示:

   String email = "someone@example.com";
   Uri uri = TimeLog.CSVAttachment.CONTENT_URI;
   Intent i = new Intent(Intent.ACTION_SEND, uri);
   i.setType("text/csv");
   i.putExtra(Intent.EXTRA_EMAIL, new String[]{email});
   i.putExtra(Intent.EXTRA_SUBJECT, "Time log");
   i.putExtra(Intent.EXTRA_TEXT, "Hello World!");
   i.putExtra(Intent.EXTRA_STREAM, uri);
   i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
   startActivity(i);
当在我的HTC手机上运行它时,我会弹出一个选项,选择Gmail 和HTC邮件。选择Gmail,我会在Gmail应用程序中遇到以下异常:

ERROR/AndroidRuntime(8169): Caused by: java.lang.SecurityException:
Permission Denial: reading com.mycompany.timelog.TimeLog uri
content://com.mycompany.timelog/csv_attachment from pid=8169,
uid=10035 requires com.mycompany.timelog.permission.READ_TIME_LOG
我确实在我的提供商上设置了
android:grantUriPermissions=“true”
,但是 那没用。我有一个关于为什么会发生这种情况的理论。我有 预期标志\u授予\u读取\u URI\u权限以授予Gmail访问权限 访问我的内容提供商,但我认为真正发生的是 此许可被授予 com.android.internal.app.ResolverActivity,因为 如果与Intent和Android匹配,则为 向用户显示选择

因此,我努力将其编码到我的应用程序中,只是为了测试:

   grantUriPermission("com.google.android.gm", uri,
       Intent.FLAG_GRANT_READ_URI_PERMISSION);
这使Gmail能够正确显示电子邮件,我可以按 “发送”。不幸的是,在GMail关闭后,我得到了这个例外 com.google.process.gapps:

错误/AndroidRuntime(7617):java.lang.SecurityException:权限 拒绝:读取com.mycompany.timelog.timelog uri content://com.mycompany.timelog/csv_attachment 从pid=7617, uid=10011需要
com.mycompany.timelog.permission.READ\u TIME\u LOG

请注意,这来自不同的PID和UID。这是因为 对openAssetFile的实际调用来自某个同步提供程序 属于不同包的组件 (com.google.android.googleapps?)

虽然我有希望最终找到一种授予权限的方法 向我的
操作的最终接收者发送
意图,呼叫 openAssetFile是从完全不同的、实际的 不相关的软件包让我对如何授予权限感到困惑 应该有用的

所以最终我的问题是,考虑到日志是敏感数据, 我如何允许它作为附件通过电子邮件发送,同时尊重 用户隐私(例如,不建立附件世界
可读)

其他应用程序无法访问您应用程序的数据。只需使用专用存储。您有几个选择:

  • 将时间跟踪数据保存到数据库。应用程序数据库仅对创建它的应用程序可见。其他应用程序将无法查看此数据。发送电子邮件时,只需查询数据库并创建文本附件

  • 通过创建一个私有文件


  • 这是一种很好的方法,不幸的是,正如您所看到的,您可能会在框架中遇到许多问题,从而阻止您这样做。目前在授予uri权限方面存在一些问题,这使得该功能没有应有的用处(其中许多问题将在姜饼中解决),除此之外,Gmail似乎并不期望这种情况发生,而是在需要时保留授予的权限


    这个数据有多大?如果它不是太大,那么把它作为一个字符串包含在意图中怎么样?

    亲爱的未来的人们

    甚至谷歌本身似乎也以另一种方式解决了这个问题,而我在试图解决同样的问题时偶然发现了这种方式

    如果查看
    com.android.contacts.detail.ContactLoaderFragment
    ,您会在方法
    中找到私有Uri getPreAuthorizedUri(Uri Uri)

    解析为
    com.android.providers.contacts.ContactsProvider2
    ,其中类似的
    调用
    方法将uri添加到映射
    mPreAuthorizedUris
    ,该映射在
    查询/更新/…
    方法中使用


    该调用的返回值被放入Intent中,然后使用。

    让附件在世界范围内可读是什么意思。或者,比如说,把它放在SD卡上。权限的使用非常好。但是(对于收件人)在电子邮件附件离开您的内容提供商之前,是否可以先使用公钥加密对其进行加密?或者内置直接从应用程序发送电子邮件的功能?@Christopher这是一个创新的解决方法。但我认为,对于可能从未处理过公钥加密的最终用户来说,这会使事情变得太复杂。我自己发邮件也可以,但是我会失去将日志导出到dropbox帐户的能力。嗨,我也面临同样的问题。你解决了吗?估计使用了十年,每天有10个条目,我想大概有1到2MB的数据。意图的最大大小是多少?你相信我所描述的可以在姜饼上做吗?作为一种粗切,>256K太大了。我怀疑这在GB中仍然是不可能的,因为当应用程序只是暂时有权访问数据时,它可能仍然无法处理接收此意图。我怀疑大多数其他电子邮件应用程序也无法处理它。用户真的有可能一次导出十年每天十条条目吗?我相信这个权限问题将在十年内解决;)或者,这次的数据是高度可压缩的,您是否可以附加一个.gz或.zip文件而不是.csv文件?我认为您不理解这个问题,因为您告诉我要做我已经在做的事情。问题是文本附件变得可访问
    mContext.getContentResolver().call(
                ContactsContract.AUTHORITY_URI,
                ContactsContract.Authorization.AUTHORIZATION_METHOD,
                null,
                uriBundle);