android 版本更新和下载安装 适配android 7.0

版权声明:转载时请标明出处。https://blog.csdn.net/mhhyoucom https://blog.csdn.net/mhhyoucom/article/details/81195786

在android 7.0之前版本更新其实相当简单,只需要使用系统下载器就能够完成下载之后安装,但是在7.0之后android升级安全机制,下载安装受到一些限制。这里我分装成了几个工具方便开发者使用:

添加权限

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

接下来是最重要的工具类:

public class CXVersionCheckUtils {

    private static File saveFile;
    private Activity activity;
    private static long downloadId = 0;

    public CXVersionCheckUtils(Activity activity) {
        this.activity = activity;
        initFile();
    }

    private void initFile() {
        if (saveFile==null)
            saveFile=new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "filiday.apk");
    }

    public void start(String url,String t, String d){
        if (downloadId!=0) {
            clearCurrentTask(downloadId);
        }
        downloadId=download(url,t,d);
    }

    public long download(String url, String title, String desc) {
        Uri uri = Uri.parse(url);
        DownloadManager.Request req = new DownloadManager.Request(uri);
        //设置WIFI下进行更新
        req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
        //下载中和下载完后都显示通知栏
        req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        //使用系统默认的下载路径 此处为应用内 /android/data/packages ,所以兼容7.0
//        req.setDestinationInExternalFilesDir(activity, Environment.DIRECTORY_DOWNLOADS, title);
        if (saveFile.exists()) {
            saveFile.delete();
        }
        req.setDestinationUri(Uri.fromFile(saveFile));
        //通知栏标题
        req.setTitle(title);
        //通知栏描述信息
        req.setDescription(desc);
        //设置类型为.apk
        req.setMimeType("application/vnd.android.package-archive");
        //获取下载任务ID
        DownloadManager dm = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE);
        return dm.enqueue(req);
    }

    public void clearCurrentTask(long downloadId) {
        DownloadManager dm = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE);
        try {
            dm.remove(downloadId);
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }

    }

    public static void installApk(Context context) {
        downloadId=0;

        Intent intent = new Intent(Intent.ACTION_VIEW);
        try {
            String[] command = {"chmod", "777", saveFile.getAbsolutePath()};
            ProcessBuilder builder = new ProcessBuilder(command);
            builder.start();
        } catch (Exception ignored) {
            ignored.printStackTrace();
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(context, "com.chengxing.comchenxingnetapp.fileprovider", saveFile);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(saveFile), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }

        context.startActivity(intent);
    }


}

创建广播接受者:CXDownloadReceiver

public class CXDownloadReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
            long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
            CXVersionCheckUtils.installApk(context);//开始安装
        } else if (intent.getAction().equals(DownloadManager.ACTION_NOTIFICATION_CLICKED)) {
            // DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
            //获取所有下载任务Ids组
            //long[] ids = intent.getLongArrayExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS);
            ////点击通知栏取消所有下载
            //manager.remove(ids);
            //Toast.makeText(context, "下载任务已取消", Toast.LENGTH_SHORT).show();
            //处理 如果还未完成下载,用户点击Notification ,跳转到下载中心
            Intent viewDownloadIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
            viewDownloadIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(viewDownloadIntent);
        }

    }
}

配置广播:

        <!--下载安装接收器-->
        <receiver android:name=".CXDownloadReceiver">
            <intent-filter>
                <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
                <action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED" />
            </intent-filter>
        </receiver>

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

@xml/file_paths是允许安装apk的目录:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
</paths>

这里使用允许sd卡根目录的apk 允许安装。android.support.v4.content.FileProvider 是android7.0 需要配置一个提供者。

使用方法:

versionCheckUtils.start(updateBean.updateUrl,"filiday.apk", "filiday new version");

第一个参数是下载地址, 第二个参数是下载通知标题,第三个通知是通知描述。

猜你喜欢

转载自blog.csdn.net/mhhyoucom/article/details/81195786