我有一个 JNI 代码,用于获取签名并返回 java 中的值。
我需要使用get()方法从JNI获取包名称,如下面的代码所述,并将其传递给java类。
但是,在JNI中传递全局变量时,应用程序正在崩溃。
当前实现采用JNI代码,如下所示
static jstring packageNameValue;
char* jstringTostring(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = (*env)->FindClass(env, "java/lang/String");
jstring strencode = (*env)->NewStringUTF(env, "utf-8");
jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode);
jsize alen = (*env)->GetArrayLength(env, barr);
jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
if (alen > 0)
{
rtn = (char*)malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
(*env)->ReleaseByteArrayElements(env, barr, ba, 0);
return rtn;
}
char* loadSignature(JNIEnv* env, jobject obj)
{
jclass cls = (*env)->FindClass(env, "android/content/ContextWrapper");
jmethodID mid = (*env)->GetMethodID(env, cls, "getPackageManager",
"()Landroid/content/pm/PackageManager;");
if (mid == NULL) {
return "";
}
jobject pm = (*env)->CallObjectMethod(env, obj, mid);
if (pm == NULL) {
return "";
}
mid = (*env)->GetMethodID(env, cls, "getPackageName", "()Ljava/lang/String;");
if (mid == NULL) {
return "";
}
jstring packageName = (jstring)(*env)->CallObjectMethod(env, obj, mid);
packageNameValue = packageName;
cls = (*env)->GetObjectClass(env, pm);
mid = (*env)->GetMethodID(env, cls, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
jobject packageInfo = (*env)->CallObjectMethod(env, pm, mid, packageName, 0x40); //GET_SIGNATURES = 64;
cls = (*env)->GetObjectClass(env, packageInfo);
jfieldID fid = (*env)->GetFieldID(env, cls, "signatures", "[Landroid/content/pm/Signature;");
jobjectArray signatures = (jobjectArray)(*env)->GetObjectField(env, packageInfo, fid);
jobject sign = (*env)->GetObjectArrayElement(env, signatures, 0);
cls = (*env)->GetObjectClass(env, sign);
mid = (*env)->GetMethodID(env, cls, "toCharsString", "()Ljava/lang/String;");
if(mid == NULL){
return "";
}
jstring signString = (jstring)(*env)->CallObjectMethod(env, sign, mid);
printf("signString", signString);
return jstringTostring(env, signString);
}
char* getSignatureMd5(JNIEnv* env, jobject obj)
{
char* sign = loadSignature(env, obj);
MD5_CTX context = { 0 };
MD5Init(&context);
MD5Update(&context, sign, strlen(sign));
unsigned char dest[16] = { 0 };
MD5Final(dest, &context);
int i;
static char destination[32]={0};
for (i = 0; i < 16; i++) {
sprintf(destination, "%s%02x", destination, dest[i]);
}
return destination;
}
jstring Java_com_example_u29692_helloandroidjni_MainActivity_getToken(JNIEnv *env, jobject obj,
jobject context) {
char* correctSign = "72eed157ba97751805fc2a3dfacea102";
char* signMd5 = loadSignature(env, obj);
printf("value sign", signMd5);
jstring packageDetail = (*env)->NewGlobalRef(env, packageNameValue);
char* packageDetailvalue = packageDetail;
return (*env)->NewStringUTF(env,packageDetailvalue);
}
答案 0 :(得分:1)
您可以将mainActivity传递给本机
static jstring getpkg(JNIEnv* env, jobject thiz, jobject activity) {
jclass android_content_Context =env->GetObjectClass(activity);
jmethodID midGetPackageName = env->GetMethodID(android_content_Context,"getPackageName", "()Ljava/lang/String;");
jstring packageName= (jstring)env->CallObjectMethod(activity, midGetPackageName);
return packageName;