Import Picture with Java Jni to C++

Hello,

Helped me if you can take the advantage

I Developed a game with cocos2d-x-3.0 c ++.

But for 4 functionality I need invoked java code:

Facebook.
Choose an picture.
Choose music.
Delete xml / picture.

For facebook, I used the tutorial Yuye

After some difficulty it worked

But when I want to recycle their method to create new java code.
My game crash at startup with this code
0 error message in adb logcat ndk-stack

error to logcat :

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.shadw.StoryCraft/org.cocos2dx.cpp.AppActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2122)
at android.app.ActivityThread.access$600(ActivityThread.java:140)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1228)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4895)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:101)
at android.app.Activity.onCreate(Activity.java:887)
at org.cocos2dx.cpp.FindPicture.onCreate(FindPicture.java:37)
at org.cocos2dx.cpp.AppActivity.onCreate(AppActivity.java:66)
at android.app.Activity.performCreate(Activity.java:5163)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2061)
… 11 more

Here is my code to select a picture in galery Android :

Java :

FindPicture.java:

package org.cocos2dx.cpp;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;

public class FindPicture extends Activity
{

	 private static final int SELECT_PICTURE = 1;
	 private String selectedImagePath;
	 
	public FindPicture() 
	{

	}
	    
	   @Override
	public void onCreate(Bundle savedInstanceState) 
	{
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
	}
    public void onClick()
	{
		Intent intent = new Intent();
		intent.setType("image/*");
		intent.setAction(Intent.ACTION_GET_CONTENT);
		startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);
	} 
	public void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		 if (resultCode == RESULT_OK) 
		 {
			 if (requestCode == SELECT_PICTURE) 
		     {
		         Uri selectedImageUri = data.getData();
		     	 selectedImagePath = getPath(selectedImageUri);
		      }
		  }
	 }
	 public String getPath(Uri uri)
	 {
		 String[] projection = { MediaStore.Images.Media.DATA };
		 Cursor cursor = managedQuery(uri, projection, null, null, null);
		 int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		 cursor.moveToFirst();
		 return cursor.getString(column_index);
		}
	 
		public void onResume() 
		{
			super.onResume();
		}

		public void onPause() 
		{
			super.onPause();
		}
		public void onSaveInstanceState(Bundle outState) 
		{
			super.onSaveInstanceState(outState);
		}
		public void onDestory() 
		{
			super.onDestroy();
		}

}

Add to AppActivity.java :

package org.cocos2dx.cpp;

import org.cocos2dx.lib.Cocos2dxActivity;

import android.content.Intent;
import android.os.Bundle;

public class AppActivity extends Cocos2dxActivity {
	
	private FindPicture findPicture = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
        
		findPicture = new FindPicture();
		findPicture.onCreate(savedInstanceState);
		
	}
	
	@Override
	public void onResume() {
	    super.onResume();
	    
	    findPicture.onResume();
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
	    super.onActivityResult(requestCode, resultCode, data);
	    
	    findPicture.onActivityResult(requestCode, resultCode, data);
	}

	@Override
	public void onPause() {
	    super.onPause();
	    facebookLoginPlugin.onPause();
	    facebookPickFriendPlugin.onPause();
	    facebookPostPlugin.onPause();
	    facebookSendRequestsPlugin.onPause();
	    
	   findPicture.onPause();
	}

	@Override
	public void onDestroy() {
	    super.onDestroy();
	    
	    findPicture.onDestory();
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
	    super.onSaveInstanceState(outState);
	    
	    findPicture.onSaveInstanceState(outState);
	}
}

C++ :

NativeInterface.h :

#ifndef  __NATIVE_INTERFACE_H_
#define  __NATIVE_INTERFACE_H_

#include "string"

class NativeInterface
{

public:
//facebook
//for callback

    static void callbackJs(int cbIndex, const char* params);
    static const char* FindPicture(int cbIndex);
   // void menuCloseCallback(Object*);
};
#endif  //__NATIVE_INTERFACE_H_

NativeInterface.cpp :

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "Creation/EditorScene.h"
#include "Native/NativeInterface.h"
#include "platform/android/jni/JniHelper.h"
#include <jni.h>
#include <android/log.h>
const char* FindPicturejavaClassName = "org/cocos2dx/cpp/FindPicture";
extern "C"
{
    void Java_org_cocos2dx_cpp_FindPicture_nativeCallback(JNIEnv*  env, jobject thiz, jint cbIndex,jstring params)
    {
        
        if (params != NULL)
		{
			const char* str;
        	str = env->GetStringUTFChars(params, 0);
        	std::string tstr(str);
        	EditorLayer1::CallFunctionName(cbIndex,tstr);
		}
		else
		{
			std::string tstr = "";
			EditorLayer1::CallFunctionName(cbIndex,tstr);
		}
    }
};

const char* NativeInterface::FindPicture(int cbIndex){
	
	cocos2d::JniMethodInfo t;
	if (cocos2d::JniHelper::getStaticMethodInfo(t
                                                , FindPicturejavaClassName
                                                , "onClick"
                                                , "(I)Ljava/lang/String;"))
	{
		jstring ret = (jstring)(t.env->CallStaticObjectMethod(t.classID, t.methodID,cbIndex));
        t.env->DeleteLocalRef(t.classID);
        const char* aStr = " ";
        aStr = t.env->GetStringUTFChars(ret, 0);
        return aStr;
	}  
}
#endif

Add to EditorLayer1.h :

 	#include "Native/NativeInterface.h"
class EditorLayer1 : public cocos2d::Layer
{
public:

	  static string pathPicture;
      static void CallFunctionName(int cbIndex,string tstr);
      void menuCloseCallback(Object * );
}

Add to EditorLayer1.cpp :

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
 #include "Native/NativeInterface.h"
 #endif	
string EditorLayer1::pathPicture = "";
bool EditorLayer1::init()
{
   MenuItemImage *ImageItem = MenuItemImage::create(	"butonoff.png", "butonon.png", CC_CALLBACK_1(EditorLayer1::menuCloseCallback, this));
   ImageItem->setPosition(Point(visibleSize.width/2 + origin.x , 650.000000 + origin.y ));
   Menu* menuN = Menu::create(ImageItem,NULL);
   menuN->setPosition(Point::ZERO);
   this->addChild(menuN, 1 ,8);
}
void EditorLayer1::CallFunctionName(int cbIndex,string tstr)
{
		EditorLayer1::pathPicture = tstr;
}

void EditorLayer1::menuCloseCallback(Object * pSender)
{
            NativeInterface::FindPicture(0);
}

Other :

Add to Android.mk :

LOCAL_SRC_FILES := 

				../../Classes/Native/NativeInterface.cpp \

Add to Manifest :

<activity android:name="org.cocos2dx.cpp.FindPicture"></activity>

Thank you for that attempts to find a solution to my problem

What did you do at startup?

I just do anything that crash on startup.
no error message and I can not found the cause of this problem.
Probably because “extends Activity” in findPicture who comes into conflict with maybe "Cocos2dxActivity "or because of Manifest.
I do not know yet.

Can you make sure that, it crashed in c++ codes?
If so, then i think you have to print log to check what caused crash.

Thank you for your interest has motivated me it’s my problem found why this error

I removed

<activity android:name="org.cocos2dx.cpp.FindPicture"></activity>

in the manifest.

and remove onCreate()/onResume() /onPause()/oonSaveInstanceState(Bundle outState) /onDestory() in FindPicture.java and AppActivity.java

and my game start finally

but now my game crash if i click to button for invoke my function in java

I have no message with “adb logcat | $NDK_ROOT/ndk-stack -sym $COCOS2DX/proj.android/obj/local/armeabi”
that allows me to see my mistakes c ++.

but looking at the “All Messages” in logcat (in Eclipse)
I finally found:

W/dalvikvm(28332): dvmFindClassByName rejecting 'org/cocos2dx/cpp/FindPicture'
 D/JniHelper(28332): Failed to find static method id of onClick
 W/dalvikvm(28332): threadid=11: thread exiting with uncaught exception (group=0x4160e2a0)
 E/AndroidRuntime(28332): FATAL EXCEPTION: GLThread 5807
 E/AndroidRuntime(28332): java.lang.NoSuchMethodError: no static method with name='onClick' signature='(I)Ljava/lang/String;' in class Lorg/cocos2dx/cpp/FindPicture;
 E/AndroidRuntime(28332): 	at org.cocos2dx.lib.Cocos2dxRenderer.nativeTouchesEnd(Native Method)
	at org.cocos2dx.lib.Cocos2dxRenderer.handleActionUp(Cocos2dxRenderer.java:131)
	at org.cocos2dx.lib.Cocos2dxGLSurfaceView$9.run(Cocos2dxGLSurfaceView.java:257)
 	at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462)
 	at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)

I am in the process of research on these error.