[SOLVED] Qt on Android : Open an external file



  • I'd like to open an external file from my app (for Android) but I have a big problem.

    The code is the following:

    @
    QString myfile;
    myfile = "/data/data/com.sample.org/sample.kml";
    myfile = QDir::toNativeSeparators(myfile);
    myfile = "file:///" + myfile;
    QDesktopServices::openUrl(QUrl(myfile));
    @

    If I run the same code in the desktop I haven't problem and the file is opened (in particolar mode Window ask me what application I have to associate to open the file; Google Earth in this case).

    The same example worked fine with Symbian, but with Android I have no response.

    Please can you help me ? There is a alternative way ?



  • I guess you add an extra slash '/', try delete one.
    Another proper way to test whether this url is correct is using QFileDialog to let user select one, then print the file path selected by the user.



  • I did several tests:

    @

    QString myfile;
    myfile = getXMLFileName();
    myfile = QDir::toNativeSeparators(myfile);
    myfile = "file:////" + myfile;
    QDesktopServices::openUrl(QUrl(myfile));
    @

    after also the following:

    @
    QString myfile;
    myfile = getXMLFileName();
    myfile = QDir::toNativeSeparators(myfile);
    myfile = "file://" + myfile;
    QDesktopServices::openUrl(QUrl(myfile));
    @

    and the following:

    @
    QString myfile;
    myfile = getXMLFileName();
    myfile = QDir::toNativeSeparators(myfile);
    QDesktopServices::openUrl(QUrl(myfile));
    @

    but none works.

    The Application output is the following:

    @D/Instrumentation(13081): checkStartActivityResult :Intent { act=android.intent.action.VIEW dat=/data/data/org.qtproject.gsp/files/gps.kml }
    D/Instrumentation(13081): checkStartActivityResult inent is instance of inent:
    W/System.err(13081): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=/data/data/org.qtproject.gsp/files/gps.kml }
    W/System.err(13081): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1580)
    W/System.err(13081): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1431)
    W/System.err(13081): at android.app.Activity.startActivityForResult(Activity.java:3428)
    W/System.err(13081): at android.app.Activity.startActivityForResult(Activity.java:3389)
    W/System.err(13081): at android.app.Activity.startActivity(Activity.java:3599)
    W/System.err(13081): at android.app.Activity.startActivity(Activity.java:3567)
    W/System.err(13081): at org.qtproject.qt5.android.QtNative.openURL(QtNative.java:116)
    W/System.err(13081): at dalvik.system.NativeStart.run(Native Method)
    W/IInputConnectionWrapper(13081): getSelectedText on inactive InputConnection
    W/IInputConnectionWrapper(13081): setComposingText on inactive InputConnection
    W/IInputConnectionWrapper(13081): getExtractedText on inactive InputConnection@

    I think it is a permissions issue.

    to resolve the problem above I have add the following block inside the AndroidMnifest:

    @<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="file">
    </intent-filter>@

    and now I haven't the error above but the file is not opened......(from google earth or another program).

    The message inside the Application output now is the following:

    @D/AbsListView( 9087): Get MotionRecognitionManager@

    but the application associate don't start...

    Where am I doing wrong?



  • Perhaps, there is no application assigned to open this kind of file.

    QDesktopServices::openUrl() should use local system resources to open the file.

    Try to open more common files like: mp3 , html, pdf or text files.



  • I have change the directory where I create the kml file:

    from

    /data/data/org.qtproject.gsp/files/gps.kml

    to

    /storage/sdcard0/Documents/gps.kml

    and I have removed the code inside the AndroidManifest following:

    @<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="file">
    </intent-filter>@

    and now the Google Earth start.

    bq. Probably the initial directory was not accessible.

    1) Google Earth start but does not load the KML file even if it is well-formed

    2) An App in which directory should create a file? Is there a directory name in which to write the official files?



  • bq. 2) An App in which directory should create a file? Is there a directory name in which to write the official files?

    For the scond question, the answer is the following: (what I used)

    @QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);

    path.append("/gps");@

    bq. 1) Google Earth start but does not load the KML file even if it is well-formed

    for the moment I have no solution.

    My app open the Google Earth but not view the path inside the kml file.

    If I open the file without app from file browser the kml file is opend well.

    very strange



  • I have found an altenative solution.

    I can call a java class file from qt c++ and open the file using JNI method.

    The java class is the following:

    @//
    // Next72Utility.java
    //
    package org.qtproject.example.Chronometer;

    import android.app.Activity;
    import java.lang.Runnable;
    import android.content.Intent;
    import java.io.File;
    import android.net.Uri;

    public class Next72Utility extends org.qtproject.qt5.android.bindings.QtActivity
    {

    public static Next72Utility m_istance;

    public Next72Utility()
    {
    m_istance = this;
    }

    public static void openUrl(final String m_url, final String m_application_type)
    {
    m_istance.runOnUiThread(new Runnable() {
    public void run() {

             Intent intent = new Intent();
             intent.setAction(android.content.Intent.ACTION_VIEW);
             File file = new File&#40;m_url&#41;;
             intent.setDataAndType(Uri.fromFile(file&#41;, m_application_type&#41;;
             m_istance.startActivity(intent);
         }
       });
    

    }

    }@

    and the call from c++ is the following:

    @QAndroidJniObject m_url = QAndroidJniObject::fromString("storage/sdcard0/gps/gps.kml");

    QAndroidJniObject m_application_type = QAndroidJniObject::fromString("application/vnd.google-earth.kml+xml");

    QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/Chronometer/Next72Utility", "openUrl", "(Ljava/lang/String;Ljava/lang/String;)V",m_url.object<jstring>(),m_application_type.object<jstring>());@



  • I agree that it was a permissions problem.

    I finally succeeded in opening a KML file in Google Earth without resorting to JNI.
    The KML file must be located in external storage where Google Earth can access it.

    @
    // Saving KML file in QStandardPaths::DownloadLocation will work
    QString destinationFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);

    // The KML file must be opened from a folder accessible to Google Earth app
    // This will not work: /data/data/com.myccompany.myapp/
    // This works........: /storage/emulated/0/Download/JOB-0001.kml
    // /storage/sdcard0/Download/JOB-0001.kml
    //
    // Android: QStandardPaths::DownloadLocation

    QUrl urlToLocalKmlFile =
            QUrl::fromLocalFile&#40;kmlFileNamePath&#41;;
    bool success = QDesktopServices::openUrl(urlToLocalKmlFile&#41;;
    if( success&#41;
    {
        return;
    }
    
    qCritical("openUrl failed?");
    

    @



  • <deleted>


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.