#include "mainwindow.h" #include #include #ifndef WIN32 #include #include #endif #include #include #include #include #ifdef WIN32 static std::string fileName = "foo.txt"; #else static std::string fileName = "/sdcard/Documents/foo.txt"; #endif MainFrame::MainFrame() { // create a file: std::fstream file; file.open( fileName.c_str(), std::ios_base::out ); file << "Hello World!" << std::endl; file.close(); QWidget* centralWidget = new QWidget( this ); centralWidget->setLayout( new QVBoxLayout() ); QPushButton* qt_button = new QPushButton( "Open with Qt", centralWidget ); QObject::connect( qt_button, SIGNAL(clicked()), this, SLOT(openFromQt()) ); centralWidget->layout()->addWidget( qt_button ); #ifndef WIN32 QPushButton* sdk_button = new QPushButton( "Open with SDK", centralWidget ); QObject::connect( sdk_button, SIGNAL(clicked()), this, SLOT(openFromSDK()) ); centralWidget->layout()->addWidget( sdk_button ); #endif setCentralWidget( centralWidget ); } void MainFrame::openFromQt() { // use Qt code to open a file. Works on PC, not on Android QUrl url = QUrl::fromLocalFile(fileName.c_str()); QDesktopServices::openUrl(url); } #ifndef WIN32 std::string GetFileType( const std::string& fileName ) { QAndroidJniObject javaFileName = QAndroidJniObject::fromString(fileName.c_str()); //type is valid QAndroidJniObject extension = QAndroidJniObject::callStaticObjectMethod("android/webkit/MimeTypeMap", "getFileExtensionFromUrl", "(Ljava/lang/String;)Ljava/lang/String;", javaFileName.object()); if ( extension.isValid() ) { std::string ext = extension.toString().toStdString(); QAndroidJniObject mime = QAndroidJniObject::callStaticObjectMethod("android/webkit/MimeTypeMap", "getSingleton", "()Landroid/webkit/MimeTypeMap;"); if ( mime.isValid() ) { QAndroidJniObject type = mime.callObjectMethod("getMimeTypeFromExtension", "(Ljava/lang/String;)Ljava/lang/String;", extension.object() ); if ( type.isValid() ) { return type.toString().toSDEString(); } } } return "text/plain"; } void MainFrame::openFromSDK() { // access native Android code to open the file, it works! QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); //activity is valid if ( activity.isValid() ) { QAndroidJniObject intent("android/content/Intent","()V"); if ( intent.isValid() ) { QAndroidJniObject name = QAndroidJniObject::fromString(fileName.c_str()); //type is valid std::string mimeType = GetFileType(fileName); QAndroidJniObject type = QAndroidJniObject::fromString(mimeType.c_str()); //type is valid // should we actually use QAndroidJniObject::getStaticObjectField("android/intent/action","ACTION_VIEW"); ? QAndroidJniObject action = QAndroidJniObject::fromString("android.intent.action.VIEW"); if ( type.isValid() && name.isValid() && action.isValid() ) { QAndroidJniObject file( "java/io/File","(Ljava/lang/String;)V",name.object()); if ( file.isValid() ) { jboolean exists = file.callMethod("exists","()Z"); if ( exists ) { QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "fromFile", "(Ljava/io/File;)Landroid/net/Uri;", file.object()); if ( uri.isValid() ) { intent.callObjectMethod("setDataAndType","(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/Intent;",uri.object(),type.object()); intent.callObjectMethod("setAction","(Ljava/lang/String;)Landroid/content/Intent;",action.object()); intent.callObjectMethod("setFlags","(I)Landroid/content/Intent;",0x10000000); if ( intent.isValid() ) { activity.callMethod("startActivity","(Landroid/content/Intent;)V",intent.object()); } } } } } } } } #else void MainFrame::openFromSDK() { } #endif