如何请求C 代码的Android NDK摄像机许可
How to Request Android NDK Camera Permission from C++ code?
我正在用纯C 编写该应用,并且我有打开相机的代码。并设置AndroidManifest.xml为:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera2" android:required="true" />
第一次运行应用程序时,它没有提供提示以打开许可的提示。安装后,我必须手动进行操作,设置 ->应用 ->" myApp" ->权限。
如何在不引入Java代码的情况下在C 中提供提示?非常感谢所有帮助。
这可以使用JNI调用来完成。请参阅下面的示例,以获取read_external_storage和write_external_storage(可以轻松适应相机perms)。
调用函数:
check_android_permissions(struct android_app* app)(下面的源)应用程序启动时。
几个陷阱:
- android.manifest.permission是嵌套在android.manifest中的类因此,其JNI名称为" Android/Sustest $许可"。
- 我没有设法访问contextCompat(android.support.v4.content.contextcompat)和jni的ActivityCompat(android.support.v4.app.activitycompat)我使用了上下文(android.content.context)和活动(android.app.Activity)直接。结果,需要Android API 23级(2015年5月棉花糖)。
- 常数需要在类中检索,尤其是read_external_storage和write_external_storage是android.manifest.permission中的静态字符串,并且ofermission_grant_grant android.content.content.content.packagemanager。
- 当用户单击"不再次问我"按钮时,我没有实现如何处理,这将需要实现onrequestpermissionsresult()回调。
/**
* brief Gets the internal name for an android permission.
* param[in] lJNIEnv a pointer to the JNI environment
* param[in] perm_name the name of the permission, e.g.,
* "READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE".
* return a jstring with the internal name of the permission,
* to be used with android Java functions
* Context.checkSelfPermission() or Activity.requestPermissions()
*/
jstring android_permission_name(JNIEnv* lJNIEnv, const char* perm_name) {
// nested class permission in class android.Manifest,
// hence android 'slash' Manifest 'dollar' permission
jclass ClassManifestpermission = lJNIEnv->FindClass(
"android/Manifest$permission"
);
jfieldID lid_PERM = lJNIEnv->GetStaticFieldID(
ClassManifestpermission, perm_name, "Ljava/lang/String;"
);
jstring ls_PERM = (jstring)(lJNIEnv->GetStaticObjectField(
ClassManifestpermission, lid_PERM
));
return ls_PERM;
}
/**
* brief Tests whether a permission is granted.
* param[in] app a pointer to the android app.
* param[in] perm_name the name of the permission, e.g.,
* "READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE".
* retval true if the permission is granted.
* retval false otherwise.
* note Requires Android API level 23 (Marshmallow, May 2015)
*/
bool android_has_permission(struct android_app* app, const char* perm_name) {
JavaVM* lJavaVM = app->activity->vm;
JNIEnv* lJNIEnv = nullptr;
bool lThreadAttached = false;
// Get JNIEnv from lJavaVM using GetEnv to test whether
// thread is attached or not to the VM. If not, attach it
// (and note that it will need to be detached at the end
// of the function).
switch (lJavaVM->GetEnv((void**)&lJNIEnv, JNI_VERSION_1_6)) {
case JNI_OK:
break;
case JNI_EDETACHED: {
jint lResult = lJavaVM->AttachCurrentThread(&lJNIEnv, nullptr);
if(lResult == JNI_ERR) {
throw std::runtime_error("Could not attach current thread");
}
lThreadAttached = true;
} break;
case JNI_EVERSION:
throw std::runtime_error("Invalid java version");
}
bool result = false;
jstring ls_PERM = android_permission_name(lJNIEnv, perm_name);
jint PERMISSION_GRANTED = jint(-1);
{
jclass ClassPackageManager = lJNIEnv->FindClass(
"android/content/pm/PackageManager"
);
jfieldID lid_PERMISSION_GRANTED = lJNIEnv->GetStaticFieldID(
ClassPackageManager, "PERMISSION_GRANTED", "I"
);
PERMISSION_GRANTED = lJNIEnv->GetStaticIntField(
ClassPackageManager, lid_PERMISSION_GRANTED
);
}
{
jobject activity = app->activity->clazz;
jclass ClassContext = lJNIEnv->FindClass(
"android/content/Context"
);
jmethodID MethodcheckSelfPermission = lJNIEnv->GetMethodID(
ClassContext, "checkSelfPermission", "(Ljava/lang/String;)I"
);
jint int_result = lJNIEnv->CallIntMethod(
activity, MethodcheckSelfPermission, ls_PERM
);
result = (int_result == PERMISSION_GRANTED);
}
if(lThreadAttached) {
lJavaVM->DetachCurrentThread();
}
return result;
}
/**
* brief Query file permissions.
* details This opens the system dialog that lets the user
* grant (or deny) the permission.
* param[in] app a pointer to the android app.
* note Requires Android API level 23 (Marshmallow, May 2015)
*/
void android_request_file_permissions(struct android_app* app) {
JavaVM* lJavaVM = app->activity->vm;
JNIEnv* lJNIEnv = nullptr;
bool lThreadAttached = false;
// Get JNIEnv from lJavaVM using GetEnv to test whether
// thread is attached or not to the VM. If not, attach it
// (and note that it will need to be detached at the end
// of the function).
switch (lJavaVM->GetEnv((void**)&lJNIEnv, JNI_VERSION_1_6)) {
case JNI_OK:
break;
case JNI_EDETACHED: {
jint lResult = lJavaVM->AttachCurrentThread(&lJNIEnv, nullptr);
if(lResult == JNI_ERR) {
throw std::runtime_error("Could not attach current thread");
}
lThreadAttached = true;
} break;
case JNI_EVERSION:
throw std::runtime_error("Invalid java version");
}
jobjectArray perm_array = lJNIEnv->NewObjectArray(
2,
lJNIEnv->FindClass("java/lang/String"),
lJNIEnv->NewStringUTF("")
);
lJNIEnv->SetObjectArrayElement(
perm_array, 0,
android_permission_name(lJNIEnv, "READ_EXTERNAL_STORAGE")
);
lJNIEnv->SetObjectArrayElement(
perm_array, 1,
android_permission_name(lJNIEnv, "WRITE_EXTERNAL_STORAGE")
);
jobject activity = app->activity->clazz;
jclass ClassActivity = lJNIEnv->FindClass(
"android/app/Activity"
);
jmethodID MethodrequestPermissions = lJNIEnv->GetMethodID(
ClassActivity, "requestPermissions", "([Ljava/lang/String;I)V"
);
// Last arg (0) is just for the callback (that I do not use)
lJNIEnv->CallVoidMethod(
activity, MethodrequestPermissions, perm_array, 0
);
if(lThreadAttached) {
lJavaVM->DetachCurrentThread();
}
}
void check_android_permissions(struct android_app* app) {
bool OK = android_has_permission(
app, "READ_EXTERNAL_STORAGE"
) && android_has_permission(
app, "WRITE_EXTERNAL_STORAGE"
);
if(!OK) {
android_request_file_permissions(app);
}
}
,所以我也看过。
-
手动执行您也可以通过命令行使用
adb shell pm grant com.package.name android.permission.CAMERA
进行操作。 检查权限是否存在
adb shell dumpsys package com.package.name
这是要求使用Java的权限的一系列步骤
要弄清楚没有Java的情况,您将需要深入研究AOSP才能找到它在引擎盖下的工作方式……这不是微不足道的,找不到示例。p>
相关文章:
- Android NDK传感器向事件队列报告奇怪的间隔
- Android NDK 编译 LAME HAVE_MPGLIB > 'interface.h' 文件未找到
- Android NDK clang 编译器错误在 Windows 上显示'No such file or directory'
- 在 constexpr 构造函数 (c++17) 中赋值到 const char * 在使用 Android NDK 时
- 如何在 android ndk 上链接 C 和 C++ 代码,以及 C 和 C++ 运行时库(包括 STL)?
- Android NDK 未定义对ASensorEventQueue_registerSensor的引用
- 如何将 libjpeg-turbo Android NDK 添加为静态库
- 在 Flutter 应用程序中使用 Android NDK 中的 AssetManager 类
- Android NDK - 无法在 Visual Studio 2017 中调试
- 不再支持Android NDK APP_STL gnustl_shared
- Android NDK:用于第三方Java库的静态或共享C++运行时
- 为 Android NDK 编译库
- 从文件问题加载纹理 Android NDK 和 OpenGL
- Android NDK - C++ 异常会导致第三方原生库崩溃
- 如何在 Android/NDK 上将命令行参数从 gradlew.bat 传递到 Clang
- [android ndk]如何获取资产文件夹中文件的绝对路径?
- Android NDK.Build命令失败.未定义的引用.clang++:错误:链接器命令失败,退出代码为1
- 如何在Android(NDK)中使用CPR库
- 使用 Android NDK 使用 clang++ 编译C++代码时对"_Unwind_Resume"的未定义引用
- 如何在 C/Android NDK 中将字符串日期转换为毫秒