7

I need to get name of my android application from the native side somethin like that:

 android.content.context context=(android.content.context) this;//current activiy
 Resources appR =context.getResources();
 String packageName=context.getPackageName();
 int id=appR.getIdentifier("app_name","string",packageName );
 CharSequence txt = appR.getText(id);

my native code like that:

  jstring Java_com_AnalyticToolC_AnalyticToolActivity_JNISendData(JNIEnv* env,jobject entryObject,jobject contxt)
 {

   char *realAppName;
 realAppName=(char *)malloc(16 * 1024);
 jclass android_content_Context =(*env)->GetObjectClass(env, contxt);
    jmethodID midGetPackageName = (*env)->GetMethodID(env, android_content_Context, "getPackageName", "()Ljava/lang/String");
 jstring packageName=(*env)->CallObjectMethod(env, contxt, midGetPackageName);
jmethodID midGetResources = (*env)->GetMethodID(env, android_content_Context, "getResources", "()L");
    jobject jResource=(*env)->CallObjectMethod(env, context, midGetResources);

   jclass resource_Class=(*env)->GetObjectClass(env, jResource);
   jmethodID midGetIdentifier = (*env)->GetMethodID(env, resource_Class, "getIdentifier", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String)I");
   jstring app_name=(*env)->NewStringUTF(env,"app_name");
   jstring TypeName=(*env)->NewStringUTF(env,"string");
   int id=(*env)->CallObjectMethod(env, jResource, midGetIdentifier,app_name,TypeName,packageName);

  jmethodID midGetAppName = (*env)->GetMethodID(env, resource_Class,"getText","(I)Ljava/lang/String");
  jstring appName=(*env)->CallObjectMethod(env, jResource, midGetAppName,id);   

  realAppName=(*env)->GetStringUTFChars(env, appName, NULL);
}

and i just pass the activity to my native methon from java code.

and i don't have a chance to write this code in java class then call it form my NDK application I'm trying a lot to pass a context object as jobject to my native code but it always crash. dose any one have any idea?

Serngawy
  • 73
  • 1
  • 1
  • 7

2 Answers2

14

Reflected Java access in C is ugly, ugly, ugly, just like you've demonstrated. Pass the app name as an extra string parameter.

EDIT: OK, you want reflection, reflection you'll get.

Your native method belongs to class AnalyticToolActivity. As a nonstatic class method, it has a this pointer on every call. Unlike C++ and Java methods, this pointer is passed explicitly as the second parameter. The method has two mandatory parameters - a JNIEnv * and a jobject. The second one corresponds to the this pointer of the Java object.

So if your AnalyticToolActivity is a subclass of Activity - quite likely - the entryObject parameter is an instance of Activity, meaning it's an instance of Context. So get rid of the third parameter (contxt), and your JNI code can go like this:

jclass android_content_Context =(*env)->GetObjectClass(env, entryObject);
//or use FindClass

jmethodID midGetPackageName = (*env)->GetMethodID(env,
    android_content_Context,
    "getPackageName",
    "()Ljava/lang/String;");

jstring packageName=(*env)->CallObjectMethod(env, entryObject, midGetPackageName); 

and so forth.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • I know it's ugly, ugly so ugly but this is the case, I need to access the SharedPreferences object also, if anyone can help I really appreciated – Serngawy Apr 02 '12 at 20:55
  • Wording suggests your native method belongs to your activity class. The activity *is* a subclass of context. If your native method is static, remove that; then treat the `this` pointer (AKA `entryObject`) as a Context reference. – Seva Alekseyev Apr 02 '12 at 21:00
  • sorry i didn't get you, but my native method is not static method and you mean (jobject entryObject) should be my pass object "activity from java side" – Serngawy Apr 02 '12 at 21:21
  • 1
    thanks, I solve it problem with method signature you have to put ; if your method will return object not primitive type object, it should looks like "()Ljava/lang/String;" – Serngawy Apr 03 '12 at 19:59
  • brilliant answer...learnt more in that paragraph than from an entire book – Houston Oct 26 '12 at 12:07
  • should be "()Ljava/lang/String;" – NickUnuchek Apr 26 '16 at 06:18
-4

Why do you need to do so from the NDK? Perhaps it would be more useful for us to help you debug the problem passing a context object, and then you could just pass the app name as a string.

Samuel
  • 16,923
  • 6
  • 62
  • 75
  • i do that cause i have a my C lib which will use by other native application so i need to use the application name in my C lib, anyway i will update the Question with my native code. – Serngawy Apr 02 '12 at 20:18