• Android 自己实现更新下载自动安装


    1、一些公司开发完一款App之后可能并不会去上架App商店,但事后期也需要定时进行维护更新,所以会选择把打包好的apk 发布到自己的服务器,然后在数据库建一个版本号的表,然后剩下的就交给你android开发了,android自己要实现版本检测更新,由于android自带的DownloadManager 就可以实现下载功能,用起来就会很简单了,不用再写很多下载等相关代码了,不过在下载完有的是在通知栏通知,然后用户自己手动点击进行安装,有的是下载完自己就进入安装状态了,用户只需要确认安装就可以了,但是由于一些高版本的系统和低版本的自动安装不同,这里就简单介绍一下,然大家能很快的处理这个事情,我就是在这个自动安装这块弄了有好几天不知道怎么回事,先总结一下:

    2、这里就从开始下载开始,那些版本号的请求就不提了,,

        这里我们可以先写一个工具类Util,然后顶一个静态方法downLoadApk();

       eg:

    /**
    * 更新下载apk
    * @param context 上下文对象
    * @param title 程序的名字
    * @param url 下载的url地址
    *
    */

    public static long downLoadApk(Context context,String title,String url){

    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
    request.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS,"ausee.apk");
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    // 设置 Notification 信息
    request.setTitle(title);
    request.setDescription("下载完成后请点击打开");
    request.setVisibleInDownloadsUi(true);
    request.allowScanningByMediaScanner();
    request.setMimeType("application/vnd.android.package-archive");

    // 实例化DownloadManager 对象
    DownloadManager downloadManager = (DownloadManager) MyApp.getContext().getSystemService(Context.DOWNLOAD_SERVICE);
    final long refrence = downloadManager.enqueue(request);

    return refrence;
    }
    上面的那个静态方法就可以实现下载了,把url传过去就OK了;下面就来处理剩下的,大家注意上面的方法会返回一个long类型的值,
     大家在activity调用这个方法的时候,拿到这个返回值,然后在activity里面建一个广播接收器,因为上面的返回值是DownloadManager 下载完后返回的一个下载id,自带的,每一个下载任务都会返回一个唯一的id,并且会发一条广播,这里我在activity里面定义一个方法:listener(id),并建一个广播接受器; 如下

    private void listener(final long Id) {
    // 注册广播监听系统的下载完成事件。
    IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
    broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
    DownloadManager manager = (DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);
      // 这里是通过下面这个方法获取下载的id,
    long ID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
    // 这里把传递的id和广播中获取的id进行对比是不是我们下载apk的那个id,如果是的话,就开始获取这个下载的路径
    if (ID == Id) {

    DownloadManager.Query query = new DownloadManager.Query();
    query.setFilterById(Id);

    Cursor cursor = manager.query(query);
    if (cursor.moveToFirst()){
    // 获取文件下载路径
    String fileName = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));

    // 如果文件名不为空,说明文件已存在,则进行自动安装apk
    if (fileName != null){

    openAPK(fileName);

    }
    }
    cursor.close();
    }
    }
    };
    registerReceiver(broadcastReceiver, intentFilter);
    }
    下面是上面的自动打开apk的方法:
    /**
    * 安装apk
    * @param fileSavePath
    */
    private void openAPK(String fileSavePath){
    File file=new File(Uri.parse(fileSavePath).getPath());
    String filePath = file.getAbsolutePath();
    Intent intent = new Intent(Intent.ACTION_VIEW);
    Uri data = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//判断版本大于等于7.0
    // 生成文件的uri,,
      // 注意 下面参数com.ausee.fileprovider 为apk的包名加上.fileprovider,
    data = FileProvider.getUriForFile(LoginActivity.this, "com.ausee.fileprovider", new File(filePath));
    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);// 给目标应用一个临时授权
    } else {
    data = Uri.fromFile(file);
    }

    intent.setDataAndType(data, "application/vnd.android.package-archive");
    startActivity(intent);
    }
    上面基本就可以了,但是上面的那个参数com.ausee.fileprovider,这个需要注意,进行下面的配置
    先在项目res文件下新建一个文件夹名字为 xml ;后新建一个xml的文件:file_paths.xml;
    xml中内容为:
    <?xml version="1.0" encoding="utf-8"?>
    <paths>
    <external-path name="name" path="."/>
    </paths>
    这里写好之后,下面在manifest里面配置一个provider标签:这么写就可以:

    <provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.ausee.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/file_paths" />
    </provider>
    仔细看上面的 android:authorities="com.ausee.fileprovider" (com.ausee为你自己的包名),这个内容和前面的那个参数一样的吧?就是因为这里,这里的内容也是那样填写的,包名加上一个fileprovider 就可以了,然后在meta-data 里面把刚开配置的xml文件配置进来就可以!

    需要加个 android.intent.category.DEFAULT

    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>

    好了,到这里就完工了,快去试试吧!


  • 相关阅读:
    爸爸妈妈儿子女儿吃水果问题以及五个哲学家吃饭问题
    同步与互斥中的购票和退票问题的PV操作与实现
    创建react&ts&antd项目
    在POM配置Maven plugin提示错误“Plugin execution not covered by lifecycle configuration”的解决方案
    aws rds 储存空间占用 异常排查 存储空间占满
    Linux下clang、gcc、intel编译器最新版本安装笔记
    extern "C"与extern "C" { … }的差别
    gcc预处理指令之#pragma once
    指向类的成员变量的指针
    Java程序中使用SQLite总结
  • 原文地址:https://www.cnblogs.com/Alex80/p/11611798.html
Copyright © 2020-2023  润新知