bool getCommandLine(Engine* engine, char*& commandLine) { struct android_app* app = engine->mApp; jclass thisClass = app->appThreadEnv->GetObjectClass(app->appThreadThis); EXCEPTION_RETURN(app->appThreadEnv); jfieldID field = app->appThreadEnv->GetFieldID( thisClass, "mCommandLine", "Ljava/lang/String;" ); EXCEPTION_RETURN(app->appThreadEnv); jstring jCommandStr = (jstring)app->appThreadEnv->GetObjectField(app->appThreadThis, field); EXCEPTION_RETURN(app->appThreadEnv); const char* commandLineChars = app->appThreadEnv->GetStringUTFChars(jCommandStr, 0); EXCEPTION_RETURN(app->appThreadEnv); LOGI("commandLineChars = %s", commandLineChars); if (commandLineChars) { int length = strlen(commandLineChars) + 1; commandLine = new char[length]; strncpy(commandLine, commandLineChars, length); } else { commandLine = new char[1]; commandLine[0] = 0; } app->appThreadEnv->ReleaseStringUTFChars(jCommandStr, commandLineChars); EXCEPTION_RETURN(app->appThreadEnv); return true; }
//java/lang/ClassLoader make a while,so the best way is make a Init function to keep java/lang/ClassLoader alive bool RegisterNativeFunction(const char*e_strPackageAndClassName,const char*e_strJAVAFunctionName,const char*e_strSignature,void*FunctionPointer,sJNIUtilData*e_pJNIUtilData) { JNINativeMethod nm[1]; nm[0].name = e_strJAVAFunctionName; nm[0].signature = e_strSignature; nm[0].fnPtr = (void*)FunctionPointer; try { jstring strClassName = e_pJNIUtilData->pJNIEnv->NewStringUTF(e_strPackageAndClassName); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); jclass classIWant = (jclass)e_pJNIUtilData->pJNIEnv->CallObjectMethod(e_pJNIUtilData->cls, e_pJNIUtilData->findClass, strClassName); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); ////Register methods with env->RegisterNatives. int l_iResult = e_pJNIUtilData->pJNIEnv->RegisterNatives(classIWant, nm, 1); //https://www.java.net/node/676773 e_pJNIUtilData->pJNIEnv->DeleteLocalRef(strClassName); e_pJNIUtilData->pJNIEnv->DeleteLocalRef(classIWant); return l_iResult==0?true:false; } catch(const std::exception& ex) { const char*l_str = ex.what(); int a=0; } return false; }
bool CallLaunchActivityVoidFunction(char*e_strFunction,char*e_strFunctionParameters) { jclass thisClass = cGameApp::m_spThreadEnv->GetObjectClass(*cGameApp::m_spAppThreadThis); EXCEPTION_RETURN(cGameApp::m_spThreadEnv); jmethodID l_FunctionMethodID = cGameApp::m_spThreadEnv->GetMethodID(thisClass,e_strFunction,e_strFunctionParameters); EXCEPTION_RETURN(cGameApp::m_spThreadEnv); cGameApp::m_spThreadEnv->CallVoidMethod(*cGameApp::m_spAppThreadThis,l_FunctionMethodID); return true; }
bool Engine::useChoreographer(bool use) { jclass thisClass = mApp->appThreadEnv->GetObjectClass(mApp->appThreadThis); EXCEPTION_RETURN(mApp->appThreadEnv); jmethodID useChoreographer = mApp->appThreadEnv->GetMethodID(thisClass, "useChoreographer", "(Z)Z"); EXCEPTION_RETURN(mApp->appThreadEnv); bool success = mApp->appThreadEnv->CallBooleanMethod(mApp->appThreadThis, useChoreographer, use); EXCEPTION_RETURN(mApp->appThreadEnv); return true; }
bool CallStaticVoidMethod3(char*e_strClassName,char*e_strMethodName,char*e_strFunctionParameter,void*e_pInputData1,void*e_pInputData2,sJNIUtilData*e_pJNIUtilData,bool e_bCustomClass) { jclass l_Class; if( e_bCustomClass ) l_Class = GetCustomJavaClass(e_strClassName,e_pJNIUtilData); else l_Class = e_pJNIUtilData->pJNIEnv->FindClass(e_strClassName); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); jmethodID l_Method = e_pJNIUtilData->pJNIEnv->GetStaticMethodID(l_Class,e_strMethodName,e_strFunctionParameter); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); e_pJNIUtilData->pJNIEnv->CallStaticVoidMethod(l_Class, l_Method,e_pInputData1,e_pInputData2); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); e_pJNIUtilData->pJNIEnv->DeleteLocalRef(l_Class); return true; }
bool sJNIUtilData::Init() { activityClass = pJNIEnv->FindClass("android/app/NativeActivity"); EXCEPTION_RETURN(pJNIEnv); getClassLoader = pJNIEnv->GetMethodID(activityClass,"getClassLoader", "()Ljava/lang/ClassLoader;"); EXCEPTION_RETURN(pJNIEnv); ThreadThis = pJNIEnv->NewGlobalRef(cGameApp::m_spANativeActivity->clazz); cls = pJNIEnv->CallObjectMethod(ThreadThis , getClassLoader); EXCEPTION_RETURN(pJNIEnv); classLoader = pJNIEnv->FindClass("java/lang/ClassLoader"); EXCEPTION_RETURN(pJNIEnv); findClass = pJNIEnv->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); EXCEPTION_RETURN(pJNIEnv); return true; }
bool ShowDialog(const char* title, const char *contents, bool exitApp) { jstring jniTitle = g_pMainThreadJNIUtilData->pJNIEnv->NewStringUTF(title); EXCEPTION_RETURN(g_pMainThreadJNIUtilData->pJNIEnv); jstring jniContents = g_pMainThreadJNIUtilData->pJNIEnv->NewStringUTF(contents); EXCEPTION_RETURN(g_pMainThreadJNIUtilData->pJNIEnv); jclass thisClass = g_pMainThreadJNIUtilData->pJNIEnv->GetObjectClass(g_pMainThreadJNIUtilData->ThreadThis); EXCEPTION_RETURN(g_pMainThreadJNIUtilData->pJNIEnv); jmethodID showToastAlert = g_pMainThreadJNIUtilData->pJNIEnv->GetMethodID(thisClass, "showAlert", "(Ljava/lang/String;Ljava/lang/String;Z)V"); EXCEPTION_RETURN(g_pMainThreadJNIUtilData->pJNIEnv); g_pMainThreadJNIUtilData->pJNIEnv->CallVoidMethod(g_pMainThreadJNIUtilData->ThreadThis, showToastAlert, jniTitle, jniContents, exitApp); EXCEPTION_RETURN(g_pMainThreadJNIUtilData->pJNIEnv); }
bool Engine::launchURL(const char* url) { // JNI is running the equivalent of the following Java code // activity.launchURL(url); jstring jniText = mApp->appThreadEnv->NewStringUTF(url); EXCEPTION_RETURN(mApp->appThreadEnv); jclass thisClass = mApp->appThreadEnv->GetObjectClass(mApp->appThreadThis); EXCEPTION_RETURN(mApp->appThreadEnv); jmethodID launchURL = mApp->appThreadEnv->GetMethodID(thisClass, "launchURL", "(Ljava/lang/String;)V"); EXCEPTION_RETURN(mApp->appThreadEnv); mApp->appThreadEnv->CallVoidMethod(mApp->appThreadThis, launchURL, jniText); EXCEPTION_RETURN(mApp->appThreadEnv); return true; }
bool ShowIntersitialAd(char*e_strADMobID) { jclass l_Class = GetCustomJavaClass("util/AdMobUtility"); //jclass l_Class = g_pMainThreadJNIUtilData->pJNIEnv->FindClass("util/AdMobUtility"); jmethodID l_Method = g_pMainThreadJNIUtilData->pJNIEnv->GetStaticMethodID(l_Class,"showInterstitialAd","(Ljava/lang/String;)V"); jstring l_strADMobID = g_pMainThreadJNIUtilData->pJNIEnv->NewStringUTF(e_strADMobID); g_pMainThreadJNIUtilData->pJNIEnv->CallStaticVoidMethod(l_Class, l_Method,l_strADMobID); EXCEPTION_RETURN(g_pMainThreadJNIUtilData->pJNIEnv); g_pMainThreadJNIUtilData->pJNIEnv->DeleteLocalRef(l_Class); return true; }
bool ShowAd(char*e_strADMobID,int e_iWidth,int e_iHeight,Vector2 e_vshowPos) { jclass l_Class = GetCustomJavaClass("util/AdMobUtility"); //jclass l_Class = g_pMainThreadJNIUtilData->pJNIEnv->FindClass("util/AdMobUtility"); jmethodID l_Method = g_pMainThreadJNIUtilData->pJNIEnv->GetStaticMethodID(l_Class,"Show","(Ljava/lang/String;II)V"); jstring l_strADMobID = g_pMainThreadJNIUtilData->pJNIEnv->NewStringUTF(e_strADMobID); g_pMainThreadJNIUtilData->pJNIEnv->CallStaticVoidMethod(l_Class, l_Method,l_strADMobID,e_iWidth,e_iHeight); EXCEPTION_RETURN(g_pMainThreadJNIUtilData->pJNIEnv); g_pMainThreadJNIUtilData->pJNIEnv->DeleteLocalRef(l_Class); return true; }
bool Engine::showToast(const char* text) { // JNI is running the equivalent of the following Java code // activity.showToastAlert(text); jstring jniText = mApp->appThreadEnv->NewStringUTF(text); EXCEPTION_RETURN(mApp->appThreadEnv); jclass thisClass = mApp->appThreadEnv->GetObjectClass(mApp->appThreadThis); EXCEPTION_RETURN(mApp->appThreadEnv); jmethodID showToastAlert = mApp->appThreadEnv->GetMethodID(thisClass, "showToastAlert", "(Ljava/lang/String;)V"); EXCEPTION_RETURN(mApp->appThreadEnv); mApp->appThreadEnv->CallVoidMethod(mApp->appThreadThis, showToastAlert, jniText); EXCEPTION_RETURN(mApp->appThreadEnv); return true; }
bool cDownloadFile::StartToDownload(const char*e_strDownloadFileURL,const char*e_strDescription,const char* e_strTitle,const char*e_strDownloadFileName) { m_strDownloadFileName = e_strDownloadFileName; #ifdef ANDROID RegisterNativeFunction("util/NetworkUtil","DownloadProgress","(I)V",(void*)NetworkUtil_DownloadProgress); jstring l_jnistrURL = cGameApp::m_spThreadEnv->NewStringUTF(e_strDownloadFileURL); EXCEPTION_RETURN(cGameApp::m_spThreadEnv); jstring l_jnistrDescription = cGameApp::m_spThreadEnv->NewStringUTF(e_strDescription); EXCEPTION_RETURN(cGameApp::m_spThreadEnv); jstring l_jnistrTitle = cGameApp::m_spThreadEnv->NewStringUTF(e_strTitle); EXCEPTION_RETURN(cGameApp::m_spThreadEnv); jstring l_jnistrDownloadFileName = cGameApp::m_spThreadEnv->NewStringUTF(e_strDownloadFileName); EXCEPTION_RETURN(cGameApp::m_spThreadEnv); jclass thisClass = GetCustomJavaClass("util/NetworkUtil"); EXCEPTION_RETURN(cGameApp::m_spThreadEnv); jmethodID l_DownloadFileFromNetworkMethod = cGameApp::m_spThreadEnv->GetStaticMethodID(thisClass,"DownloadByDownloadManager","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V"); EXCEPTION_RETURN(cGameApp::m_spThreadEnv); //true for delete old file already download,because we do not check file size,so just delete old to avoid accident. //false for if old file is exists it will skip download //cGameApp::m_spThreadEnv->CallVoidMethod(*cGameApp::m_spAppThreadThis, l_DownloadFileFromNetworkMethod,l_jnistrURL,l_jnistrDescription,l_jnistrTitle,l_jnistrDownloadFileName,false); cGameApp::m_spThreadEnv->CallStaticVoidMethod(thisClass, l_DownloadFileFromNetworkMethod,l_jnistrURL,l_jnistrDescription,l_jnistrTitle,l_jnistrDownloadFileName,true); cGameApp::m_spThreadEnv->DeleteLocalRef(thisClass); //Sleep(1); //cGameApp::m_spThreadEnv->ReleaseStringUTFChars(l_jnistrURL,e_strDownloadFileURL); //cGameApp::m_spThreadEnv->ReleaseStringUTFChars(l_jnistrDescription,e_strDescription); //cGameApp::m_spThreadEnv->ReleaseStringUTFChars(l_jnistrTitle,e_strTitle); //cGameApp::m_spThreadEnv->ReleaseStringUTFChars(l_jnistrDownloadFileName,e_strDownloadFileName); //cGameApp::m_spThreadEnv->ReleaseStringUTFChars(l_jnistrPasseord,e_strZipPassword); #endif return true; }
bool NvAppBase::showDialog(const char* title, const char *contents, bool exitApp) { Engine* engine = (Engine*)getPlatformContext(); struct android_app* app = engine->mApp; jstring jniTitle = app->appThreadEnv->NewStringUTF(title); EXCEPTION_RETURN(app->appThreadEnv); jstring jniContents = app->appThreadEnv->NewStringUTF(contents); EXCEPTION_RETURN(app->appThreadEnv); jclass thisClass = app->appThreadEnv->GetObjectClass(app->appThreadThis); EXCEPTION_RETURN(app->appThreadEnv); jmethodID showToastAlert = app->appThreadEnv->GetMethodID(thisClass, "showAlert", "(Ljava/lang/String;Ljava/lang/String;Z)V"); EXCEPTION_RETURN(app->appThreadEnv); app->appThreadEnv->CallVoidMethod(app->appThreadThis, showToastAlert, jniTitle, jniContents, exitApp); EXCEPTION_RETURN(app->appThreadEnv); return true; }
//from nvidia TADP sample bool OpenURL(const char*e_strURL,sJNIUtilData*e_pJNIUtilData) { // JNI is running the equivalent of the following Java code // Uri uri = Uri.parse(urlString); // Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uri); // startActivity(launchBrowser); // Convert the C string to a JNI string jstring urlText = e_pJNIUtilData->pJNIEnv->NewStringUTF(e_strURL); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // Find the URI class jclass uriClass = e_pJNIUtilData->pJNIEnv->FindClass("android/net/Uri"); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // Find the ID of the URI-from-string parse function (static) jmethodID uriParse = e_pJNIUtilData->pJNIEnv->GetStaticMethodID(uriClass, "parse", "(Ljava/lang/String;)Landroid/net/Uri;"); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // Call: Uri uri = Uri.parse(urlString); jobject uri = e_pJNIUtilData->pJNIEnv->CallStaticObjectMethod(uriClass, uriParse, urlText); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // Find the Intent class jclass intentClass = e_pJNIUtilData->pJNIEnv->FindClass("android/content/Intent"); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // Get the static string field Intent.ACTION_VIEW jfieldID ACTION_VIEW_id = e_pJNIUtilData->pJNIEnv->GetStaticFieldID(intentClass, "ACTION_VIEW", "Ljava/lang/String;"); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); jobject ACTION_VIEW = e_pJNIUtilData->pJNIEnv->GetStaticObjectField(intentClass, ACTION_VIEW_id); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // Get the initializer/constructor for Uri jmethodID newIntent = e_pJNIUtilData->pJNIEnv->GetMethodID(intentClass, "<init>", "()V"); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // Call Intent intent = new Intent(Intent.ACTION_VIEW, uri); // Three stages: alloc object, then call init on it (init is the constructor) // then call the set functions // We SHOULD be able to set URI and Action in <init>; it works on HC and ICS, // but GB fails. So this longer code is safer on GB. jobject intent = e_pJNIUtilData->pJNIEnv->AllocObject(intentClass); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); e_pJNIUtilData->pJNIEnv->CallVoidMethod(intent, newIntent); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // Find the function to set the URL jmethodID setURI = e_pJNIUtilData->pJNIEnv->GetMethodID(intentClass, "setData", "(Landroid/net/Uri;)Landroid/content/Intent;"); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // Set the URL e_pJNIUtilData->pJNIEnv->CallObjectMethod(intent, setURI, uri); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // Find the function to set the Action jmethodID setAction = e_pJNIUtilData->pJNIEnv->GetMethodID(intentClass, "setAction", "(Ljava/lang/String;)Landroid/content/Intent;"); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // Set the Action e_pJNIUtilData->pJNIEnv->CallObjectMethod(intent, setAction, ACTION_VIEW); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); // startActivity(launchBrowser); jclass activityClass = e_pJNIUtilData->pJNIEnv->FindClass("android/app/Activity"); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); jmethodID startActivity = e_pJNIUtilData->pJNIEnv->GetMethodID(activityClass, "startActivity", "(Landroid/content/Intent;)V"); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); e_pJNIUtilData->pJNIEnv->CallVoidMethod(e_pJNIUtilData->ThreadThis, startActivity, intent); EXCEPTION_RETURN(e_pJNIUtilData->pJNIEnv); return true; }