Hello. I am writing .net maui application that serves as launcher for another multiplatform application. This launcher can run, install and update this another application.
In case of Android platform launcher loads apk file from the server and creates intent that launches apk installation. The problem is that I can't find a way to catch an event when another app was intstalled or updated in order to do update launcher state (update ui, delete temporary files,..). I tried several approaches in order to do that:
- Using OnActivityResult callback. Intent that install the apk file looks like this:
partial void _Run()
{
var context = Android.App.Application.Context;
Java.IO.File apkFile = new Java.IO.File(_apkPath);
Intent intent = new Intent(Intent.ActionView);
var uri = Microsoft.Maui.Storage.FileProvider.GetUriForFile(context, context.ApplicationContext.PackageName + ".fileProvider", apkFile);
intent.SetDataAndType(uri, "application/vnd.android.package-archive");
intent.AddFlags(ActivityFlags.NewTask);
intent.AddFlags(ActivityFlags.GrantReadUriPermission);
intent.AddFlags(ActivityFlags.ClearTop);
intent.PutExtra(Intent.ExtraNotUnknownSource, true);
Platform.CurrentActivity.StartActivityForResult(intent, 1);
}
}
Method StartActivityForResult starts new activity with code 1. It can be handled in OnActivityResult callback in MainActivity.cs when it ended:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent? data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == 1)
{
// some actions when activity is over
}
}
The problem is that confirmation prompt automatically pops up during apk installation and when it happens activity returns a result (with resultCode = 'Cancel') and algorithm described in OnActivityResult callback is executed before actual apk installation.
- Using BroadcastRecevier that listens installing or updating an application events. For example, in case of installing new application broadcast receiver looks like this:
public class AddedPackageReciever : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == Intent.ActionPackageAdded)
{
// Some actions after installing an application
}
}
}
And it registerd in MainActivity:
public class MainActivity : MauiAppCompatActivity
{
private AddedPackageReciever addedPackageReciever;
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
addedPackageReciever = new AddedPackageReciever();
RegisterReceiver(addedPackageReciever, new IntentFilter(Intent.ActionPackageAdded));
}
...
}
I also added permission QUERY_ALL_PACKAGES in my AndroidManifest.xml file because it required in order to get data from another packages in such cases as mine: https://developer.android.com/training/package-visibility
Full permissions list from AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
But OnRecevie method doesn't execute in case of ActionPackageAdded in intent filter. If I replace it with another one (for example ActionAirplaneModeChanged) then OnRecevie starts to excecute. The same result with ActionPackageReplaced. I have no idea why this two broadcasts don't trigger OnReceive method.
- Using getChangedPackages on PackageManager periodically using JobScheduler. This approach looks suboptimal and my attempts to implement it cause the application to crash on startup.
This is not my first attempt to ask a question in order to solve the issue. But I believe that at this time I formulated it correctly and supplied with all data that I could find. I will appreciate any help.