Monday 6 October 2014

Install programmatically an Android .apk file from qt 5 (liveupdate).

A few days ago I managed to install an .apk file from qt using the Java code I found here http://stackoverflow.com/questions/4967669/android-install-apk-programmatically

I modified the code just to use it within qt 5 using the QAndroidJniObject API which allows to interface your code with Java.

Here it is the resulting code snippet:

   1 QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");   
   2 if (activity.isValid()){
   3     QAndroidJniObject kindOfActivity = QAndroidJniObject::fromString(QLatin1String("android.intent.action.VIEW"));
   4     QAndroidJniObject apkFile = QAndroidJniObject::fromString(QLatin1String("file:///pathToApk/new.apk"));
   5     QAndroidJniObject mimetype = QAndroidJniObject::fromString(QLatin1String("application/vnd.android.package-archive"));
   6     QAndroidJniObject intent("android/content/Intent","(Ljava/lang/String;)V",kindOfActivity.object());
   7     QAndroidJniObject myUri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri","parse","(Ljava/lang/String;)Landroid/net/Uri;",apkFile.object());
   8     intent = intent.callObjectMethod("setDataAndType","(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/Intent;",myUri.object(),mimetype.object());
   9     intent = intent.callObjectMethod("setFlags","(I)Landroid/content/Intent;",0x10000000);
  10     activity.callObjectMethod("startActivity","(Landroid/content/Intent;)V",intent.object());
  11 }

The value 0x10000000  corresponds to the FLAG_ACTIVITY_NEW_TASK constant of the Intent class.

The usage of the QAndroidJniObject class and how to correctly submit the method and parameters signatures are explained here http://qt-project.org/doc/qt-5/qandroidjniobject.html

The lines of code like this:
QAndroidJniObject kindOfActivity = QAndroidJniObject::fromString(QLatin1String("android.intent.action.VIEW"));
 are used to build Java Objects from the correponding Qt counterparts (QString to String in this example).

To use these objects as parameters to any Java method, you must call the .object() method of the QAndroidJniObject class as in
QAndroidJniObject myUri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri","parse","(Ljava/lang/String;)Landroid/net/Uri;",apkFile.object());

1 comment:

Anonymous said...

nice post, thanks for this!

it would be awesome if you could add a function which returns the correct path to the apk if we download the apk via the qt app aswell :)