Android 版本更新(适配7.0 xml配置)

版本更新一般分两种情况:

  1. 需要更新时跳转到应用市场或者跳转到浏览器处理
  2. 另一种情况则是在App内进行更新

第一种没什么好说的,本文主要是实现应用内进行更新

App内部更新分以下几个步骤:

  1. 检测App版本
  2. 下载Apk
  3. 安装已下载完成的Apk

下面贴上实例:

1. 检测App版本

/**
 * 登录时查询是否有新版本应用
 */
public void queryVersion() {
    if (!Const.IS_CHECK_UPDATE) return; // 判断是否进行请求更新 (场景:进入App自动检测更新)

    HttpUtil.post(mContext, Const.URL_UPDATE, new TextResponseHandler() {
        @Override
        public void onSuccess(String result) {
        
            // 解析服务器返回的版本信息
            JSONObject jsonObject = JSON.parseObject(result);
            if (Const.JSON_SUCCESS.equals(jsonObject.getString("success")))
            {
                String strResult = jsonObject.getString("isupdate");
                if (TextUtils.isEmpty(strResult)) return;
                UpdateVersion update = JSON.parseObject(strResult, UpdateVersion.class);
                String edition = update.getEdition();    //    服务器返回版本信息
                String versionName = AppUtil.getVersionName(mContext);    //    当前应用版本号
                // 比较两者 不一致提示更新
                if (!versionName.equals(edition))
                {
                    // 显示更新提示
                    showNoticeDialog(update, versionName);
                }
            }
        }

        @Override
        public void onFailure(String message) // 视业务而定
        { 
            ...
        }
    });
}

2.有新版本时 提示更新

/**
 * 显示软件更新对话框
 *
 * @param update      更新介绍
 * @param versionName 当前版本名
 */
private void showNoticeDialog(final UpdateVersion update, String versionName) 
{
    // 构造对话框
    MaterialDialog.Builder builder = new MaterialDialog.Builder(mContext);
    builder.title("更新提示");
    if ("1".equals(update.getCode()))    //    强制更新
        builder.content("您当前使用版本会对您的使用带来不便,请您更新!");
    else
        builder.content("当前版本:" + versionName + "\r\n新版本:" + update.getEdition());    //    非重要更新

    builder.positiveText("确定");
    builder.negativeText("取消");
    //点击事件添加 方式1
    builder.onAny(new MaterialDialog.SingleButtonCallback() 
    {
        @Override
        public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which)         
        {
            if (which == DialogAction.POSITIVE) 
            {
                dialog.dismiss();
                showDownloadProgress(update);    // 显示更新进度 同时进行更新
            } else if (which == DialogAction.NEGATIVE) 
            {
                if ("2".equals(update.getCode()) || "3".equals(update.getCode()))
                {
                    dialog.dismiss();
                }else // 强制更新    如果不进行更新则无法使用当前应用
                {
                    dialog.dismiss();
                    mContext.finish();
                    System.exit(0);
                }
            }
        }
    });
    MaterialDialog materialDialog = builder.build();
    materialDialog.setCancelable(false);
    materialDialog.show();
}

3.显示下载进度

/**
 * 显示软件下载提示框
 *
 * @param update 后台返回更新的信息
 */
private void showDownloadProgress(UpdateVersion update) {
    String url = update.getUrl();
    apkName = url.substring(url.lastIndexOf("/") + 1, url.length());
    String apkUrl = Const.URL_HOSTS + url;
    
    // 构造软件下载对话框
    if (materialDialog == null) 
    {
        materialDialog = new MaterialDialog.Builder(mContext)
                .title("版本升级")
                .content("正在下载安装包,请稍候")
                .progress(false, 100, false)
                .cancelable(false)
                .show();
    }
    downloadThread(apkUrl);    // 下载Apk
}

4.下载Apk

/**
 * 使用DownloadManager进行下载
 */
private void downloadThread(String apkUrl) 
{
    downloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(apkUrl));
    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkName);
    //设置显示在文件下载Notification(通知栏)中显示的文字。6.0的手机Description不显示
    request.setTitle(mContext.getString(R.string.app_name));
    request.setDescription("新版本给您带来更优质的体验!");
    request.setMimeType("application/vnd.android.package-archive");
    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
    request.allowScanningByMediaScanner();
    request.setVisibleInDownloadsUi(true);

    lastDownloadId = downloadManager.enqueue(request);
    downloadObserver = new DownloadChangeObserver(null);
    mContext.getContentResolver().registerContentObserver(CONTENT_URI, true, downloadObserver);
}

5.监听下载进度

class DownloadChangeObserver extends ContentObserver {

    DownloadChangeObserver(Handler handler) 
    {
        super(handler);
    }

    @Override
    public void onChange(boolean selfChange) 
    {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(lastDownloadId);
        DownloadManager dManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        Cursor cursor = null;
        try 
        {
            cursor = dManager.query(query);
            if (cursor != null && cursor.moveToFirst())
            {
                final int totalColumn = cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
                final int currentColumn = cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
                int totalSize = cursor.getInt(totalColumn);
                int currentSize = cursor.getInt(currentColumn);
                float percent = (float) currentSize / (float) totalSize;
                int progress = Math.round(percent * 100);
                materialDialog.setProgress(progress);
                if (progress == 100)
                {
                    materialDialog.dismiss();
                    installAPK();
                }
            }
        } finally 
        {
            // 一定不要忘记关闭游标!!!
            if (cursor != null) 
            {
                cursor.close();
            }
        }
    }

}

6.安装新版Apk

private void installAPK() {
    File apkFile =new File
    (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), apkName);

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
    {
        Uri apkUri = FileProvider.getUriForFile(mContext, "com.你的自定义路径.update.fileprovider", apkFile);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
    } else
    {
        intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
    }
    mContext.startActivity(intent);
}

7.释放资源

/**
 * 释放当前资源
 */
public void onDestroy()
{

    if (Const.IS_CHECK_UPDATE && downloadManager != null) 
    {
        downloadManager = null;
        mContext.getContentResolver().unregisterContentObserver(downloadObserver);
    }
}

结束了?No No No ,由于Android系统的不断完善,尤其是权限方面,所以在7.0以上的系统需要在manifest中注册provider

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.你的路径.update.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
<!-- file_paths -->
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <paths>
        <external-path
            name="download"
            path=""/>
    </paths>
</resources>
​

ok,至此自动App更新功能完成

功能全部代码:

public class UpdateManager {
    private DownloadChangeObserver downloadObserver;
    private long lastDownloadId = 0;
    //"content://downloads/my_downloads"必须这样写不可更改
    private final Uri CONTENT_URI = Uri.parse("content://downloads/my_downloads");
    private AlertDialog materialDialog;

    private Activity mActivity;
    private String apkName;
    private DownloadManager downloadManager;


    public UpdateManager(Activity activity) 
    {
        this.mActivity = activity;
    }


    /**
     * 登录时查询是否有新版本应用
     */
    public void queryVersion() {
        if (!Constants.IS_CHECK_UPDATE) return; 

        HttpUtil.get(mActivity, Constants.URL_UPDATE, new TextResponseHandler() {
            @Override
            public void onSuccess(String result) 
            {
                JSONObject jsonObject = JSON.parseObject(result);
                if (Constants.JSON_SUCCESS.equals(jsonObject.getString("success"))) 
                {
                    String strResult = jsonObject.getString("isupdate");
                    if (TextUtils.isEmpty(strResult)) return;
                    UpdateVersion update = JSON.parseObject(strResult, UpdateVersion.class);
                    String edition = update.getEdition();
                    String versionName = AppUtil.getVersionName(mContext);
                    String code = update.getCode();
                    if (!versionName.equals(edition))
                    {
                        showNoticeDialog(update, versionName);
                    }
                }
            }

            @Override
            public void onFailure(String message) 
            { 
                ...
            }
        });

    }

    /**
     * 显示软件更新对话框
     *
     * @param update      更新介绍
     * @param versionName 当前版本名
     */
    private void showNoticeDialog(final UpdateVersion update, String versionName) 
    {
        // 构造对话框
        MaterialDialog.Builder builder = new MaterialDialog.Builder(mContext);
        builder.title("系统提示");
        if ("1".equals(update.getCode()))    // 强制更新
            builder.content("您当前使用版本会对您的使用带来不便,请您更新!");
        else    // 正常更新
            builder.content("当前版本:" + versionName + "\r\n新版本:" + update.getEdition());

        builder.positiveText("确定");
        builder.negativeText("取消");

        builder.onAny(new MaterialDialog.SingleButtonCallback() 
        {
            @Override
            public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) 
            {
                if (which == DialogAction.POSITIVE)
                {
                    dialog.dismiss();
                    showDownloadProgress(update);
                } else if (which == DialogAction.NEGATIVE) 
                {
                    if ("2".equals(update.getCode()) || "3".equals(update.getCode()))
                    {
                        dialog.dismiss();
                    }else     // 强制更新
                    {
                        dialog.dismiss();
                        mContext.finish();
                        System.exit(0);
                    }
                }
            }
        });
        MaterialDialog materialDialog = builder.build();
        materialDialog.setCancelable(false);
        materialDialog.show();
    }

    /**
     * 显示软件下载对话框
     *
     * @param update 返回更新信息
     */
  private void showDownloadProgress(UpdateVersion update) 
  {
        String url = update.getUrl();
        apkName = url.substring(url.lastIndexOf("/") + 1, url.length());
        String apkUrl = Constants.URL_HOSTS + url;
        // 构造软件下载对话框
        if (materialDialog == null) 
        {
            materialDialog = new MaterialDialog.Builder(mActivity)
                    .title("版本升级")
                    .content("正在下载安装包,请稍候")
                    .progress(false, 100, false)
                    .cancelable(false)
                    .show();
        }
         
        // 屏幕常亮
        mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        downloadThread(apkUrl);    // 下载
    }

    private void downloadThread(String apkUrl)
    {
        String directoryDownloads = Environment.DIRECTORY_DOWNLOADS;
        String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
//        ToolUtil.deleteFile(path + "/" + apkName);    // 删除下载的安装包
        downloadManager = (DownloadManager) mActivity.getSystemService(Context.DOWNLOAD_SERVICE);
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(apkUrl));
        request.setDestinationInExternalPublicDir(directoryDownloads, apkName);
        //设置显示在文件下载Notification(通知栏)中显示的文字。6.0的手机Description不显示
        request.setTitle(mActivity.getString(R.string.app_name));
        request.setDescription("新版本给您带来更优质的体验!");
        request.setMimeType("application/vnd.android.package-archive");
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
        request.allowScanningByMediaScanner();
        request.setVisibleInDownloadsUi(true);

        lastDownloadId = downloadManager.enqueue(request);
        downloadObserver = new DownloadChangeObserver(null);
        mActivity.getContentResolver().registerContentObserver(CONTENT_URI, true, downloadObserver);
    }

    //用于显示下载进度
    class DownloadChangeObserver extends ContentObserver {

        DownloadChangeObserver(Handler handler) 
        {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) 
        {
            DownloadManager.Query query = new DownloadManager.Query();
            query.setFilterById(lastDownloadId);
            DownloadManager dManager = (DownloadManager) mActivity.getSystemService(Context.DOWNLOAD_SERVICE);
            Cursor cursor = null;
            try
            {
                assert dManager != null;
                cursor = dManager.query(query);
                if (cursor != null && cursor.moveToFirst()) 
                {
                    //下载的文件到本地的目录
                    String addressDir = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                    final int totalColumn = cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
                    final int currentColumn = cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
                    int totalSize = cursor.getInt(totalColumn);
                    int currentSize = cursor.getInt(currentColumn);
                    float percent = (float) currentSize / (float) totalSize;
                    int progress = Math.round(percent * 100);
                    materialDialog.setProgress(progress);
                    if (progress == 100)
                    {
                        materialDialog.dismiss();
                        installAPK();
                    }
                }
            } finally 
            {
                if (cursor != null)
                {
                    cursor.close();
                }
            }
        }

    }
/*
    // 使用浏览器下载
    private void openBrowserDown(UpdateVersion update) 
    {
        String apkUrl = Constants.URL_HOSTS + update.getUrl();
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.addCategory(Intent.CATEGORY_BROWSABLE);
        intent.setData(Uri.parse(apkUrl));
        mActivity.startActivity(intent);
        SystemClock.sleep(1500L);
        System.exit(0);
    }
*/
    private void installAPK() 
    {
        File apkFile =
                new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), apkName);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 
        {
            Uri apkUri = FileProvider.getUriForFile(mActivity, "com.wzy.buytickets.update.fileprovider", apkFile);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else 
        {
            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
        }
        mActivity.startActivity(intent);
    }


    /**
     * 释放当前资源
     */
    public void onDestroy() 
    {
        if (!Constants.IS_CHECK_UPDATE && downloadManager == null) return;

        downloadManager = null;
        mActivity.getContentResolver().unregisterContentObserver(downloadObserver);
    }

}

使用:

private UpdateManager updateManager;    //  更新类

if (updateManager == null)   // 初始化
{
     updateManager = new UpdateManager(this);
}

updateManager.queryVersion();    // 调用(直接调用或button点击调用)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android是一个开源的移动操作系统,由Google开发。它的各个版本都有不同的特性和适配要求。下面是Android各个版本适配情况: 1. Android 1.0:这是Android的首个正式版本,发布于2008年。它主要适配了当时的早期智能手机。 2. Android 1.5 Cupcake:这个版本引入了许多新特性,包括虚拟键盘、文本选择和复制功能等。它的适配要求相对较低,可以在较旧的设备上运行。 3. Android 1.6 Donut:这个版本增加了搜索框和快捷方式等功能。它的适配要求与Cupcake相似。 4. Android 2.0/2.1 Eclair:这个版本引入了许多新特性,包括支持多点触控、HTML5视频播放和Live壁纸等。它的适配要求相对较高,需要较新的设备支持。 5. Android 2.2 Froyo:这个版本引入了许多新特性,包括支持移动热点和Adobe Flash等。它的适配要求与Eclair相似。 6. Android 2.3 Gingerbread:这个版本引入了许多新特性,包括支持NFC和下载管理器等。它的适配要求相对较高,需要较新的设备支持。 7. Android 4.0 Ice Cream Sandwich:这个版本引入了许多新特性,包括全新的用户界面和面部解锁等。它的适配要求相对较高,需要较新的设备支持。 8. Android 4.1/4.2/4.3 Jelly Bean:这个版本引入了许多新特性,包括Google Now和通知增强等。它的适配要求与Ice Cream Sandwich相似。 9. Android 4.4 KitKat:这个版本引入了许多新特性,包括透明状态栏和打印支持等。它的适配要求相对较高,需要较新的设备支持。 10. Android 5.0/5.1 Lollipop:这个版本引入了许多新特性,包括Material Design和多用户支持等。它的适配要求相对较高,需要较新的设备支持。 11. Android 6.0 Marshmallow:这个版本引入了许多新特性,包括指纹识别和运行时权限等。它的适配要求相对较高,需要较新的设备支持。 12. Android 7.0/7.1 Nougat:这个版本引入了许多新特性,包括分屏模式和通知增强等。它的适配要求相对较高,需要较新的设备支持。 13. Android 8.0/8.1 Oreo:这个版本引入了许多新特性,包括自适应图标和通知渠道等。它的适配要求相对较高,需要较新的设备支持。 14. Android 9 Pie:这个版本引入了许多新特性,包括手势导航和应用程序切片等。它的适配要求相对较高,需要较新的设备支持。 15. Android 10:这个版本引入了许多新特性,包括暗黑模式和系统级录屏等。它的适配要求相对较高,需要较新的设备支持。 16. Android 11:这个版本引入了许多新特性,包括聊天气泡和无线Android Auto等。它的适配要求相对较高,需要较新的设备支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值