Qt on Android: How to restart your application
Some time ago, I wrote a code to restart the running application on Android.
You might well ask why such a thing was needed. It was needed because there are cases where, whenever a user changes the theme, the application has to restart to apply the change (it can’t be applied on the fly). In my example I used it to restart Qt Quick Controls 2 gallery.
Sadly my fix was not accepted, because other platforms (iOS, IIRC) have this missing feature too, so it was decided to remove Android code so it didn’t stand out.
Anyway, because I think this piece of code might help other people, I’m going to share it with you today.
Our goal is to use AlarmManager.set() method to set an alarm (a PendingIntent) that will start our application in the near future (in our case 100ms from now), then quits the application. When the alarm timeouts it will start our application. Be aware that the AlarmManager is anything but accurate, so it might take more than 100ms to restart the application (in some cases it takes up to 5s to restart it).
Here is the code that does all the magic:
auto activity = QtAndroid::androidActivity(); auto packageManager = activity.callObjectMethod("getPackageManager", "()Landroid/content/pm/PackageManager;"); auto activityIntent = packageManager.callObjectMethod("getLaunchIntentForPackage", "(Ljava/lang/String;)Landroid/content/Intent;", activity.callObjectMethod("getPackageName", "()Ljava/lang/String;").object()); auto pendingIntent = QAndroidJniObject::callStaticObjectMethod("android/app/PendingIntent", "getActivity", "(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;", activity.object(), jint(0), activityIntent.object(), QAndroidJniObject::getStaticField<jint>("android/content/Intent", "FLAG_ACTIVITY_CLEAR_TOP")); auto alarmManager = activity.callObjectMethod("getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;", QAndroidJniObject::getStaticObjectField("android/content/Context", "ALARM_SERVICE", "Ljava/lang/String;").object()); alarmManager.callMethod<void>("set", "(IJLandroid/app/PendingIntent;)V", QAndroidJniObject::getStaticField<jint>("android/app/AlarmManager", "RTC"), jlong(QDateTime::currentMSecsSinceEpoch() + 100), pendingIntent.object()); qApp->quit();
Let’s have a closer look to the code:
- 1st line gets the activity packageManager object.
- 2nd line gets an activityIntent object using the packageManager. getPackageName() method returns the name of this application’s package name.
- 3rd line gets a pendingIntent needed to restart our application.
- 4th line gets the alarmManager
- 5th line sets the pendingIntent to start 100 milliseconds from now.
- 6th line quits the application