Android应用中apk下载更新,适用于android 9及以下安卓版本。

直接上代码:

一、在主配置文件中写权限。

                                                                   //在此加入                  //在res文件夹下新建package命名为xml,新建xml文件命名为files_paths            

二、创建 files_paths.xml

<?xml version="1.0" encoding="utf-8"?>                

三、创建 UpdateVersionController.java

        public class UpdateVersionController {    private Button cancelBtn;    private Context context;    private int info;    private int info3;    private int versionCode;//当前版本号    private Dialog dialog; //提示用户更新的dialog    private ProgressDialog pd;  //下载进度条    public static UpdateVersionController getInstance(Context context) {        return new UpdateVersionController(context);    }    public UpdateVersionController(Context context) {        this.context = context;    } /* * 记得运行该方法 */    public void forceCheckUpdateInfo(){        //获取版本号,这个版本号为未更新的版本号        versionCode = getVerCode(context);         //获取app新版版本信息,添加网络请求        new Thread(new Runnable() {            @Override            public void run() {                /*                 *用的Volley框架,Volley可以自己搜索下载jar包,下面是使用Volley获取GET请求的方法                 */                RequestQueue mQueue= Volley.newRequestQueue(context);                JsonObjectRequest mreq=new JsonObjectRequest(Request.Method.GET,“获取版本号的网址”,new Response.Listener() {                    @Override                    public void onResponse(JSONObject jsonObject) {                        String  tt=jsonObject.toString();      //把获取的jsonObject转为String类型                        Gson gson=new Gson();                  //这里我用的是Gson解析,可以自己搜索gson的jar包下载使用                        AppVersion nt=gson.fromJson(tt, AppVersion.class);      //这里的AppVersion是网络获取版本号的网址中json数据的实体类,tt是网络获取的数据,用该方法实现json解析                        //关于实体类:从服务器网址获取的json数据,通过搜索json自动生成实体类下载复制。并 implement Serializable ,添加构造方法                        info=nt.getVNumber();                   //通过nt获取实体类里的版本号,为String类型                        info3=nt.getIsForce();                 //通过nt获取是否强制更新,为String类型                        Log.e("版本",""+versionCode);//建议输出一下版本号,进行对比                        //更新app版本号比对,info新版本号和当前的版本号versionCode做对比,如果新版本号大于本版本就运行更新方法showUpdataDialog()                        if ( info > versionCode) {                            showUpdataDialog();                        } else {                        }                    }                }, new Response.ErrorListener() {                    @Override                    public void onErrorResponse(VolleyError volleyError) {                        Log.e("*****", String.valueOf(volleyError));                    }                });                mQueue.add(mreq);            }        }).start();    }    /**     * 弹出对话框提示用户更新     */    protected void showUpdataDialog() {        dialog = new Dialog(context, android.R.style.Theme_Dialog);        dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);        dialog.setContentView(R.layout.activity_updater);        dialog.setCanceledOnTouchOutside(false);        dialog.setCancelable(false);        ((TextView) dialog.findViewById(R.id.content)).setText("是否进行更新?");        cancelBtn = (Button) dialog.findViewById(R.id.cancel);        cancelBtn.setVisibility("0".equals(info3) ? View.GONE : View.VISIBLE);        // 取消更新        cancelBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                dialog.dismiss();            }        });        // 确认更新        dialog.findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                dialog.dismiss();                downLoadApk();            }        });        dialog.show();    }    /**     * 步骤三:下载文件     */    private void downLoadApk() {        // 进度条对话框        pd = new ProgressDialog(context);        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);        pd.setMessage("下载中...");        pd.setCanceledOnTouchOutside(false);        pd.setCancelable(false);        // 监听返回键--防止下载的时候点击返回        pd.setOnKeyListener(new OnKeyListener() {            @Override            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {                if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {                    Toast.makeText(context, "正在下载请稍后", Toast.LENGTH_SHORT).show();                    return true;                } else {                    return false;                }            }        });        // Sdcard不可用        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {            Toast.makeText(context, "SD卡不可用", Toast.LENGTH_SHORT).show();        } else {            pd.show();            //下载的子线程            new Thread() {                @Override                public void run() {                    try {                        // 在子线程中下载APK文件                        File file = getFileFromServer(“下载apk的网址 ”, pd);                        sleep(1000);                        // 安装APK文件                        OpenFileUtil.openFileByPath(context,file.toString());                        pd.dismiss(); // 结束掉进度条对话框                    } catch (Exception e) {                        Toast.makeText(context, "文件下载失败了", Toast.LENGTH_SHORT).show();                        pd.dismiss();                        e.printStackTrace();                    }                }            }.start();        }    }    /**     * 从服务器下载apk     */    public File getFileFromServer(String path, ProgressDialog pd) throws Exception {        // 如果相等的话表示当前的sdcard挂载在手机上并且是可用的        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {            URL url = new URL(path);            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            conn.setConnectTimeout(5000);            // 获取到文件的大小            pd.setMax(conn.getContentLength() / 1024);            InputStream is = conn.getInputStream();            String p = PathUtils.path;            File file = new File(p+ "/update/aaaa.apk");          Log.e("File路径",""+file);            //判断文件夹是否被创建            boolean mkdirs;            if (!file.getParentFile().exists()) {                 mkdirs = file.getParentFile().mkdirs();            }            FileOutputStream fos = new FileOutputStream(file);            BufferedInputStream bis = new BufferedInputStream(is);            byte[] buffer = new byte[1024];            int len;            int total = 0;            while ((len = bis.read(buffer)) != -1) {                fos.write(buffer, 0, len);                total += len;                // 获取当前下载量                pd.setProgress(total / 1024);            }            fos.close();            bis.close();            is.close();            return file;        } else {            return null;        }    }   /**   * 获取版本号    */    public static int getVerCode(Context context) {        int verCode = -1;        try {            // 获取packagemanager的实例            PackageManager packageManager = context.getPackageManager();            // getPackageName()是你当前类的包名,0代表是获取版本信息            PackageInfo packInfo = packageManager.getPackageInfo(                    context.getPackageName(), 0);            verCode = packInfo.versionCode;        } catch (Exception e) {            e.printStackTrace();        }        return verCode;    }}

三、创建OpenFileUtil.java 打开任意文件也可以使用该类

public class OpenFileUtil {    private static final String[][] MATCH_ARRAY={            //{后缀名,    文件类型}            {".3gp",    "video/3gpp"},            {".apk",    "application/vnd.android.package-archive"},            {".asf",    "video/x-ms-asf"},            {".avi",    "video/x-msvideo"},            {".bin",    "application/octet-stream"},            {".bmp",      "image/bmp"},            {".c",        "text/plain"},            {".class",    "application/octet-stream"},            {".conf",    "text/plain"},            {".cpp",    "text/plain"},            {".doc",    "application/msword"},            {".docx",    "application/msword"},            {".xls",    "application/msword"},            {".xlsx",    "application/msword"},            {".exe",    "application/octet-stream"},            {".gif",    "image/gif"},            {".gtar",    "application/x-gtar"},            {".gz",        "application/x-gzip"},            {".h",        "text/plain"},            {".htm",    "text/html"},            {".html",    "text/html"},            {".jar",    "application/java-archive"},            {".java",    "text/plain"},            {".jpeg",    "image/jpeg"},            {".jpg",    "image/jpeg"},            {".js",        "application/x-javascript"},            {".log",    "text/plain"},            {".m3u",    "audio/x-mpegurl"},            {".m4a",    "audio/mp4a-latm"},            {".m4b",    "audio/mp4a-latm"},            {".m4p",    "audio/mp4a-latm"},            {".m4u",    "video/vnd.mpegurl"},            {".m4v",    "video/x-m4v"},            {".mov",    "video/quicktime"},            {".mp2",    "audio/x-mpeg"},            {".mp3",    "audio/x-mpeg"},            {".mp4",    "video/mp4"},            {".mpc",    "application/vnd.mpohun.certificate"},            {".mpe",    "video/mpeg"},            {".mpeg",    "video/mpeg"},            {".mpg",    "video/mpeg"},            {".mpg4",    "video/mp4"},            {".mpga",    "audio/mpeg"},            {".msg",    "application/vnd.ms-outlook"},            {".ogg",    "audio/ogg"},            {".pdf",    "application/pdf"},            {".png",    "image/png"},            {".pps",    "application/vnd.ms-powerpoint"},            {".ppt",    "application/vnd.ms-powerpoint"},            {".prop",    "text/plain"},            {".rar",    "application/x-rar-compressed"},            {".rc",        "text/plain"},            {".rmvb",    "audio/x-pn-realaudio"},            {".rtf",    "application/rtf"},            {".sh",        "text/plain"},            {".tar",    "application/x-tar"},            {".tgz",    "application/x-compressed"},            {".txt",    "text/plain"},            {".wav",    "audio/x-wav"},            {".wma",    "audio/x-ms-wma"},            {".wmv",    "audio/x-ms-wmv"},            {".wps",    "application/vnd.ms-works"},            {".xml",    "text/plain"},            {".z",        "application/x-compress"},            {".zip",    "application/zip"},            {"",        "*/*"}    };    /**     * 根据路径打开文件     * @param context 上下文     * @param path 文件路径     */    public static void openFileByPath(Context context, String path) {        if(context==null||path==null)            return;        Intent intent = new Intent();        //设置intent的Action属性        intent.setAction(Intent.ACTION_VIEW);        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        intent.addCategory(Intent.CATEGORY_DEFAULT);        //文件的类型        String type = "";        for(int i =0;i < MATCH_ARRAY.length;i++){            //判断文件的格式            if(path.contains(MATCH_ARRAY[i][0])){                type = MATCH_ARRAY[i][1];                break;            }        }        try {            File out = new File(path);            Uri fileURI;            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {                // 由于7.0以后文件访问权限,可以通过定义xml在androidmanifest中申请,也可以直接跳过权限                // 通过定义xml在androidmanifest中申请//                fileURI = FileProvider.getUriForFile(context,//                        "com.lonelypluto.zyw_test.provider",//                        out);                // 直接跳过权限                StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();                StrictMode.setVmPolicy(builder.build());                fileURI = Uri.fromFile(out);            }else{                fileURI = Uri.fromFile(out);            }            //设置intent的data和Type属性            intent.setDataAndType(fileURI, type);            //跳转            if (context.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {                context.startActivity(intent);            } else {                Toast.makeText(context, "没有找到对应的程序", Toast.LENGTH_SHORT).show();            }        } catch (Exception e) { //当系统没有携带文件打开软件,提示            Toast.makeText(context, "无法打开该格式文件", Toast.LENGTH_SHORT).show();            e.printStackTrace();        }    }}

三、PathUtils .java

public class PathUtils {    public static String path = null;}

四、程序入口MainActivity.java

 private UpdateVersionController controller=new UpdateVersionController(this);        @Override        protected void onCreate(Bundle savedInstanceState) {              super.onCreate(savedInstanceState);              setContentView(R.layout.activity_main);                            PathUtils.path = getExternalFilesDir(null).toString();              controller.forceCheckUpdateInfo();//运行该方法        if (Build.VERSION.SDK_INT>=23&&checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);            requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO},1);            requestPermissions(new String[]{Manifest.permission.INTERNET},1);            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);            requestPermissions(new String[]{Manifest.permission.ACCESS_NETWORK_STATE},1);            requestPermissions(new String[]{Manifest.permission.ACCESS_WIFI_STATE},1);            requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE},1);            requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},1);            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},1);            requestPermissions(new String[]{Manifest.permission.CAMERA},1);            requestPermissions(new String[]{Manifest.permission.GET_TASKS},1);            requestPermissions(new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES},1);            requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},1);        }        }

完成了。

更多相关文章

  1. 【Android】1.6版本所有权限
  2. android+spring boot 选择,上传,下载文件
  3. Android 危险权限与所有权限大全
  4. Eclipse下Android工程无法自动产生R文件解决
  5. [置顶] Android中资源文件的详解和android中的单位介绍
  6. android(drawable文件夹)图片适配
  7. Android资源文件使用经验

随机推荐

  1. 如何实现Android重启应用程序代码 ?
  2. Android之类似于黑名单的短信拦截
  3. swig android的使用
  4. android 复制字符串到剪贴板
  5. android中EditText只允许输入汉字(过滤汉
  6. android反射方式访问内部类成员
  7. Delphi XE5 android 捕获几个事件
  8. Android源码编译全过程
  9. android之渐变色背景
  10. android hardware 简述(Android系统源码情