如何在 Android 上注册 ACTION_VIEW Intent?为啥我的 QApplication 没有收到 QEvent::FileOpen 事件?
Posted
技术标签:
【中文标题】如何在 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?如何在 Android 上注册 ACTION_VIEW Intent?为什么我的 QApplication 没有收到 QEvent::FileOpen 事件? 【发布时间】:2015-10-01 07:20:42 【问题描述】:我正在尝试注册一个 QtQuick android 应用程序来打开某类文件并处理它们。
据我所知,当使用QApplication
打开文件时,会触发QEvent::FileOpen
。
对此我拥有的最有力(如果不确定)证据是在生产系统中发现的 this 提交,以及一些 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 和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 API 22 在我的 AVD 中的 ES 文件资源管理器中打开 .foo
文件时,我的应用程序确实被带到了前台,但是 没有 FileOpen
事件被记录。
如果我在我的过滤器方法中设置了一个断点,我似乎没有命中它。
这让我很困惑。
我通过扩展QApplication
并重载event(QEvent *)
尝试了另一种方法,结果几乎相同(没有命中)。
我做错了什么?
请找到此 MWE here 的完整存储库。
【问题讨论】:
【参考方案1】:在阅读 Bogdan's tutorials 并从 Freenode 上的 #qt
获得一些宝贵的帮助后,我将回答我自己的问题。
看起来在 Android 中打开文件确实不,实际上,会导致QEvent::FileOpen
,这仅在具有窗口管理器的系统上有用。
相反,必须在 Java 中使用 subclass QtActivity
and override onIntent
,然后在 JNI 中使用 call an appropriate C++ method:
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。
【讨论】:
很好用。但是我怎样才能读取文件的内容呢? QFile::readAll() 抛出错误设备未打开。 @LiborB。我这辈子都不记得了。我会看看我是否可以在接下来的几天里挖掘这个代码并尝试回答你。以上是关于如何在 Android 上注册 ACTION_VIEW Intent?为啥我的 QApplication 没有收到 QEvent::FileOpen 事件?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 上注册 ACTION_VIEW Intent?为啥我的 QApplication 没有收到 QEvent::FileOpen 事件?
如何获取 android 设备“上次看到的活动”和“注册日期”