Search code examples
androidapkandroid-download-manager

Download APK from url and execute


I'm using the DownloadManager to download the apk from url. Download completes, I get the onReceive in my BroadcastReceiver for DownloadManager.ACTION_DOWNLOAD_COMPLETE.

Some Coding: I download the apk file from an url to the download directory.

DownloadManager.Request r = new DownloadManager.Request(mUri);
r.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "myapp.apk");
r.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
DownloadManager dm = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE);
SharedPreferences mSharedPref = activity.getSharedPreferences("package", Context.MODE_PRIVATE);
mSharedPref.edit().putLong("downloadID", dm.enqueue(r)).commit();

onReceive

File apkFile = new File(Environment.DIRECTORY_DOWNLOADS + "myapp.apk");
Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
startActivity(promptInstall);

Problems:

  • The file is there, I want to execute it but I package-installer is not shown
  • Even though I see the file in my phones download folder, I if I want to install it there is no package-installer to choose
  • I'm not sure if I do the file and pathing stuff right..
  • I get an parsing error from android when I try to open the file

Someone got an idea please?


Solution

  • I recently had to do something like this, hope it helps:

    EDIT: Couple of notes, apkurl is a string to the download location. Make the byte buffer big enough for your response

        try {
    
            String PATH = Environment.getExternalStorageDirectory() + "/download/";
            File file = new File(PATH);
            file.mkdirs();
            // Create a file on the external storage under download
            File outputFile = new File(file, "app.apk");
            FileOutputStream fos = new FileOutputStream(outputFile);
    
            HttpGet m_httpGet = null;
            HttpResponse m_httpResponse = null;
    
            // Create a http client with the parameters
            HttpClient m_httpClient = setupHttpClient();
            String result = null;
    
            try {
    
                // Create a get object
                m_httpGet = new HttpGet(apkurl);
    
                // Execute the html request
                m_httpResponse = m_httpClient.execute(m_httpGet);
                HttpEntity entity = m_httpResponse.getEntity();
    
                // See if we get a response
                if (entity != null) {
    
                    InputStream instream = entity.getContent();
                    byte[] buffer = new byte[1024];
    
                    // Write out the file
                    int len1 = 0;
                    while ((len1 = instream.read(buffer)) != -1) {
                        fos.write(buffer, 0, len1);
                    }
                    fos.close();
                    instream.close();// till here, it works fine - .apk is download to my sdcard in download file
    
                }
    
            } catch (ConnectTimeoutException cte) {
                // Toast.makeText(MainApplication.m_context, "Connection Timeout", Toast.LENGTH_SHORT).show();
                return false;
            } catch (Exception e) {
                return false;
            } finally {
                m_httpClient.getConnectionManager().closeExpiredConnections();
            }
    
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(
                    Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "app.apk")),
                    "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            MainApplication.getApp().getApplicationContext().startActivity(intent);
    
            // System.exit(0);
    
        } catch (IOException e) {
            Debug.ERROR(CLASSNAME, METHODNAME, "Failed to update new apk");
            return false;
        } catch (Exception e1) {
            Debug.ERROR(CLASSNAME, METHODNAME, "Failed to update new apk");
            return false;
        }
    
        return true;