9


I've developed some android games and created .apk file..
I've put these .apk files on my website (say: http://www.sush19.com/androidApp/apk/myGame1.apk) Is it possible to directly install this game when this url visit from another app onClick() event.

I don't want user to download .apk fine to their sdcard and then install manually, infact the game should be installed directly to the device.

I was trying below code in my another app onClick() event:

Intent goToMarket = new Intent(Intent.ACTION_VIEW).setData(Uri.parse("http://www.sush19.com/androidApp/apk/myGame1.apk"));
startActivity(goToMarket);

I know the above code is not correct.. but can anyone comment on this..

Swati Garg
  • 995
  • 1
  • 10
  • 21
Sushil
  • 533
  • 2
  • 8
  • 28
  • 1
    They can download APK file and install them from SD or phone. – Ing. Michal Hudak Nov 19 '13 at 06:53
  • Thank you for your answer. downloading the APK file and installing them from SDcard is working fine. But I don't want to download the `.apk` file, directly I want to prompt to the user saying something like this: `you are about to install myGame1 on your device`, `OK` or `Cancel` and on clicking `OK` the game should install to the device same way we install apps from marketplace. – Sushil Nov 19 '13 at 09:12

2 Answers2

17

The below code, allow user to Download, Install and Delete .apk file on Android device. I've created an Android app (Say App1), which downloads other android apps on SD card. On Button click in App1, it will download the .apk file from my own website on Background, on download complete it will prompt user to install the app downloaded recently from App1 and after the installation is completed the downloaded .apk file will be deleted from the SD card.

In my App1 main activity: I've included button
In my case I'm launching my other applications from App1, if not installed on the device, I'm downloading it from my website and installing it.
button click event method

public OnClickListener ButtonClicked = new OnClickListener() {
        public void onClick(View v) {
            Intent i;
            PackageManager manager = getPackageManager();
            try {
                i = manager.getLaunchIntentForPackage("com.mycompany.mygame");
                if (i == null)
                    throw new PackageManager.NameNotFoundException();
                i.addCategory(Intent.CATEGORY_LAUNCHER);
                startActivity(i);
            } catch (PackageManager.NameNotFoundException e) {
                InstallAPK downloadAndInstall = new InstallAPK();
                progress.setCancelable(false);
                progress.setMessage("Downloading...");
                downloadAndInstall.setContext(getApplicationContext(), progress);
                downloadAndInstall.execute("http://xyz/android/gamedownload.aspx?name=mygame.apk");
            }
        }
    };

InstallAPK Class

public class InstallAPK extends AsyncTask<String,Void,Void> {

    ProgressDialog progressDialog;
    int status = 0;

    private Context context;
    public void setContext(Context context, ProgressDialog progress){
        this.context = context;
        this.progressDialog = progress;
    }

    public void onPreExecute() {
        progressDialog.show();
    }

    @Override
    protected Void doInBackground(String... arg0) {
        try {
            URL url = new URL(arg0[0]);
            HttpURLConnection c = (HttpURLConnection) url.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();

            File sdcard = Environment.getExternalStorageDirectory();
            File myDir = new File(sdcard,"Android/data/com.mycompany.android.games/temp");
            myDir.mkdirs();
            File outputFile = new File(myDir, "temp.apk");
            if(outputFile.exists()){
                outputFile.delete();
            }
            FileOutputStream fos = new FileOutputStream(outputFile);

            InputStream is = c.getInputStream();

            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len1);
            }
            fos.flush();
            fos.close();
            is.close();

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File(sdcard,"Android/data/com.mycompany.android.games/temp/temp.apk")), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
            context.startActivity(intent);


        } catch (FileNotFoundException fnfe) {
            status = 1;
            Log.e("File", "FileNotFoundException! " + fnfe);
        }

        catch(Exception e)
        {
            Log.e("UpdateAPP", "Exception " + e);
        }
        return null;
    }

    public void onPostExecute(Void unused) {
        progressDialog.dismiss();
        if(status == 1)
            Toast.makeText(context,"Game Not Available",Toast.LENGTH_LONG).show();
    }
}

To delete downloaded file from SD card I've used BroadcastReceiver class

@Override
    public void onReceive(Context context, Intent intent) { 

        try
        {
            String packageName = intent.getData().toString() + getApplicationName(context, intent.getData().toString(), PackageManager.GET_UNINSTALLED_PACKAGES);

            if(intent.getAction().equals("android.intent.action.PACKAGE_ADDED")){
                File sdcard = Environment.getExternalStorageDirectory();
                File file = new File(sdcard,"Android/data/com.mycompany.android.games/temp/temp.apk");
                file.delete();
            }
        }catch(Exception e){Toast.makeText(context, "onReceive()", Toast.LENGTH_LONG).show();}
    }

Don't forget to include following permission in the AndroidManifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

In my website, I create two .aspx pages and placed it inside Android folder and .apk files inside Android/Games folder in Visual Studio
First page: marketplace.aspx.cs

public partial class marketplace : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            DirectoryInfo directory = new DirectoryInfo(Server.MapPath("~/Android/Games"));
            int counter = 0;
            foreach (FileInfo file in directory.GetFiles())
            {
                HyperLink link = new HyperLink();
                link.ID = "Link" + counter++;
                link.Text = file.Name;
                link.NavigateUrl = "gamedownload.aspx?name=" + file.Name;

                Page.Controls.Add(link);
                Page.Controls.Add(new LiteralControl("<br/>"));

            }
        }

        protected void Click(object sender, EventArgs e)
        {
            Response.Redirect("gamedownload.aspx");
        }
    }

Second Page: gamedownload.aspx.cs

public partial class gamedownload : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string fileName = Request.QueryString["name"].ToString();
            Response.ContentType = "application/octet-stream";
            Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
            Response.TransmitFile(Server.MapPath("~/Android/Games/" + fileName));
            Response.End();
        }
    }

I added following code in Web.config file

<system.webServer>
    <staticContent>
      <mimeMap fileExtension=".apk"
               mimeType="application/vnd.android.package-archive" />
    </staticContent>
  </system.webServer>

I hope this information will be help full for some people.

Sushil
  • 533
  • 2
  • 8
  • 28
0

Who is maintaining server for your apk because for this you have to do some server setting: set the MIME type of your folder on server containing this apk file as .apk and application/vnd.android.package-archive. Then it will automatically get installed on clicking the link similarly as that of any other app from google play.

Vikram Singh
  • 1,420
  • 14
  • 19
  • Hi! thank you for your response... I'm managing the server, as you told, I've setup the MIME setting, I added `.apk` as extension and `MIME` type as `application/vnd.android.package-archive` for apk folder. I'm trying on my local server, the `.apk` url is `http://192.168.0.4/Sush19/games/apk/myGame1.apk`. I've written code on onClick event as: `Intent promptInstall = new Intent(Intent.ACTION_VIEW).setData(Uri.parse("http://192.168.0.4/Sush19/games/apk/myGame1.apk")); startActivity(promptInstall);` it doesn't install the app, it downloads the app to sdcard then it prompt to install it... – Sushil Nov 19 '13 at 09:06
  • umm..yes, AFAIK, it will behave in this way only. the only difference is now you dont have to reach to or find your .apk file on sd card through file explorer or anything to install it. But by doing this Android will know what to do with this file as soon as it gets downloaded and asks you to install it. – Vikram Singh Nov 19 '13 at 09:31
  • but my question is different.. If you want to install any app from marketplace, it will not download the .apk file in your sdcard, instead it prompt you to install the app directly from the marketplace server... same way I wanna do.. whether it is possible do it? – Sushil Nov 19 '13 at 09:50
  • even if you install app from marketplace, it always download the .apk first and then install it. The only thing is it does not keep it on sdcard but in ../data folder which you don't have access until your phone is rooted. You can see this process in your notification area while installing, it always says downloading..and then installing.. – Vikram Singh Nov 19 '13 at 10:43
  • so if you dont want to keep .apk on sd card, you may have to workaround and programatically delete file after installation.. – Vikram Singh Nov 19 '13 at 10:46
  • hmmm... Thank you for the information.. I was not knowing this as I'm new to android development... will try something else.... Thank you... – Sushil Nov 19 '13 at 12:08