Follow-up to my previous question version 1: How to run a console program which is packed in an Android APK package?
and version 2: How to run a console program that using JNI bridge which is packed in an Android APK package?
the problem still not solved.
In my app written in C++Builder 11.2, I need to run a console program which is packed in the APK. The console program, written in NDK aarch64, is named test_run
, from 2 questions the problem still not solved.
and I changed my mind using jclass in RadStudio it's build successfully but crached:
// copying test_run to the path we can use
// get JAVA_VM and JAVA_ENV first, then:
jclass runtimeClass = JAVA_ENV->FindClass("java/lang/Runtime");
jmethodID getRuntimeMethod = JAVA_ENV->GetStaticMethodID(runtimeClass, "getRuntime", "()Ljava/lang/Runtime;");
jobject runtimeObject = JAVA_ENV->CallStaticObjectMethod(runtimeClass, getRuntimeMethod);
jclass processClass = JAVA_ENV->FindClass("java/lang/Process");
jmethodID execMethod = JAVA_ENV->GetMethodID(runtimeClass, "exec", "(Ljava/lang/String;)Ljava/lang/Process;");
std::string cmd = "chmod a+x ";
cmd += path.c_str();
jstring chmodCmd = JAVA_ENV->NewStringUTF(cmd.c_str());
jobject chmodProcess = JAVA_ENV->CallObjectMethod(runtimeObject, execMethod, chmodCmd);
JAVA_ENV->CallVoidMethod(chmodProcess, JAVA_ENV->GetMethodID(processClass, "waitFor", "()I"));
std::string testCmd = path.c_str();
testCmd += " arguments";
jstring testCmdString = JAVA_ENV->NewStringUTF(testCmd.c_str());
jobject testProcess = JAVA_ENV->CallObjectMethod(runtimeObject, execMethod, testCmdString);
jobject processInputStream = JAVA_ENV->CallObjectMethod(testProcess, JAVA_ENV->GetMethodID(processClass, "getInputStream", "()Ljava/io/InputStream;"));
jclass inputStreamClass = JAVA_ENV->FindClass("java/io/InputStream");
jmethodID readMethod = JAVA_ENV->GetMethodID(inputStreamClass, "read", "([B)I");
jint readBytes = 1;
jint bufferSize = 1024;
jbyteArray buffer = JAVA_ENV->NewByteArray(bufferSize);
std::string output;
while (readBytes > 0) {
readBytes = JAVA_ENV->CallIntMethod(processInputStream, readMethod, buffer);
if (readBytes > 0) {
jbyte* b = JAVA_ENV->GetByteArrayElements(buffer, NULL);
output += std::string((char*)b, readBytes);
JAVA_ENV->ReleaseByteArrayElements(buffer, b, JNI_ABORT);
}
}
ShowMessage(output.c_str());
JAVA_ENV->DeleteLocalRef(runtimeClass);
JAVA_ENV->DeleteLocalRef(processClass);
JAVA_ENV->DeleteLocalRef(runtimeObject);
JAVA_ENV->DeleteLocalRef(testProcess);
JAVA_ENV->DeleteLocalRef(processInputStream);
JAVA_ENV->DeleteLocalRef(inputStreamClass);
JAVA_ENV->DeleteLocalRef(buffer);
please help. thanks