别裁伪体亲风雅,转益多师是汝师。这篇文章主要讲述从Android Activity onCreate方法调用QCoreApplication方法相关的知识,希望能为你提供帮助。
我正在为android开发基于Qt的应用程序。如果应用程序是由于打开文件而启动的,我需要将其传递给Qt应用程序实例。我创建了一个自定义java活动,以实现此行为:
public class MyActivity extends org.qtproject.qt5.android.bindings.QtActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent i = getIntent();
String act = i.getAction();
if (act != null) &
&
act.compareTo(Intent.ACTION_VIEW) == 0)
{
int fd = -1;
try
{
fd = getContentResolver().openFileDescriptor(i.getData(), "r").detachFd();
}
catch (IOException e)
{
Log.e("MyActivity::onCreate", "Exception caught: " + e.getMessage());
}boolean ok = openFd(fd);
}
}// onCreateprivate static native boolean openFd(int fd);
} // MyActivity
在C ++方面,我有这样的事情:
#include <
QDebug>
#include <
jni.h>
jboolean processInputFile(JNIEnv *env, jobject obj, jint fileDescriptor)
{
int fd = (int)fileDescriptor;
qDebug() <
<
"processInputFile called: " <
<
fd;
QFile f;
if (f.open(fd, QIODevice::ReadOnly, QFileDevice::AutoCloseHandle))
{
QFileInfo fi(f);
qDebug() <
<
"Successfully opened the file " <
<
f.fileName() <
<
fi.absoluteFilePath() <
<
fi.canonicalFilePath() <
<
fi.fileName();
return true;
}
else
{
qDebug() <
<
"Failed to open the file: " <
<
f.errorString();
return false;
}
}// processInputFileJNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*)
{
qDebug() <
<
"JNI_OnLoad got called";
JNIEnv* env;
if (vm->
GetEnv(reinterpret_cast<
void**>
(&
env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}jclass javaClass = env->
FindClass("com/mycompany/mypackage/MyActivity");
if(!javaClass)
{
return JNI_ERR;
}// Register methods with env->
RegisterNativesstatic JNINativeMethod methodsArray[] =
{
{"openFd", "(I)Z", (void*)processInputFile}
};
if(env->
RegisterNatives(javaClass, methodsArray, sizeof(methodsArray) / sizeof(methodsArray[0])) <
0)
{
return JNI_ERR;
}return JNI_VERSION_1_6;
}int main(int argc, char *argv[])
{
qDebug() <
<
"Calling main()";
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qDebug() <
<
"main arguments:";
for (int i = 0;
i <
argc;
++i)
qDebug() <
<
argv[i];
// ...
}
调用C ++方法(processInputFile),但它在调用main()函数之前发生,因此尚未创建应用程序对象。我无法处理传入的数据,因为此时处理类不存在。所以我的问题是如何从android.app.Activity :: onCreate方法调用Qt应用程序实例的方法?
还有一件事:是否有可能获得打开的文件的名称?有时意图的URI看起来像“content:// downloads / my_downloads / 47”,而且我发现的转换方法都没有。 QFile和QFileInfo也不返回
fd
的名称。例如,知道名称对于描述正在处理的项目是有用的,而47则没有实际意义。答案我想我找到了解决这个问题的方法。这是一种解决方法,但应该工作正常。
在onCreate函数存储中,filePath和来自Qt主循环的ncall:
public class MyActivity extends org.qtproject.qt5.android.bindings.QtActivity
{String filePath;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent i = getIntent();
String act = i.getAction();
filePath = "";
if (act != null) &
&
act.compareTo(Intent.ACTION_VIEW) == 0)
{
filePath = i.getData();
}
}// onCreatepublic String getFile()
{
return filePath;
}} // MyActivity
然后在你的main()函数中进行C ++调用
QAndroidJniObject javaFilePath =QtAndroid::androidActivity().callObjectMethod("getFile", "()Ljava/lang/String;
");
QString filePath = javaFilePath.toString();
if (filePath != "") {
// do something
}
我只是尝试过它似乎工作。它可能需要更多的工作来处理所有情况,但作为一个基本的想法,它似乎做了这项工作。
【从Android Activity onCreate方法调用QCoreApplication方法】另一种可能性是使用here描述的未决意图。它还包含将文件URI转换为实际路径的解决方案。
推荐阅读
- 如何调查随机Android原生函数调用错误()
- 如何使用/合并CPP文件到Android项目()
- Android JNI - 调用AttachCurrentThread而不使用DetachCurrentThread
- 如何加载android系统本机库
- 使用Android NDK将文件写入SDcard以外的位置()
- Xamarin.Android Java绑定库运行时失败访问本机库
- 如何在tid xxxxx(Thread-X)中解决Android致命信号11(SIGSEGV),代码1,故障地址0x0()
- 如何在Android应用程序中使用Geocoder在特定位置找到大陆
- 从AppWidgetProvider到Broadcastreceiver的意图