I'm developing an app that runs as Device Owner, and I want to build an automatic updater inside it.
To do it I use the PackageInstaller, as I have the privileges to use it due to my Device owner position.
private void installPackage(InputStream inputStream)
throws IOException {
notifyLog("Inizio aggiornamento...");
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
int sessionId = packageInstaller.createSession(new PackageInstaller
.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL));
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
long sizeBytes = 0;
OutputStream out = null;
out = session.openWrite("my_app_session", 0, sizeBytes);
int total = 0;
byte[] buffer = new byte[65536];
int c;
while ((c = inputStream.read(buffer)) != -1) {
total += c;
out.write(buffer, 0, c);
}
session.fsync(out);
inputStream.close();
out.close();
session.commit(createIntentSender(sessionId));
}
private IntentSender createIntentSender(int sessionId) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
sessionId,
new Intent(LauncherReceiver.START_INTENT),
0);
return pendingIntent.getIntentSender();
}
The update goes right, but the problem is that it doesn't re-open the app itself after the update, even if I set an IntentSender to broadcast the action LauncherReceiver.START_INTENT
to the new app instance (that will bring it on to start).
Here it is my Receiver:
public class LauncherReceiver extends BroadcastReceiver {
public static final String START_INTENT = "com.aaa.aaa.action.START";
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("CALL RECEIVER!!");
Intent startIntent = new Intent(context, StartActivity.class);
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(startIntent);
}
}
And it is registered in my manifest:
<receiver android:name=".receivers.LauncherReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="com.aaa.aaa.action.START"></action>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
If I call it by CLI it works:
am broadcast -a com.worldnet.gestitruck.action.START
So the receiver works but for some reason it doesn't work from the Package Installer session commit. The app close itself due to the upgrade but does't open again.
If I change the createIntentSender
to this:
private IntentSender createIntentSender(int sessionId) {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:0123456789"));
PendingIntent pendingIntent = PendingIntent.getActivity(context,sessionId,intent,0);
return pendingIntent.getIntentSender();
}
it actually opens the phone service. So I think the problem reside in the upgrade lifecycle, as the app is not ready when the broadcast action is spawned.
Moreover, I made another try and I created a side app that does nothing but call the broadcast action to my main app, so I can call this side app and with this "double step" it can actually re-open the just updated app. The problem is that I have to install two apps =/
Can anybody help me? Is there a way to re-open the just updated app?
android.content.pm.PackageInstaller. Offers the ability to install, upgrade, and remove applications on the device. This includes support for apps packaged either as a single "monolithic" APK, or apps packaged as multiple "split" APKs. An app is delivered for installation through a PackageInstaller.
Since Package Installer is built into the Android OS, it is not possible for a normal user to remove the package installer from the device. One also cannot uninstall the Package Installer from Android.
PackageInstaller is the default application for Android to interactively install a normal package. PackageInstaller provide user interface to manage applications/packages. PackageInstaller calls InstallAppProgress activity to receive instructions from the user.
Starting from about Android 5 (I don't know the exact API level), Android will send a broadcast Intent
with ACTION="android.intent.action.MY_PACKAGE_REPLACED"
after your app is updated. Just add
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
to your <receiver>
declaration and you should be able to listen for this and restart your app in onReceive()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With