gpt4 book ai didi

android - 从 Android Activity onCreate 方法调用 QCoreApplication 方法

转载 作者:太空狗 更新时间:2023-10-29 14:44:13 25 4
gpt4 key购买 nike

我正在为 Android 开发基于 Qt 的应用程序。如果应用程序因打开文件而启动,我需要将其传递给 Qt 应用程序实例。我创建了一个自定义 Java Activity 以实现此行为:

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);
}
} // onCreate

private 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;
}
} // processInputFile

JNIEXPORT 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->RegisterNatives

static 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 应用程序实例的方法?

还有一件事:是否可以获取打开的文件的名称?有时 Intent 的 URI 看起来像“content://downloads/my_downloads/47”,我发现这两种转换方法都不起作用。 QFile 和 QFileInfo 也不返回 fd 的名称。知道名称会很有用,例如,描述正在处理的项目,而 47 并没有真正的意义。

最佳答案

我想我找到了解决这个问题的办法。这是一种解决方法,但应该可以正常工作。

在 onCreate 函数中存储文件路径并从 Qt 主循环调用它:

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();
filePath = "";

if (act != null) && act.compareTo(Intent.ACTION_VIEW) == 0)
{
filePath = i.getData();
}
} // onCreate

public String getFile()
{
return filePath;
}

} // MyActivity

然后在 C++ 调用的 main() 函数中

QAndroidJniObject javaFilePath =  QtAndroid::androidActivity().callObjectMethod("getFile", "()Ljava/lang/String;");
QString filePath = javaFilePath.toString();
if (filePath != "") {
// do something
}

我刚试了一下,好像还行。它可能需要更多的工作来处理所有情况,但作为一个基本的想法,它似乎可以完成这项工作。

另一种可能性是使用未决 Intent ,如 here 所述.它还包含将文件 URI 转换为真实路径的解决方案。

关于android - 从 Android Activity onCreate 方法调用 QCoreApplication 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42644901/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com