如何将软件包名称从JNI获取到Android?

时间:2016-10-19 09:04:00

标签: c++ android-ndk

我有一个 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);

}

1 个答案:

答案 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;