Приветствую!
Задача следующая.
Разрабатывается связка для драйвера подключаемого оборудования с 1С, другими словами, интеграционная компонента. Используется язык C++.
Есть драйвер, написанный на Java, реализующийся через запуск Activity с намерениями (Intent).
Запуск Activity происходит корректно, отрабатывает тоже правильно. Основной затык - с получением результата.
Результат работы Activity я записываю в Content через Content Provider. Записывается корректно.
Теперь нужно в C++ прочитать записанные данные. Вот здесь и проблема: не получается этого сделать.
В manifest-файле драйвера (приложение, которое записывает данные) указано следующее:
<provider
android:name="myPackage.MyContentProvider"
android:authorities="myPackage.provider"
android:exported="true"
android:permission="myPackage.provider.permission.ACCESS_PROVIDER"
android:grantUriPermissions="true">
</provider>
Показать
Для чтения Content используется следующий код на C++:
// Получаем ссылку на Java-контекст для выполнения операций через JNI
jclass contextClass = env->FindClass("android/content/Context");
jmethodID getApplicationContextMethod = env->GetMethodID(contextClass, "getApplicationContext", "()Landroid/content/Context;");
jobject context = env->CallObjectMethod(currentActivity, getApplicationContextMethod);
// URI Content Provider'а
const char* contentProviderUri = "myPackage.provider.permission.ACCESS_PROVIDER";
// Создаем ContentResolver для доступа к Content Provider
jclass contextWrapperClass = env->FindClass("android/content/ContextWrapper");
jmethodID getContentResolverMethod = env->GetMethodID(contextWrapperClass, "getContentResolver", "()Landroid/content/ContentResolver;");
jobject contentResolver = env->CallObjectMethod(context, getContentResolverMethod);
jclass contentResolverClass = env->GetObjectClass(contentResolver);
// Создаем URI для Content Provider
jclass uriClass = env->FindClass("android/net/Uri");
jmethodID parseMethod = env->GetStaticMethodID(uriClass, "parse", "(Ljava/lang/String;)Landroid/net/Uri;");
jstring uriString = env->NewStringUTF(contentProviderUri);
jobject uriObject = env->CallStaticObjectMethod(uriClass, parseMethod, uriString);
// Запрашиваем данные у Content Provider
jclass cursorClass = env->FindClass("android/database/Cursor");
jmethodID queryMethod = env->GetMethodID(contentResolverClass, "query", "(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;");
jobjectArray projection = env->NewObjectArray(1, env->FindClass("java/lang/String"), NULL);
jstring columnProjection = env->NewStringUTF("data");
env->SetObjectArrayElement(projection, 0, columnProjection);
jobject cursor = env->CallObjectMethod(contentResolver, queryMethod, uriObject, projection, NULL, NULL, NULL);
bool hasPerm = hasPermissionForContentProvider(env, context, "myPackage.provider.permission.ACCESS_PROVIDER");
Показать
функция hasPermissionForContentProvider проверяет наличие доступа
myPackage.provider.permission.ACCESS_PROVIDER
bool AddInNative::hasPermissionForContentProvider(JNIEnv* env, jobject context, const char* contentProviderAuthority) {
jclass contextClass = env->GetObjectClass(context);
jmethodID packageManagerMethod = env->GetMethodID(contextClass, "getPackageManager", "()Landroid/content/pm/PackageManager;");
jobject packageManager = env->CallObjectMethod(context, packageManagerMethod);
jclass packageManagerClass = env->GetObjectClass(packageManager);
jmethodID resolveContentProviderMethod = env->GetMethodID(packageManagerClass, "resolveContentProvider", "(Ljava/lang/String;I)Landroid/content/pm/ProviderInfo;");
jstring contentProviderAuthorityString = env->NewStringUTF(contentProviderAuthority);
jobject providerInfo = env->CallObjectMethod(packageManager, resolveContentProviderMethod, contentProviderAuthorityString, 0);
if (providerInfo != nullptr) {
jclass providerInfoClass = env->GetObjectClass(providerInfo);
jfieldID readPermissionField = env->GetFieldID(providerInfoClass, "readPermission", "Ljava/lang/String;");
jstring readPermission = (jstring)env->GetObjectField(providerInfo, readPermissionField);
if (readPermission != nullptr) {
const char* readPermissionStr = env->GetStringUTFChars(readPermission, nullptr);
jint hasPermission = env->CallIntMethod(packageManager, env->GetMethodID(packageManagerClass, "checkPermission", "(Ljava/lang/String;Ljava/lang/String;)I"), readPermission, context);
env->ReleaseStringUTFChars(readPermission, readPermissionStr);
if (hasPermission == JNI_OK) {
return true; // У приложения есть разрешение на использование Content Provider
}
}
}
return false; // Разрешение отсутствует или недостаточно
}
Показать
В переменную hasPerm возвращается False.
В сборке драйвера .zip используется файл ANDROID_MANIFEST_EXTENSIONS.XML, в котором я добавляю нужные права. Однако, как показывает результат, это не сработало..(
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="myPackage.provider.permission.ACCESS_PROVIDER"/>
</root>
Собственно, вопрос
Почему permission не добавился к приложению? Помогут любые предположения, потому что идей пока что не приходит в голову. Спасибо заранее.