Thursday, April 25, 2013

Install apk and uninstall an app via Intents

        Currently am working on a project that requires to build an Android application that will download another apps within itself and install the same. I call the main app as parent app and the apps that will be downloaded as child apps (just for simplicity...... :)). Also it is required that the child apps should not be visible to the user and should be used only via the parent app. Finally when the parent app is uninstalled; it is required that the child apps also be uninstalled.

        Initially I thought that the requirements mentioned above were not possible, but after a little bit of reading I came up with a solution.

              1) The first requirement of downloading and installing an app within another app can be achieved by simply downloading an apk (using http) and installing the apk when download finishes. Android does not authorize to install anything without users consent (unless device is rooted), only thing we can do is prompt the user to install the apk. The app will be installed successfully if user clicks 'Install'.

Intent intent = new Intent(Intent.ACTION_VIEW);
Uri apkUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/Download/" + "app.apk")); 
intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); startActivity(intent);

              2) For the child apps not be visible to user, I simply had to remove intent-filter of the launcher activity from the manifest file. When no launcher activity is present in an application, it does not have a launcher icon.



But in absence of a launcher activity how to launch an application?
Hence, to launch the actiivty we need to provide it a custom action and use it to launch the activity from the parent app.


To launch the above activity the intent call will be as below.

Intent intent = new Intent(); intent.setAction("com.temporary.nolauncher.action.NO_LAUNCHER"); startActivity(intent);

                 3) Finally for uninstalling the child apps when parent app is uninstalled, I had to register a receiver that would catch the event when any app is uninstalled. After the event is caught, I checked which app was uninstalled using the URI. If the parent app is uninstalled then the child app would prompt the user to uninstall itself. Again uninstall can't be achieved without user's consent (unless device is rooted).

The receiver has to be registered in manifest as follows. The action PACKAGE_REMOVED serves the purpose of catching the event when any anpp is uninstalled.


After the event of uinstalling any app is caught in the receiver, we can detect which app was uninstalled (using the intent). The intent returns the package name via the uri. 'intent' reference is avaible from the onReceive method in the receiver.

private String getPackageName(Intent intent) { 
      Uri uri = intent.getData(); 
      String pkg = uri != null ? uri.getSchemeSpecificPart() : null; 
      return pkg; 
}

Finally once the it is detected that the app uninstalled was the parent app then we can fire an intent that will prompt the user to uninstall the child app.

String packToUninstall = "com.temporary.nolauncher"; 
Uri packageURI = Uri.parse("package:" + packToUninstall); 
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,packageURI); uninstallIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ctx.startActivity(uninstallIntent);

 'ctx' reference is avaible from the onReceive method in the receiver.