3

I am creating an application that installs apps downloaded from a server. I would like to Install these application After the file is downloaded the code for the method I am using to install is here:

 public void Install(String name)
{
    //prompts user to accept any installation of the apk with provided name
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(new File
    (Environment.getExternalStorageDirectory() + "/ContentManager/" + name)), "application/vnd.android.package-archive");
    startActivity(intent);
    //this code should execute after the install finishes
    File file = new File(Environment.getExternalStorageDirectory() + "/ContentManager/"+name);
    file.delete();

}

I would like to have the apk file deleted from the sd card after the install is completed. This code deletes it once the install is started, causing the installation to fail. I am fairly neew to android and would much appreciate some help. I am basically trying to wait for the installation to complete before continuing with the process.

Bmoore
  • 315
  • 4
  • 16
  • This isn't an answer, but more to alert you to a possibility and potentially save you time and effort into something that may not be allowed. I'm not sure, perhaps someone else here can confirm, but I think downloading apps from anywhere other than the Marketplace is disallowed. – providence Mar 03 '11 at 06:05
  • already have the code that downloads the application from a private server I have set up, this install code works, but the apk persists afterwards and I want it to be deleted. – Bmoore Mar 03 '11 at 22:43
  • possible duplicate of [Delete an application (\*.apk) after installation](http://stackoverflow.com/questions/15984546/delete-an-application-apk-after-installation) – Gokul Nath KP Oct 09 '13 at 09:36

2 Answers2

12

The Android package manager sends various broadcast intents while installing (or updating / removing) applications.

You can register broadcast receivers, so you will get notifications e.g. when a new application has been installed.

Intents that might be interesting for you are:

Using broadcast receivers is not a big deal:

BroadcastReceiver myReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // do whatever you want to do
    }
};

registerReceiver(myReceiver, new IntentFilter("ACTION"));
unregisterReceiver(myReceiver);
Leo
  • 37,640
  • 8
  • 75
  • 100
  • This code seems like it will work, but I cant seem to get the Broadcast receiver to receive anything, I initialize it in the main thread and nothing seems to happen. Any help would be appreciated. – Bmoore Mar 04 '11 at 17:23
  • @Bmoore which action do you register and how exactly? – Leo Mar 04 '11 at 23:33
  • I copied that code, and put it at the top of my class and changed the "ACTION" in the intent filter to "ACTION_PACKAGE_INSTALL" – Bmoore Mar 05 '11 at 15:08
  • 2
    @Bmoore ok, you have to use either `"android.intent.action.PACKAGE_INSTALL"` or `Intent.ACTION_PACKAGE_INSTALL`. Btw, this is sent when starting an installation - ACTION_PACKAGE_ADDED might be better for you ;) – Leo Mar 05 '11 at 16:10
  • @Mef : i was trying to use your code but could get any result it would be great if can help me ... Please answer given by me .. – Code_Life Jan 11 '12 at 12:05
  • 1
    PACKAGE_INSTALL is deprecated , use package_added – Yehonatan Jan 24 '17 at 07:56
4

This might not be the best way but I solved the problem. Here is my new code for the method.

 public void Install(final String name,View view)
{
    //prompts user to accept any installation of the apk with provided name
    printstatus("Installing apk please accept permissions");
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(new File
    (Environment.getExternalStorageDirectory() + "/ContentManager/" + name)), "application/vnd.android.package-archive");
    startActivity(intent);
    try {
        Thread.sleep(1500);
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    for(int i=0;i<100;)
    {
        System.gc();
        if(view.getWindowVisibility()==0)
        {
            i=200;
            System.gc();
        }
        try {
            Thread.sleep(500);
            System.gc();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    File file = new File(Environment.getExternalStorageDirectory() + "/ContentManager/"+name);
    file.delete();
}

I created a loop that will wait until the window is in the front to let the method continue executing. The garbage collector and thread sleeping prevents it from slowing down the system or the Linux kernel killing the process. The sleep before the loop is needed so the package manager has time to start before the loop begins.

Bmoore
  • 315
  • 4
  • 16