Android平台上下载Apk直接弹出安装Apk
//Java UpdateUtil.java
package com.cdx.unity3d;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.support.v4.content.FileProvider;
import java.io.File;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Handler;
import android.os.Message;
import com.unity3d.player.UnityPlayer;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class UpdateUtil {

    private Context mContext;
    private String apkUrl;
    private String savePath;
    private String saveFileName;
    private String downloadMsg;
    private int progress;
    private ProgressDialog downloadDialog;
    private Thread downLoadThread;
    private boolean interceptFlag = false;

    public UpdateUtil(Context context)
    {
        this.mContext = context;
    }
    /**
     * 更新下载apk
     */
    public static void downLoadApk(final String url, final String storge, Boolean showNotify) {

        final Activity activity = UnityPlayer.currentActivity;
        activity.runOnUiThread(new Runnable()
        {
            public void run()
            {
                UpdateUtil updater = new UpdateUtil((Context)activity);
                updater.Download(url, storge);
            }
        });
    }

    public void Download(String url, String storge)
    {
        this.apkUrl = url;
        this.savePath = storge;

        this.saveFileName =  storge;

        this.downloadDialog = new ProgressDialog(this.mContext);
        this.downloadDialog.setTitle("游戏更新");
        this.downloadDialog.setMessage("请稍后。。。");
        this.downloadDialog.setProgressStyle(1);
        this.downloadDialog.setCancelable(false);
        this.downloadDialog.setCanceledOnTouchOutside(false);

        this.downloadDialog.setMax(100);
        this.downloadDialog.show();

        downloadApk();
    }

    private void downloadApk()
    {
        this.downLoadThread = new Thread(this.mdownApkRunnable);
        this.downLoadThread.start();
    }

    private Runnable mdownApkRunnable = new Runnable()
    {
        public void run()
        {
            try
            {
                URL url = new URL(UpdateUtil.this.apkUrl);

                HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                conn.connect();
                int length = conn.getContentLength();
                InputStream is = conn.getInputStream();

                File file = new File(UpdateUtil.this.saveFileName);
                if (file.isFile()) {
                    file = new File(file.getParent());
                }
                if ((file.isDirectory()) && (!file.exists())) {
                    file.mkdir();
                }
                String apkFile = UpdateUtil.this.saveFileName;
                File ApkFile = new File(apkFile);
                FileOutputStream fos = new FileOutputStream(ApkFile);

                String fName = UpdateUtil.this.apkUrl.trim();
                fName = fName.substring(fName.lastIndexOf("/") + 1,fName.lastIndexOf("?"));


                UpdateUtil.this.downloadMsg = ("正在下载文件:" + fName);
                UpdateUtil.this.mHandler.sendEmptyMessage(0);

                int count = 0;
                byte[] buf = new byte[1024];
                do
                {
                    int numread = is.read(buf);
                    count += numread;
                    UpdateUtil.this.progress = ((int)((float)count / (float) length * 100.0F));
                    UpdateUtil.this.downloadMsg = ("正在下载文件:" + fName + "   " + count / 1024 + "kb/" + length / 1024 + "kb");

                    UpdateUtil.this.mHandler.sendEmptyMessage(1);
                    if (numread <= 0) {
                        break;
                    }
                    fos.write(buf, 0, numread);
                } while (!UpdateUtil.this.interceptFlag);
                fos.close();
                is.close();
                UpdateUtil.this.mHandler.sendEmptyMessage(2);
            }
            catch (MalformedURLException e)
            {
                e.printStackTrace();
                UpdateUtil.this.downloadMsg = ("下载失败,出现异常:" + e.getMessage());
                UpdateUtil.this.mHandler.sendEmptyMessage(3);
            }
            catch (IOException e)
            {
                e.printStackTrace();
                UpdateUtil.this.downloadMsg = ("下载失败,出现异常:" + e.getMessage());
                UpdateUtil.this.mHandler.sendEmptyMessage(3);
            }
        }
    };

    private Handler mHandler = new Handler()
    {
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case 0:
                    UpdateUtil.this.downloadDialog.setMessage(UpdateUtil.this.downloadMsg);
                    break;
                case 1:
                    UpdateUtil.this.downloadDialog.setMessage(UpdateUtil.this.downloadMsg);
                    UpdateUtil.this.downloadDialog.setProgress(UpdateUtil.this.progress);
                    break;
                case 2:
                    UpdateUtil.this.installApk();

                    UpdateUtil.this.downloadDialog.dismiss();

                    break;
                case 3:
                    UpdateUtil.this.downloadDialog.dismiss();

                    AlertDialog.Builder builder = new AlertDialog.Builder(UpdateUtil.this.mContext);
                    builder.setTitle("下载失败");
                    builder.setMessage("是否重试?");
                    builder.setPositiveButton("确定", new DialogInterface.OnClickListener()
                    {
                        public void onClick(DialogInterface dialog, int which)
                        {
                            dialog.dismiss();
                            UpdateUtil.this.Download(UpdateUtil.this.apkUrl, UpdateUtil.this.savePath);
                        }
                    });
                    builder.setNegativeButton("取消", new DialogInterface.OnClickListener()
                    {
                        public void onClick(DialogInterface dialog, int which)
                        {
                            dialog.dismiss();

                            Activity act = (Activity)UpdateUtil.this.mContext;
                            act.finish();
                        }
                    });
                    builder.create().show();

                    break;
            }
        }
    };

    /**
     * 安装apk
     */
    private void installApk() {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Uri data = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//判断版本大于等于7.0
            // 生成文件的uri,,
            // 注意 下面参数com.xxx.xxx.fileprovider为apk的包名加上.fileprovider,
            data = FileProvider.getUriForFile(this.mContext, "com.xxx.xxx.fileprovider", new File(this.saveFileName));
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);// 给目标应用一个临时授权
        } else {
            data = Uri.fromFile(new File(this.saveFileName));
        }
        intent.setDataAndType(data, "application/vnd.android.package-archive");


        this.mContext.startActivity(intent);
    }
}


修改Plugins/Android/AndroidManifest.xml文件,添加权限和provider

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

<provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="com.zfzx.cyzx.fileprovider"
      android:exported="false"
      android:grantUriPermissions="true">
  <meta-data
      android:name="android.support.FILE_PROVIDER_PATHS"
      android:resource="@xml/filepaths"/>
</provider>


在Plugins/Android/res/xml下添加filepaths.xml文件,注意替换包名!

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
  <!--<external-path name="external_files" path="."/>-->
  <external-path path="Android/data/包名!" name="files_root" />
  <external-path path="." name="external_storage_root" />
</paths>


这样把下载的apk的文件保存在Application.persistentDataPath目录下,也就是在downloadApk方法中传入的storge参数为Application.persistentDataPath + "/包.apk"就可以了。如果打包不了或报错了,将android-support-v4.jar放到Plugins/Android目录下。


首页 我的博客
粤ICP备17103704号