2015-10-01 9 views
0

Я пытаюсь зарегистрировать приложение QtQuick для Android, чтобы открыть определенный класс файлов и обработать их.Как зарегистрироваться для ACTION_VIEW Intent на Android? Почему мой QApplication не получает события QEvent :: FileOpen?

Из того, что я собираю, когда файл открывается с 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 эмулятор ,

Когда я открываю файл из .foo ES File Explorer в моем AVD с Nexus 5, API 22, мое приложение является действительно принес на первый план, но нетFileOpen события регистрируются.

Если я установил точку останова внутри моего метода фильтрации, я, похоже, не попал в нее.

Это меня озадачивает.

Я пробовал альтернативный подход, расширяя QApplication и перегружая event(QEvent *) с почти такими же результатами (без ударов).

Что я могу делать неправильно?


Пожалуйста, найти полное хранилище для этого MWE here.

ответ

1

Я собираюсь ответить на свой вопрос после изучения Bogdan's tutorials и получить неоценимую помощь от #qt на Freenode.

Похоже, что открытие файла на Android делает не, в действительности это результат QEvent::FileOpen, который полезен только для систем с оконным менеджером.

Вместо этого один должен subclass QtActivity and override onIntent в Java, то 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.

+0

Отлично работает. Но как я могу прочитать содержимое файла? QFile :: readAll() throw error device не открывается. –

+0

@ LiborB. Я не могу, чтобы жизнь меня помнила. Я посмотрю, смогу ли я выкопать этот код в ближайшие дни и попытаюсь ответить вам. –