Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

android - programatically install a external APK

I am trying to see if it is possible to download and install an apk file and I got as far as testing with an included apk file in the resources folder. I try:

btnGo.addEventListener('click', function() {
   var intent = Ti.Android.createIntent({
    action: Ti.Android.ACTION_VIEW,
    data: 'myapp2.apk',
    type: "application/vnd.android.package-archive"
  });
  Ti.Android.currentActivity.startActivity(intent);
});

but it falls over with ActivityNotFoundException: No Activity found to handle Intent. I am pretty sure this is straigtforward in java, but why not Titanium?

— asked February 9th 2011 by Paul Burrowes
  • android
  • intent
0 Comments

6 Answers

  • Hello,

    i think i found the solution for that problem and managed to work for me,
    so i do this:

    var intent = Ti.Android.createIntent({
        action: Ti.Android.ACTION_VIEW,
        data: 'file:///mnt/sdcard/download/yourapkfile.apk',
        type: "application/vnd.android.package-archive",
        packageName: "com.android.packageinstaller",
        flag: "0x10000000"
    });
    Ti.Android.currentActivity.startActivity(intent);
    

    i added the packageName and the flag.
    i found this by using the download manager from gmail and see what was happening in the log, then i tried to add the packageName and flag and it worked :)

    But first you need to download the apk to your sdcard.

    It still need the input from te user to continue to install.

    — answered November 22nd 2011 by Daniel Jorge
    permalink
    3 Comments
    • Forget to mention that ive tested in 1.8.0.20111106 SDK with Ti Studio 1.0.7.201111212347 in device with android 2.3

      — commented November 22nd 2011 by Daniel Jorge
    • Worked for me greatly, thanks

      — commented January 11th 2014 by Visuddha Karunaratne
    • Hello!
      I am programming in Titanium, and I am making a app in two plataforms (Android and iOS).
      I need open different app since a main app. Your code is good but would I do similar process in iOS, is it possible?

      — commented January 29th 2014 by Mariela Brenes
  • I've got the same issue…
    Do you solve it?

    — answered December 16th 2011 by chi xuan
    permalink
    7 Comments
    • @chi xuan did you try my solution?

      var intent = Ti.Android.createIntent({
          action: Ti.Android.ACTION_VIEW,
          data: 'file:///mnt/sdcard/download/yourapkfile.apk',
          type: "application/vnd.android.package-archive",
          packageName: "com.android.packageinstaller",
          flag: "0x10000000"
      });
      Ti.Android.currentActivity.startActivity(intent);
      

      — commented December 16th 2011 by Daniel Jorge
    • Hi,It's ok now.
      Just use the api as

      var fileUri = file.nativePath;
      var intent = Ti.Android.createIntent({
                      action: Ti.Android.ACTION_VIEW,
                      data: fileUri,
                      type: "application/vnd.android.package-archive"
      });    
      
      Ti.Android.currentActivity.startActivity(intent);
      

      Tks Daniel Jorge!

      — commented December 19th 2011 by chi xuan
    • I am sorry Daniel Jorge.
      When i use my code the view will show “There is a problem parsing the package”

      When i use your code the view will show “There is a problem parsing the package”

      what can i do?

      — commented December 22nd 2011 by chi xuan
    • @Daniel Jorge Thank you

      — commented December 22nd 2011 by chi xuan
    • Hi @chi xuan,

      Do you have the file in the right directory?
      this is what a do:

      
      //create a view to add the progress bar
      var view = Ti.UI.createView({
            height: 'auto',
            width: 'auto'
      });
      
      //progress bar
      var ind = Titanium.UI.createProgressBar({
              width:'90%',
              min:0,
              max:1,
              value:0,
              color:'#fff',
              font:{fontSize:14, fontWeight:'bold'}
      }); 
      view.add(ind);
      
      
      //dialog that i will add the view to show the progressbar
      var progress_dial = Titanium.UI.createAlertDialog({
                  buttonNames: ['cancel'],
                  title: title,
                  message: msg
              }); 
      
      
      var progress_dial_cancel = false;
      
      
      /****************/
      
      
      Ti.API.info("doanloading......");
      ind.value = 0; //reset the progressbar
      progress_dial.androidView = view; //add the view to the dialog
      progress_dial.show();
      
      progress_dial.addEventListener('click', function(e){
             if(e.index === 0) {
                     progress_dial_cancel = true;
              //this is to help aborting the connection
             } 
      });
      
      var filename = 'file.apk';
      
      //defines the path to the downalods folder in sdcard             
      if(Ti.Filesystem.isExternalStoragePresent()){
          var _storage = 'file:///sdcard/download/';                       
      }
      
      var localFilepath = _storage + apk_filename;
      
      var c = Titanium.Network.createHTTPClient();
      c.setTimeout(10000);
      
      c.onload = function(e) {
              if(progress_dial_cancel === false) {
                  Ti.API.info('MyApp: (Andoid) Downloaded this file from server:.' + localFilepath);
                  var f = Titanium.Filesystem.getFile(localFilepath);
                  f.write(c.responseData);
                  progress_dial.hide();
                  var intent = Ti.Android.createIntent({
                           action: Ti.Android.ACTION_VIEW,
                           data: localFilepath,
                           type: "application/vnd.android.package-archive",
                           packageName: "com.android.packageinstaller",
                           flag: "0x10000000"
                  });
                  Ti.Android.currentActivity.startActivity(intent);  
              }
              else {
                    c.abort();
              }
      };
      
      c.ondatastream = function(e) {
              Ti.API.info('ONDATASTREAM1 - PROGRESS: ' + e.progress);
              ind.value = e.progress; //update the progressbar
              progress_dial.message = 'downloading.... ' + (e.progress.toPrecision(2) * 100) + '%';
      };
      c.onerror = function(e) {
             Ti.API.info('XHR Error ' + e.error);
      };
      c.open('GET', apk_url);
      
      c.send();
      

      hope that it helps you :)

      — commented December 22nd 2011 by Daniel Jorge
    • @Daniel Jorge Thank you very much for helping!
      It's OK now.
      The main reason is, i use Ti.Filesystem.applicationDataDirectory to keep the apk file,I don't know what cause the installation dosnot work.
      I am greatly illuminated by your code. Thank you!!!

      — commented December 23rd 2011 by chi xuan
    • Can this be installed from the Application Directory yet?

      — commented December 11th 2012 by Jeff Lukin
  • Hello,

    Did u find an answer ? I've got the same issue…

    — answered August 31st 2011 by Florence Trichet
    permalink
    0 Comments
  • Hello,

    I also have the same problem.
    As soon i use data: or type: in Ti.Android.createIntent i get: ActivityNotFoundException.
    I hope someone has a solution.

    — answered September 29th 2011 by Marcel de Poel
    permalink
    0 Comments
  • @chi xuan, sometimes i had problems with Ti.Filesystem.applicationDataDirectory, then i changed to the sdcard and it works very well. Im glad to help.

    — answered December 23rd 2011 by Daniel Jorge
    permalink
    0 Comments
  • Does anyone know how to launch the package installed from the app ?

    — answered May 29th 2013 by Ludovic Lecerf
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.