2016-10-19 1 views
0

Ich habe einen JNI Code zum Abrufen der Signatur und Rückgabe des Werts in java.Wie bekomme ich den Paketnamen von JNI zu Android?

Ich muss den Paketnamen von JNI erhalten, wie im folgenden Code mit der get() -Methode beschrieben und an die Java-Klasse übergeben.

Aber Anwendung wird immer abgestürzt während das Bestehen der globale Variable in JNI.

Die aktuelle Implementierung ist in JNI-Code, wie folgende

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); 

} 
+2

passieren kann _ "Aber Anwendung ist abgestürzt immer, während die globale Variable in jni vorbei" _ Dann sollten Sie den Stacktrace veröffentlichen. – Michael

+0

Es gibt eine einfache Möglichkeit, den aktuellen App-Paketnamen zu erhalten, der JNI und den Paketmanager nicht mit einbezieht: Datei '/ proc/self/cmdline' lesen. –

Antwort

0

Sie die mainActivity zu nativem

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; 
Verwandte Themen