添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
紧张的香瓜  ·  Kubernetes ...·  3 月前    · 
满身肌肉的沙滩裤  ·  趣书网 - 百度·  5 月前    · 
谦虚好学的太阳  ·  Amazon Live·  1 年前    · 
俊秀的盒饭  ·  CloseReason.CloseCodes ...·  1 年前    · 
Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode . Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).

I want to make an automatic update solution on Android, the apk download works, but I can't start it. I found this solution for it:

QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
            if (activity.isValid())
                QAndroidJniObject kindOfActivity    = QAndroidJniObject::fromString("android.intent.action.VIEW");
                QAndroidJniObject apkFile           = QAndroidJniObject::fromString(QString("file://%1/latest.apk").arg(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)));
                QAndroidJniObject apkUri            = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", apkFile.object());
                QAndroidJniObject mimetype          = QAndroidJniObject::fromString("application/vnd.android.package-archive");
                QAndroidJniObject intent("android/content/Intent", "(Ljava/lang/String;)V", kindOfActivity.object());
                intent = intent.callObjectMethod("setDataAndType", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/Intent;", apkUri.object(), mimetype.object());
                intent = intent.callObjectMethod("setFlags", "(I)Landroid/content/Intent;", FLAG_ACTIVITY_NEW_TASK);
                activity.callMethod<void>("startActivity", "(Landroid/content/Intent;)V", intent.object());
            QApplication::exit();

But gives error message:

JNI DETECTED ERROR IN APPLICATION: JNI GetStaticMethodID called with pending exception android.os.FileUriExposedException: file: ///storage/emulated/0/Download/latest.apk exposed beyond app through Intent.getData ()

Thanks in advance for the answers.

You need to process the URI through FileProvider. It's an awfully awkward and tedious thing, but Android requires it since version 6 IIRC.

Basically you need to:

  • Add file provider to res/xml/fileprovider.xml. Example contents:
  • <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <cache-path name="exports" path="." />
        <!--Uncomment below to share the entire application specific directory -->
        <!--<external-path name="all_dirs" path="."/>-->
    </paths>
    
  • Register that provider in your manifest:
  • <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="your.application.domain.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
          <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/fileprovider" />
        </provider>
    
  • In every place in Java you need to use the file provider to "access" that file, instead of regular File/ Intent. I don't have Qt code for this, only some Java (and written for different purpose so it might be incorrect for your case):
  • import android.support.v4.content.FileProvider;
    // ...
    Uri providerUri = FileProvider.getUriForFile(
                    this,
                    "your.application.domain.fileprovider",
                    fileName);
    

    You probably need to do the opposite (get file for URI). Not sure. I wrote this ages ago and APIs in Android keep changing all the time :-(

  • You may also need to add the v4 compat library in gradle config, I'm not sure. It could be something like this:
  • dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
        compile 'com.android.support:support-v4:23.+'
    

    I hope this will help you at least a bit. And sorry for not being more specific, I'm not sure about any of it :D This won't be easy, good luck!

    @ekkescorner said in Android auto update:

    @Kutyus my share example has implemented Android FileProvider https://github.com/ekke/ekkesSHAREexample

    Great example.
    Got it to work immediately with Qt5.12.7, but failure with Qt5.14.2.
    Are you interested to get a bug report? And when where?

    @koahnig said in Android auto update:

    Got it to work immediately with Qt5.12.7, but failure with Qt5.14.2.
    Are you interested to get a bug report? And when where?

    please report at gihub issues https://github.com/ekke/ekkesSHAREexample/issues

    unfortunately most of my examples are 3 years or more old and last 2 years I had to develop so many mobile business apps, so I didn't found enough spare time

    the good thing: starting with Qt 5.15 I'll rework all my examples and blogs to get mobile apps ready for Qt6 / strict QML 3. will reduce work for customers next months and concentrate on 5.15 / 6.0. with some luck all of this will finally end in a book (fingers crossed)

    I made the settings, but on this line, there is always an error:

    QAndroidJniObject uri       = QAndroidJniObject::callStaticObjectMethod("android.support.v4.content.FileProvider", "FileProvider.getUriForFile", "(Landroid/content/Context;Ljava/lang/String;Ljava.io.File;)Landroid/net/Uri;", activity.object(), authority.object(), file.object());
    
    System.err: java.lang.NoSuchMethodError: no static method "Landroid/support/v4/content/FileProvider;.FileProvider.getUriForFile(Landroid/content/Context;Ljava/lang/String;Ljava.io.File;)Landroid/net/Uri;"
    

    I also tried the getUriForFile method without the FileProvider prefix, the same error anyway.

    @Kutyus Your JNI call is not correct, you pass wrong method name!
    It should be:

    QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod(
            "android.support.v4.content.FileProvider", 
            "getUriForFile",  // only the function name!!
            "(Landroid/content/Context;Ljava/lang/String;Ljava.io.File;)Landroid/net/Uri;",
            activity.object(), 
            authority.object(), 
            file.object());
    			

    @KroMignon said in Android auto update:
    I tried anyway. The error in the second parameter was slashes instead of periods in the java.io.File section.
    If I log out after the call, I get an error that there is no activity handling the intent, if I don't log out immediately, there is no error, but nothing happens. I don't know where the error might be.

    @Kutyus You are right, there are many typos!

    QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod(
            "android/support/v4/content/FileProvider", 
            "getUriForFile",  // only the function name!!
            "(Landroid/content/Context;Ljava/lang/String;Ljava/io/File;)Landroid/net/Uri;",
            activity.object(), 
            authority.object(), 
            file.object());