android - 从市场以外的网站以编程方式在 Android 设备上下载、安装和删除 .apk 文件

标签 android onclick apk


我开发了一些安卓游戏并创建了 .apk 文件..
我已将这些 .apk 文件放在我的网站上(比如:http://www.sush19.com/androidApp/apk/myGame1.apk) 当这个 url 从另一个应用程序 onClick() 事件访问时,是否可以直接安装这个游戏。

我不希望用户下载 .apk 到他们的 sdcard 然后手动安装,事实上游戏应该直接安装到设备。

我在另一个应用 onClick() 事件中尝试使用以下代码:

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

我知道上面的代码不正确..但是任何人都可以对此发表评论..

最佳答案

下面的代码,允许用户在 Android 设备上下载、安装和删除 .apk 文件。 我创建了一个 Android 应用程序 (Say App1),它可以在 SD 卡上下载其他 Android 应用程序。在App1中点击按钮,它会在后台从我自己的网站下载.apk文件,下载完成后会提示用户安装最近从App1下载的应用程序,安装完成后下载的.apk文件将被删除SD 卡。

在我的 App1 主要 Activity 中:我包含了按钮
在我的例子中,我从 App1 启动我的其他应用程序,如果设备上没有安装,我会从我的网站下载并安装它。
按钮点击事件方法

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");
            }
        }
    };

安装APK类

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();
    }
}

要从 SD 卡中删除下载的文件,我使用了 BroadcastReceiver 类

@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();}
    }

不要忘记在 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" />

在我的网站中,我创建了两个 .aspx 页面并将其放置在 Android 文件夹中,并将 .apk 文件放置在 Visual Studio 中的 Android/Games 文件夹中
第一页: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");
        }
    }

第二页: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();
        }
    }

我在 Web.config 文件中添加了以下代码

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

我希望这些信息能对某些人有所帮助。

关于android - 从市场以外的网站以编程方式在 Android 设备上下载、安装和删除 .apk 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20065040/

相关文章:

android - 带有按钮名称的 String.xml

为统一制作插件时,具有输入类型密码的 Android Native TextField 无法正常工作

javascript - 单击 AmCharts 的自定义标记时触发 Javascript 函数

java - 如何在同一个程序中使用onclick和onclicklistener?

android - 在Google Play商店中上传失败

android - Google Play 控制台不会减少应用程序下载大小

java - 字符串包含相同的字符但仍然不同

android - 如何以编程方式清除 React Native 应用程序中的 API 缓存

asp.net - 为什么 ASP.NET MVC a href onclick 会立即触发?

android - 如何自动将 APK 从 Jenkins 上传到 TestFairy