Qt / C ++ / Android-如何以编程方式安装.APK文件?

阿拉·萨拉(Alaa Salah)

我正在应用程序中实现自己的自动更新程序。我能够成功将较新版本的.apk文件下载到sdcard上/ Download文件夹中,但是我不知道如何打开/运行该文件,因此向用户显示了新的安装对话框。

我唯一能想到的是:

QString downloadedAPK = "/storage/emulated/0/Download/latest.apk"; // Not hardcoded, but wrote it here this way for simplicity
QDesktopServices::openUrl(QUrl(downloadedAPK));

调试器输出:

D/Instrumentation(26418): checkStartActivityResult  :Intent { act=android.intent.action.VIEW dat=file:///storage/emulated/0/Download/latest.apk }
D/Instrumentation(26418): checkStartActivityResult  inent is instance of inent:
W/System.err(26418): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=file:///storage/emulated/0/Download/latest.apk }
W/System.err(26418):    at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1660)
W/System.err(26418):    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1430)
W/System.err(26418):    at android.app.Activity.startActivityForResult(Activity.java:3532)
W/System.err(26418):    at android.app.Activity.startActivityForResult(Activity.java:3493)
W/System.err(26418):    at android.app.Activity.startActivity(Activity.java:3735)
W/System.err(26418):    at android.app.Activity.startActivity(Activity.java:3703)
W/System.err(26418):    at org.qtproject.qt5.android.QtNative.openURL(QtNative.java:110)
W/System.err(26418):    at dalvik.system.NativeStart.run(Native Method)

我到处都看过,但是从Qt打开APK都一无所获。我发现的唯一一件事是使用JNI的soltotoin(我不想使用它,因为使用C ++这样做更简单,并且因为我对整个C ++ / JNI的经验为零),而且没有详细记录,所以我不知道如何使其工作。

那么,打开下载的APK的最简单方法是什么?



编辑:

我遵循了Tumbus的回答,但是由于一些编译错误,我不得不对他的JNI代码进行如下修改:

void Updater::InstallApp(const QString &appPackageName)
{
    qDebug() << "[+] APP: " << appPackageName; // Which is the string ("/storage/emulated/0/Download/latest.apk")
    QAndroidJniObject app = QAndroidJniObject::fromString(appPackageName);
    QAndroidJniObject::callStaticMethod<jint>("AndroidIntentLauncher",
                                       "installApp",
                                       "(Ljava/lang/String;)I",
                                       app.object<jstring>());
}

当我在Android设备上运行应用程序时,它会从服务器中提取最新的.apk文件,然后什么也没有发生。为什么?(到目前为止,我尚未对AndroidManifest.xml进行任何更改)。

墓葬

您必须自定义安装APK的意图。有关详细信息,请参见此问题

恐怕此类特定于平台的想法必须要求调用特定于平台的API。好消息是Qt框架简化了JNI的包装,您可以将Java类包含在Android项目中。因此,我将使自己的静态Java函数从Qt调用。

例子

Java类

package io.novikov.androidintentlauncher;

import org.qtproject.qt5.android.QtNative;

import java.lang.String;
import java.io.File;
import android.content.Intent;
import android.util.Log;
import android.net.Uri;
import android.content.ContentValues;
import android.content.Context;

public class AndroidIntentLauncher
{
    protected AndroidIntentLauncher()
    {
    }

    public static int installApp(String appPackageName) {
        if (QtNative.activity() == null)
            return -1;
        try {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File(appPackageName)), 
                                               "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            QtNative.activity().startActivity(intent);
            return 0;
        } catch (android.content.ActivityNotFoundException anfe) {
            return -3;
        }
    }

}

注意,应该从* QtNative.activity()中将startActivity()作为方法调用。我们必须根据常规规则为Java维护特殊的目录结构。该示例位于下面的Makefile部分。

杰尼

调用此方法的C ++代码有些棘手。

const static char* MY_JAVA_CLASS = "io/novikov/androidintentlauncher/AndroidIntentLauncher";


static void InstallApp(const QString &appPackageName) {
        QAndroidJniObject jsText = QAndroidJniObject::fromString(appPackageName);
        QAndroidJniObject::callStaticMethod<jint>(MY_JAVA_CLASS,
                                           "installApp",
                                           "(Ljava/lang/String;)I",
                                           jsText.object<jstring>());
   }

字符串文字“(Ljava / lang / String;)I”是java方法的签名。Java类的名称必须采用完整格式“ my / domain / my_app / MyClass”

生成文件

最后的挑战是将Java代码正确地包含到您的项目中。.pro文件的相应片段下面

android {
    QT += androidextras
    OTHER_FILES += android_src/src/io/novikov/androidintentlauncher/AndroidIntentLauncher.java
    ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android_src
}

QMake对此作业有一个特殊的变量ANDROID_PACKAGE_SOURCE_DIRJava源代码必须位于ANDROID_PACKAGE_SOURCE_DIR / src / my / domain目录中。同样不要忘记将Java源代码添加到OTHER_FILES并包含androidextras QT选项。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何以编程方式找到android apk安装活动?

来自分类Dev

android 如何以编程方式导出已签名的 apk 文件

来自分类Dev

如何以编程方式从Android应用读取Gradle文件属性

来自分类Dev

Android-如何以编程方式启动设备“文件系统”?

来自分类Dev

如何以编程方式在Android上加载动画XML文件?

来自分类Dev

Android,如何以编程方式播放WAV文件

来自分类Dev

如何以编程方式在android中打开隐藏文件?

来自分类Dev

如何以编程方式更新VSTS文件(使用C#)

来自分类Dev

如何以编程方式安装字体(C#)

来自分类Dev

iOS:如何以编程方式安装配置文件

来自分类Dev

如何使用C#.Net读取Android apk文件的清单?

来自分类Dev

如何使用C#.Net读取Android apk文件的清单?

来自分类Dev

如何以编程方式计算APK文件的哈希值?

来自分类Dev

在Android中以编程方式将所有安装的APK文件备份到sdcard中

来自分类Dev

从市场以外的网站上以编程方式在Android设备上下载,安装和删除.apk文件

来自分类Dev

在Android中以编程方式将所有安装的APK文件备份到sdcard中

来自分类Dev

如何以编程方式检查文件是否是android中的数据库?

来自分类Dev

如何以编程方式在Android Studio中的Google云端硬盘上上传和下载任何文件

来自分类Dev

如何以编程方式从android中的sdcard查找mp3文件

来自分类Dev

如何以编程方式在Android中居中GridLayout(不更改xml文件)?

来自分类Dev

如何以编程方式要求编译器用C ++编译文件?

来自分类Dev

如何以编程方式使用android:digits

来自分类Dev

如何以编程方式导致Android延迟?

来自分类Dev

如何以编程方式执行Android Numpad

来自分类Dev

Android-以编程方式安装.apk时捕获“取消”事件

来自分类Dev

如何以纯Android Studio方式编译我的C ++库(无需自行指定任何.mk文件)

来自分类Dev

是否可以安装Android的.apk文件?

来自分类Dev

无法在Android中提示安装apk文件

来自分类Dev

如何以编程方式备份Realm文件?

Related 相关文章

  1. 1

    如何以编程方式找到android apk安装活动?

  2. 2

    android 如何以编程方式导出已签名的 apk 文件

  3. 3

    如何以编程方式从Android应用读取Gradle文件属性

  4. 4

    Android-如何以编程方式启动设备“文件系统”?

  5. 5

    如何以编程方式在Android上加载动画XML文件?

  6. 6

    Android,如何以编程方式播放WAV文件

  7. 7

    如何以编程方式在android中打开隐藏文件?

  8. 8

    如何以编程方式更新VSTS文件(使用C#)

  9. 9

    如何以编程方式安装字体(C#)

  10. 10

    iOS:如何以编程方式安装配置文件

  11. 11

    如何使用C#.Net读取Android apk文件的清单?

  12. 12

    如何使用C#.Net读取Android apk文件的清单?

  13. 13

    如何以编程方式计算APK文件的哈希值?

  14. 14

    在Android中以编程方式将所有安装的APK文件备份到sdcard中

  15. 15

    从市场以外的网站上以编程方式在Android设备上下载,安装和删除.apk文件

  16. 16

    在Android中以编程方式将所有安装的APK文件备份到sdcard中

  17. 17

    如何以编程方式检查文件是否是android中的数据库?

  18. 18

    如何以编程方式在Android Studio中的Google云端硬盘上上传和下载任何文件

  19. 19

    如何以编程方式从android中的sdcard查找mp3文件

  20. 20

    如何以编程方式在Android中居中GridLayout(不更改xml文件)?

  21. 21

    如何以编程方式要求编译器用C ++编译文件?

  22. 22

    如何以编程方式使用android:digits

  23. 23

    如何以编程方式导致Android延迟?

  24. 24

    如何以编程方式执行Android Numpad

  25. 25

    Android-以编程方式安装.apk时捕获“取消”事件

  26. 26

    如何以纯Android Studio方式编译我的C ++库(无需自行指定任何.mk文件)

  27. 27

    是否可以安装Android的.apk文件?

  28. 28

    无法在Android中提示安装apk文件

  29. 29

    如何以编程方式备份Realm文件?

热门标签

归档