如何在 Android 上注册 ACTION_VIEW Intent?为什么我的 QApplication 没有收到 QEvent::FileOpen 事件?

How to register for ACTION_VIEW Intent on Android? Why doesn't my QApplication receive QEvent::FileOpen events?

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

据我所知,当使用 QApplication 打开文件时,会触发 QEvent::FileOpen

我拥有的最有力(如果不确定)证据是 this commit found in a production system, plus a number of blog posts 和 Google 结果。

所以,我先创建一个new empty QtQuick project

then write an 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);
  }
}

然后我 register it and edit my manifest accordingly,通过添加

        <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 模拟器中启动我的应用程序。

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

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

这让我很困惑。

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

我可能做错了什么?


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

我将在仔细阅读 Bogdan's tutorials 并从 #qt 在 Freenode 上获得一些宝贵帮助后回答我自己的问题。

它看起来像在 Android 中打开文件 而不是 ,实际上,结果是 QEvent::FileOpen,这仅在具有window 经理。

相反,必须 subclass QtActivity and override onIntent in Java, then call an appropriate C++ method 使用 JNI:

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

请注意,有 some tricky subtleties 带有 JNI 方法名称。

您可以找到此示例的更新后的工作版本 here