Не удается разрешить ContentProvider вне приложения. - PullRequest
3 голосов
/ 26 мая 2020

Я пытаюсь поделиться базовыми c данными между двумя приложениями с помощью SharedPreferences.

Я создал класс, расширяющий 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();
            }
        }
    }
}

все работает нормально, когда приложение такое же, но когда я меняю applicationId в моем файле gradle.build в com.chou.app2 , com.chou.app2 не могу найти первого поставщика содержимого, в журнале говорится: Failed чтобы найти информацию о провайдере для com.chou.app1.provider

Странно то, что когда я запускаю с терминала:

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

, тогда все начинает работать правильно даже со второго app.

Кто-нибудь может мне помочь?

...