对于基于AOSP源的嵌入式项目,我在一个(系统)应用程序中有大量数据,其他应用程序必须可以访问。是的,我知道:内容提供商或服务的典型工作,但是......设备上的所有用户配置文件上的应用都必须能够访问相同的数据(该大块的相同单个实例)!
我已经发现Android为服务,内容提供商和接收者提供了一个android:singleUser =“true”属性,但它有令人讨厌的副作用,它迫使android:exported =“false”!因此,我假设一个解决方案可能是在我的Manifest中使用android:singleUser =“true”,第二个是android:exported =“true”,并且第二个只查询第一个实际数据另一个应用程序可能需要,但是...这看起来很丑陋,在我的情况下 - 单用户Android已经存在内容提供商和服务的应用程序,它将需要相当多的更改。
我还尝试将我的完整(系统)应用程序标记为android:persistent =“true”,但这导致访问/ data / data的大部分数据驻留的部分(我需要进一步调试)找到根本原因)。
所以,我的问题是:是否有任何简单/建议的方式来创建内容提供者(同一个应用程序中的服务和接收者的相同问题),以便应用程序真正充当多个用户的单身人士(不是系统服务,因为我们不希望通过运行我们的东西作为SystemServer的一部分来影响系统稳定性?
答案 0 :(得分:8)
使用 android:singleUser =" true" 与 android:exported =" true" 是正确的方法,但是使用这个属性有一些警告。
首先,ActivityManagerService (isSingleton方法)将忽略此属性,除非您的应用具有INTERACT_ACCROSS_USERS权限。
第二次(这就是我认为您的问题所在),您的应用也必须作为特权应用安装在priv-app文件夹中(' LOCAL_PRIVILEGED_MODULE:= true&#39 ;在Android.mk中)。否则,PackageParser将清除你的'android:exported'属性。
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestProvider_singleUser,
false)) {
p.info.flags |= ProviderInfo.FLAG_SINGLE_USER;
if (p.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
Slog.w(TAG, "Provider exported request ignored due to singleUser: "
+ p.className + " at " + mArchiveSourcePath + " "
+ parser.getPositionDescription());
p.info.exported = false;
}
}
注意:以上所有内容不仅适用于提供商,也适用于服务和接收方。
更新:看起来对于作为特权应用的软件包的测试仅出现在Android 5.0及更高版本中。早期版本只是删除了导出属性。
答案 1 :(得分:1)
使用exported =“true”服务访问singleUser =“true”内容提供程序。
答案 2 :(得分:0)
只有位于priv-app文件夹中的系统级应用程序才具有export = true和singleUser = true,但是请注意,一旦安装更新,该标志将丢失,因此最好的策略是让内容提供商使用在用户级别,并在需要时在所有数据库之间建立某种同步机制。可悲的是,您必须复制信息才能实现所需的功能。