Cannot resolve ContentProvider outside the application

Viewed 51

I'm trying to share basic data between 2 applications using SharedPreferences.

I've created a Class that extends 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;
            }
        }

also added the class reference in the AndroidManifest.xml:

    <provider
        android:authorities="${applicationId}.provider"
        android:enabled="true"
        android:exported="true"
        android:grantUriPermissions="true"
        android:name="com.chou.playground.SharedIdProvider">
    </provider>

then in my MainActivity I'm trying to get the data:

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();
            }
        }
    }
}

everythings works fine when the app is the same, but when I change the applicationId in my gradle.build file in com.chou.app2, com.chou.app2 cannot find the first content provider, the log says: Failed to find provider info for com.chou.app1.provider

The strange thing it's that when I run from terminal:

adb shell content query --uri content://com.chou.app1.provider/__hd 

then everything starts working properly even from the second app.

Someone can help me?

0 Answers
Related