2015-10-01 3 views
0

J'essaie d'enregistrer une application Android QtQuick pour ouvrir une certaine classe de fichiers et les gérer. D'après ce que je comprends, quand un fichier est ouvert avec un QApplication il en résulte un QEvent::FileOpen être tiré.Comment s'inscrire à ACTION_VIEW Intention sur Android? Pourquoi ma QApplication ne reçoit-elle pas les événements QEvent :: FileOpen?

La preuve la plus forte (si non concluante) pour ce que j'ai est this commit trouvé dans un système de production, plus un certain nombre de blog posts et Google résultats.

Donc, je crée d'abord un new empty QtQuick project.

Je then write an EventFilter, comme ceci:

#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); 
    } 
} 

Je puis register it et edit my manifest accordingly, en ajoutant

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

À ce stade, je lance mon application dans l'émulateur Android .

Quand j'ouvrir un fichier .foo de ES File Explorer dans mon AVD avec le Nexus 5, API 22, ma demande est en effet apporté au premier plan, mais pasFileOpen événements sont enregistrés.

Si je configure un point d'arrêt dans ma méthode de filtrage, je ne semble pas l'atteindre.

Cela me laisse perplexe.

J'ai essayé l'approche alternative en prolongeant QApplication et en surchargeant event(QEvent *) avec à peu près les mêmes résultats (aucun succès).

Que pourrais-je faire de mal?


S'il vous plaît trouver le dépôt complet pour cette MWE here.

Répondre

1

Je vais répondre à ma propre question après avoir lu Bogdan's tutorials et reçu une aide précieuse de #qt sur Freenode.

Il semble que l'ouverture d'un fichier dans Android ne pas, en fait, entraîner un QEvent::FileOpen, ce qui est utile uniquement sur les systèmes avec un gestionnaire de fenêtres.

Au lieu de cela, il faut subclass QtActivity and override onIntent en Java, puis call an appropriate C++ method avec 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 

Notez qu'il existe some tricky subtleties avec des noms de méthode JNI.

Vous trouverez la version de travail mise à jour de cet exemple here.

+0

Super ça marche. Mais comment puis-je lire le contenu du fichier? QFile :: readAll() Le périphérique d'erreur de lancement n'est pas ouvert. –