java - 无法在应用程序之外解析 ContentProvider
问题描述
我正在尝试使用 SharedPreferences 在 2 个应用程序之间共享基本数据。
我创建了一个扩展 ContentProvider 的类:
package com.chou.playground;
///imports...
public class SharedIdProvider extends ContentProvider {
static final String PROVIDER_NAME = BuildConfig.APPLICATION_ID + ".provider";
static final String URL = "content://" + PROVIDER_NAME + "/__hd";
static final int uriCode = 1;
static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PROVIDER_NAME, "/__hd", uriCode);
uriMatcher.addURI(PROVIDER_NAME, "/__hd/*", uriCode);
}
private transient static SharedPreferences prefs;
private transient static String hardwareId;
@Override
public String getType(@NotNull Uri uri) {
if (uriMatcher.match(uri) == uriCode) {
return PROVIDER_NAME + "/__hd";
}
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
@Override
public boolean onCreate() {
Context context = getContext();
if (context != null) {
prefs = context.getSharedPreferences("rsa_application_key_prefs", 0);
hardwareId = getHardwareId(context);
context.getContentResolver().notifyChange(Uri.parse(URL), null);
return true;
}
return true;
}
public static void update(Context context, String value){
hardwareId = value;
storeHardwareID(context.getApplicationContext(), value);
}
static synchronized String getHardwareId(Context context) {
String hardwareId = null;
if (null != context) {
hardwareId = getStoredHardwareId(context.getApplicationContext());
if (TextUtils.isEmpty(hardwareId)) {
hardwareId = generateHardwareId();
storeHardwareID(context.getApplicationContext(), hardwareId);
}
}
return hardwareId;
}
private static void storeHardwareID(Context context, String hardwareId) {
if (prefs == null) {
Log.e("SdkPreferences", "unexpected error in storeHardwareID, can't get shared preferences");
} else {
SharedPreferences.Editor editor = prefs.edit();
editor.putString("com.aes.api.hardware_id", hardwareId);
editor.putBoolean("com.aes.api.can_be_sync", true);
editor.apply();
}
}
private static String getStoredHardwareId(Context context) {
if (prefs == null) {
Log.e("SdkPreferences", "unexpected error in getStoredHardwareId, can't get shared preferences");
return "INVALID";
} else {
return prefs.getString("com.aes.api.hardware_id", null);
}
}
private static String generateHardwareId() {
return UUID.randomUUID().toString();
}
@Override
public Cursor query(@NotNull Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Context context = getContext();
MatrixCursor cursor = new MatrixCursor(new String[] { "__hd" });
cursor.addRow(new Object[]{ getCachedOrLoadHardwareId( context ) });
return cursor;
}
public static boolean canBeSynchronized() {
return prefs.getBoolean("com.aes.api.can_be_sync", false);
}
private String getCachedOrLoadHardwareId(Context context) {
if(hardwareId == null){
hardwareId = getHardwareId(context);
}
return hardwareId;
}
@Override
public Uri insert(@NotNull Uri uri, ContentValues values) {
return null;
}
@Override
public int update(@NotNull Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return 0;
}
@Override
public int delete(@NotNull Uri uri, String selection, String[] selectionArgs) {
return 0;
}
}
还在 AndroidManifest.xml 中添加了类引用:
<provider
android:authorities="${applicationId}.provider"
android:enabled="true"
android:exported="true"
android:grantUriPermissions="true"
android:name="com.chou.playground.SharedIdProvider">
</provider>
然后在我的 MainActivity 我试图获取数据:
private void trySyncWith() {
Uri kUri = Uri.parse("content://" + "com.chou.app1.provider" + "/__hd");
Context context = getBaseContext();
if (context != null) {
ContentResolver contentResolver = context.getContentResolver();
if (contentResolver != null) {
final Cursor cursor = contentResolver.query(kUri, null, null, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToNext();
String hardwareId = cursor.getString(0);
if (hardwareId != null) {
SharedIdProvider.update(context, hardwareId);
}
cursor.close();
}
}
}
}
当应用程序相同时,一切正常,但是当我在 com.chou.app2 的 gradle.build 文件中更改 applicationId 时, com.chou.app2找不到第一个内容提供者,日志显示: 未能找到提供者信息对于 com.chou.app1.provider
奇怪的是,当我从终端运行时:
adb shell content query --uri content://com.chou.app1.provider/__hd
然后即使从第二个应用程序开始一切正常。
有人可以帮助我吗?
解决方案
推荐阅读
- bash - 有没有一种方法可以在不使用 awk 中可用的 gsub 或 sub 选项的情况下使用替换?
- android - 由于不活动而在另一个应用程序上时如何阻止我的应用程序弹出
- c# - 如何在集成测试.net核心中获取会话值
- c++ - CMake - 找不到提升库
- java - Java 继承 LuxuryCarRental
- javascript - 如何编译两个相互引用的项目
- prometheus - Prometheus 中配置文件的替代方案?
- amazon-web-services - S3 通知发生或 SQS 接收排序器排序
- android - 如何在主要活动中访问片段的按钮?
- azure - 使用 ARM 部署将访问策略添加到密钥保管库时如何调试 ConflictError