0

我正在尝试注册一个 QtQuick Android 应用程序来打开某类文件并处理它们。

据我所知,当使用 a 打开文件时,QApplication会导致 aQEvent::FileOpen被触发。

我所拥有的最有力的(如果不确定的话)证据是在生产系统中发现的这个提交,以及一些博客文章和谷歌结果。

所以,我首先创建一个新的空 QtQuick 项目

然后我写一个 EventFilter,像这样:

#include <QtGui>
#include <QApplication>

#include <QFileOpenEvent>

class MyEventFilter : public QObject {
  public:
  MyEventFilter();
  virtual ~MyEventFilter();
protected:
  virtual bool eventFilter(QObject* object,QEvent* event);
};

#include "myeventfilter.h"

MyEventFilter::MyEventFilter() : QObject () {}
MyEventFilter::~MyEventFilter() {}
bool MyEventFilter::eventFilter(QObject* object,QEvent* e) {
  qDebug() << "Received" << e->type();
  if (e->type() == QEvent::FileOpen) {
      QFile file(static_cast<QFileOpenEvent *>(e)->file());
      qDebug() << "File to open:" << file.fileName();
      // This is where I would do stuff
      return true;
  } else {
      return QObject::eventFilter(object,e);
  }
}

然后我注册它相应地编辑我的清单,通过添加

        <intent-filter android:label="Foo File" android:priority="1">
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>
            <data android:scheme="file" android:host="success"/>
            <data android:host="*"/>
            <data android:mimeType="*/*"/>
            <data android:pathPattern=".*\\.foo"/>
        </intent-filter>

此时,我在 Android 模拟器中启动了我的应用程序。

当我.foo使用 Nexus 5、API 22 在我的 AVD 中从 ES 文件资源管理器打开文件时,我的应用程序确实带到了前台,但没有 FileOpen记录任何事件

如果我在我的过滤器方法中设置了一个断点,我似乎没有命中它。

这让我很困惑。

我尝试了另一种方法,方法是扩展QApplication和重载event(QEvent *)几乎相同的结果(没有命中)。

我可能做错了什么?


请在此处找到此 MWE 的完整存储库。

4

1 回答 1

2

在阅读了Bogdan 的教程#qt并从Freenode 上获得了一些宝贵的帮助后,我将回答我自己的问题。

看起来在 Android 中打开文件实际上不会产生QEvent::FileOpen,这仅在具有窗口管理器的系统上有用。

相反,必须在 Java中继承QtActivity和覆盖onIntent,然后使用 JNI调用适当的 C++ 方法:

package com.foo;

import android.content.Intent;

import org.qtproject.qt5.android.bindings.QtActivity;

class Bar
{
    public static native void openUri(String uri);
    // Notice the 'native' keyword
}

public class MyActivity extends QtActivity {
    public void onNewIntent(Intent i) {
        if (i.getAction() == Intent.ACTION_VIEW) {
            Bar.openUri(i.getData().toString());
        }
        super.onNewIntent(i);
    }
}

class URIHandler : public QObject {
public:
    void openUri(QString uri) {
        qDebug() << "Open URI" << uri;
    }
}

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void JNICALL
  Java_com_foo_Bar_openUri(JNIEnv *env,
                                                    jobject obj,
                                                    jstring uri)
{
    jboolean isCopy;
    isCopy = false;
    const char* utf = env->GetStringUTFChars(uri, &isCopy);
    handler.openUri(QString(utf));
    env->ReleaseStringUTFChars(uri, utf);

}

#ifdef __cplusplus
}
#endif

请注意,JNI 方法名称有一些微妙之处

您可以在此处找到此示例的更新工作版本。

于 2015-10-01T19:40:50.413 回答