10

I have an application which is keeping a log of internally developed applications installed on the device. Upon installation a broadcast receiver for Intent.PACKAGE_ADDED is invoked and records the package name using the following code:

public class NewInstallReceiver extends BroadcastReceiver 
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        Bundle b = intent.getExtras();
        int uid = b.getInt(Intent.EXTRA_UID);
        String[] packages = context.getPackageManager().getPackagesForUid(uid);

        ApplicationService appService = new ApplicationService(context);
        appService.ApplicationInstalled(packages);
    }
}

The problem I'm facing is when using a broadcast receiver for Intent.PACKAGE_REMOVED, all reference to the package via the unique Id (UID) comes back with null information (As you would expect, given its already been uninstalled). I have a temporary solution for the meantime, but its not very elegant, and for the next version I would like to have cleaner code. An example of how the code should work:

public class RemoveApplicationReceiver extends BroadcastReceiver 
{
    @Override
    public void onReceive(Context context, Intent intent) 
    {
        Bundle b = intent.getExtras();
        int uid = b.getInt(Intent.EXTRA_UID);
        String[] packages = context.getPackageManager().getPackagesForUid(uid);

        ApplicationService appService = new ApplicationService(context);
        appService.ApplicationRemoved(packages);
    }

}

So to recap, the question is:

How, after a program has been removed, can I reference the package name in a broadcast receiver for Intent.PACKAGE_REMOVED.

Thanks

Arman
  • 25
  • 7
Martin
  • 1,355
  • 2
  • 14
  • 21
  • I am also getting null from getPackagesForUid(uid). What i want is to get list of all packages installed for current user. Can any one provide some input? – Pratik Sep 26 '13 at 20:44

2 Answers2

18

The package names are in the Intent you got from BroadcasReceiver, use the "getData()" function, there is the ComponentMame of the installed/uninstalled package.

Andreas
  • 1,617
  • 15
  • 18
  • 16
    Worked great... simply used getData().getSchemeSpecificPart(). Thanks – Martin Jan 18 '12 at 14:38
  • 4
    When I print out intent.toString() I can see the package name, but when I use intent.getData().getSchemeSpecificPart() I get an empty string. What am I doing wrong? – gonzobrains Jun 05 '13 at 18:08
  • 4
    @gonzobrains You probably didn't set the scheme? In the manifest, it should look like this: ``. – Anubian Noob Jul 14 '15 at 16:53
0

When installing the application. ACTION_PACKAGE_ADDED
documentation
BroadcastReceiver method onReceive

val packageManager = context.packageManager
val uId = intent.getIntExtra(Intent.EXTRA_UID, -1)
val packageName = packageManager.getPackagesForUid(uId)?.first() ?: return

When uninstalled the application. ACTION_PACKAGE_FULLY_REMOVED or ACTION_PACKAGE_REMOVED
documentation

val packageName = intent.data?.schemeSpecificPart ?: return

Get app name or icon

val applicationInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
  packageManager.getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(0))
} else {
  @Suppress("DEPRECATION")
  packageManager.getApplicationInfo(packageName, 0)
}

val appName = packageManager.getApplicationLabel(applicationInfo)
val appIcon = packageManager.getApplicationIcon(applicationInfo)

Attention
When installing the application, if use intent.data?.schemeSpecificPart not on all devices the correct one is returned package name.

Arman
  • 25
  • 7