自动检测版本更新的流程
来源:互联网 发布:北京域名备案需要多久 编辑:程序博客网 时间:2024/05/22 08:02
强制自动更新的流程
我们首先在主的Activity或者是Fragment 里面调用,如果有新的版本的话就让他自动强制更新。
首先是获取当前版本号的方法代码如下:
//获取当前版本号的方法 public String getVersionCode(Context context){ PackageManager packageManager=context.getPackageManager(); PackageInfo packageInfo; String versionCode=""; try { packageInfo=packageManager.getPackageInfo(context.getPackageName(),0); versionCode=packageInfo.versionCode+""; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return versionCode; }
下面就是要获取接口看是否有新的版本,就是调用接口这是我的接口实现获取内容:
// 解析借口获取新的版本号public void getDatabanCode(){ AppContext.getHttpService().getUpdatecheck() .compose(RxLifecycleCompact.bind(this).<BanBenBean>withObservable()) .compose(RxLifeCycleCompat.<BanBenBean>callerSchedulers()) .subscribe(new BaseObserver<BanBenBean>() { @Override public void onSuccess(@NonNull BanBenBean banBenBean) { final String content = banBenBean.getContent(); if (banBenBean.getNew_version_name().equals(getVersionCode(getActivity()))) { ToastMan.showShortToast("是最新版本"); }else { ShowDialog(content, banBenBean.getDownload_url()); } } @Override public void onFail(Throwable e) { } });}
定义Dialog实现弹出的内容比如:确定和取消,代码如下:
// 定义dialog private void ShowDialog(String content, final String url) { Toast.makeText(getActivity(),""+content,Toast.LENGTH_SHORT).show(); new android.app.AlertDialog.Builder(getActivity()) .setTitle("版本更新") .setMessage(content+"加快还款法核算的") .setPositiveButton("更新", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); pBar = new CommonProgressDialog(getActivity()); pBar.setCanceledOnTouchOutside(false); pBar.setTitle("正在下载"); pBar.setCustomTitle(LayoutInflater.from( getActivity()).inflate( R.layout.title_dialog, null)); pBar.setMessage("正在下载"); pBar.setIndeterminate(true); pBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pBar.setCancelable(true); // downFile(URLData.DOWNLOAD_URL); final DownloadTask downloadTask = new DownloadTask( getActivity()); downloadTask.execute(url); pBar.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { downloadTask.cancel(true); } }); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }) .show(); }
在创建一个类内部类实现异步请求代码这里面的代码不用更改直接粘贴里面就能用如下:
/** * 下载应用 * * @author Administrator */ class DownloadTask extends AsyncTask<String, Integer, String> { private Context context; private PowerManager.WakeLock mWakeLock; public DownloadTask(Context context) { this.context = context; } @Override protected String doInBackground(String... sUrl) { InputStream input = null; OutputStream output = null; HttpURLConnection connection = null; File file = null; try { URL url = new URL(sUrl[0]); connection = (HttpURLConnection) url.openConnection(); connection.connect(); // expect HTTP 200 OK, so we don't mistakenly save error // report // instead of the file if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { return "Server returned HTTP " + connection.getResponseCode() + " " + connection.getResponseMessage(); } // this will be useful to display download percentage // might be -1: server did not report the length int fileLength = connection.getContentLength(); if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { file = new File(Environment.getExternalStorageDirectory(), DOWNLOAD_NAME); if (!file.exists()) { // 判断父文件夹是否存在 if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } } } else { Toast.makeText(getActivity(), "sd卡未挂载", Toast.LENGTH_LONG).show(); } input = connection.getInputStream(); output = new FileOutputStream(file); byte data[] = new byte[4096]; long total = 0; int count; while ((count = input.read(data)) != -1) { // allow canceling with back button if (isCancelled()) { input.close(); return null; } total += count; // publishing the progress.... if (fileLength > 0) // only if total length is known publishProgress((int) (total * 100 / fileLength)); output.write(data, 0, count); } } catch (Exception e) { System.out.println(e.toString()); return e.toString(); } finally { try { if (output != null) output.close(); if (input != null) input.close(); } catch (IOException ignored) { } if (connection != null) connection.disconnect(); } return null; } @Override protected void onPreExecute() { super.onPreExecute(); // take CPU lock to prevent CPU from going off if the user // presses the power button during download PowerManager pm = (PowerManager) context .getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName()); mWakeLock.acquire(); pBar.show(); } @Override protected void onProgressUpdate(Integer... progress) { super.onProgressUpdate(progress); // if we get here, length is known, now set indeterminate to false pBar.setIndeterminate(false); pBar.setMax(100); pBar.setProgress(progress[0]); } @Override protected void onPostExecute(String result) { mWakeLock.release(); pBar.dismiss(); if (result != null) { // 申请多个权限。 AndPermission.with(getActivity()) .requestCode(REQUEST_CODE_PERMISSION_SD) .permission(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) // rationale作用是:用户拒绝一次权限,再次申请时先征求用户同意,再打开授权对话框,避免用户勾选不再提示。 .rationale(rationaleListener ) .send(); Toast.makeText(context, "您未打开SD卡权限" + result, Toast.LENGTH_LONG).show(); } else { // Toast.makeText(context, "File downloaded", // Toast.LENGTH_SHORT) // .show(); update(); } } } private static final int REQUEST_CODE_PERMISSION_SD = 101; private static final int REQUEST_CODE_SETTING = 300; private RationaleListener rationaleListener = new RationaleListener() { @Override public void showRequestPermissionRationale(int requestCode, final Rationale rationale) { // 这里使用自定义对话框,如果不想自定义,用AndPermission默认对话框: // AndPermission.rationaleDialog(Context, Rationale).show(); // 自定义对话框。 AlertDialog.build(getActivity()) .setTitle(R.string.title_dialog) .setMessage(R.string.message_permission_rationale) .setPositiveButton(R.string.btn_dialog_yes_permission, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); rationale.resume(); } }) .setNegativeButton(R.string.btn_dialog_no_permission, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); rationale.cancel(); } }) .show(); } }; //----------------------------------SD权限----------------------------------// @PermissionYes(REQUEST_CODE_PERMISSION_SD) private void getMultiYes(List<String> grantedPermissions) { Toast.makeText(getActivity(), R.string.message_post_succeed, Toast.LENGTH_SHORT).show(); } @PermissionNo(REQUEST_CODE_PERMISSION_SD) private void getMultiNo(List<String> deniedPermissions) { Toast.makeText(getActivity(), R.string.message_post_failed, Toast.LENGTH_SHORT).show(); // 用户否勾选了不再提示并且拒绝了权限,那么提示用户到设置中授权。 if (AndPermission.hasAlwaysDeniedPermission(this, deniedPermissions)) { AndPermission.defaultSettingDialog(this, REQUEST_CODE_SETTING) .setTitle(R.string.title_dialog) .setMessage(R.string.message_permission_failed) .setPositiveButton(R.string.btn_dialog_yes_permission) .setNegativeButton(R.string.btn_dialog_no_permission, null) .show(); // 更多自定dialog,请看上面。 } } //----------------------------------权限回调处理----------------------------------// @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); /** * 转给AndPermission分析结果。 * * @param object 要接受结果的Activity、Fragment。 * @param requestCode 请求码。 * @param permissions 权限数组,一个或者多个。 * @param grantResults 请求结果。 */ AndPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_CODE_SETTING: { Toast.makeText(getActivity(), R.string.message_setting_back, Toast.LENGTH_LONG).show(); //设置成功,再次请求更新// getVersion(Tools.getVersion(getActivity())); break; } } } private void update() { //安装应用 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File(Environment .getExternalStorageDirectory(), DOWNLOAD_NAME)), "application/vnd.android.package-archive"); startActivity(intent); }
里面还缺少一个类tools
package com.hsy.update.utils;import android.content.Context;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.os.Environment;public class Tools { /** * 检查是否存在SDCard * * @return */ public static boolean hasSdcard() { String state = Environment.getExternalStorageState(); if (state.equals(Environment.MEDIA_MOUNTED)) { return true; } else { return false; } } /** * 2 * 获取版本号 3 * @return 当前应用的版本号 4 */ public static int getVersion(Context context) { try { PackageManager manager = context.getPackageManager(); PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0); String version = info.versionName; int versioncode = info.versionCode; return versioncode; } catch (Exception e) { e.printStackTrace(); } return 0; }}
还有一个自定义进度条的类代码如下:
public class CommonProgressDialog extends AlertDialog { private ProgressBar mProgress; private TextView mProgressNumber; private TextView mProgressPercent; private TextView mProgressMessage; private Handler mViewUpdateHandler; private int mMax; private CharSequence mMessage; private boolean mHasStarted; private int mProgressVal; private String TAG = "CommonProgressDialog"; private String mProgressNumberFormat; private NumberFormat mProgressPercentFormat; public CommonProgressDialog(Context context) { super(context); // TODO Auto-generated constructor stub initFormats(); } @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.common_progress_dialog); mProgress = (ProgressBar) findViewById(R.id.progress); mProgressNumber = (TextView) findViewById(R.id.progress_number); mProgressPercent = (TextView) findViewById(R.id.progress_percent); mProgressMessage = (TextView) findViewById(R.id.progress_message); // LayoutInflater inflater = LayoutInflater.from(getContext()); mViewUpdateHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); int progress = mProgress.getProgress(); int max = mProgress.getMax(); double dProgress = (double) progress / (double) (1024 * 1024); double dMax = (double) max / (double) (1024 * 1024); if (mProgressNumberFormat != null) { String format = mProgressNumberFormat; mProgressNumber.setText(String.format(format, dProgress, dMax)); } else { mProgressNumber.setText(""); } if (mProgressPercentFormat != null) { double percent = (double) progress / (double) max; SpannableString tmp = new SpannableString( mProgressPercentFormat.format(percent)); tmp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, tmp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); mProgressPercent.setText(tmp); } else { mProgressPercent.setText(""); } } }; // View view = inflater.inflate(R.layout.common_progress_dialog, null); // mProgress = (ProgressBar) view.findViewById(R.id.progress); // mProgressNumber = (TextView) view.findViewById(R.id.progress_number); // mProgressPercent = (TextView) // view.findViewById(R.id.progress_percent); // setView(view); // mProgress.setMax(100); onProgressChanged(); if (mMessage != null) { setMessage(mMessage); } if (mMax > 0) { setMax(mMax); } if (mProgressVal > 0) { setProgress(mProgressVal); } } private void initFormats() { mProgressNumberFormat = "%1.2fM/%2.2fM"; mProgressPercentFormat = NumberFormat.getPercentInstance(); mProgressPercentFormat.setMaximumFractionDigits(0); } private void onProgressChanged() { mViewUpdateHandler.sendEmptyMessage(0); } public void setProgressStyle(int style) { // mProgressStyle = style; } public int getMax() { if (mProgress != null) { return mProgress.getMax(); } return mMax; } public void setMax(int max) { if (mProgress != null) { mProgress.setMax(max); onProgressChanged(); } else { mMax = max; } } public void setIndeterminate(boolean indeterminate) { if (mProgress != null) { mProgress.setIndeterminate(indeterminate); } // else { // mIndeterminate = indeterminate; // } } public void setProgress(int value) { if (mHasStarted) { mProgress.setProgress(value); onProgressChanged(); } else { mProgressVal = value; } } @Override public void setMessage(CharSequence message) { // TODO Auto-generated method stub // super.setMessage(message); if (mProgressMessage != null) { mProgressMessage.setText(message); } else { mMessage = message; } } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); mHasStarted = true; } @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); mHasStarted = false; }}
最后还缺少两个XML文件
文件一
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="vertical" > <TextView android:id="@+id/progress_message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="20dp" android:textColor="#000000" android:textSize="20sp" /> <ProgressBar android:id="@+id/progress" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="30px" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="20dp" android:progressDrawable="@drawable/common_progressdialog_progressbar_background" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="20dp" android:gravity="center" android:orientation="horizontal" > <TextView android:id="@+id/progress_percent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:gravity="center_horizontal" android:text="4" android:textColor="@color/red" android:textSize="15sp" /> <TextView android:id="@+id/progress_number" android:layout_width="250px" android:layout_height="wrap_content" android:layout_marginLeft="120px" android:gravity="center_horizontal" android:textColor="@color/red" android:textSize="30px" android:visibility="gone" /> </LinearLayout> </LinearLayout></FrameLayout>
XML文件二
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="正在下载" android:textColor="@color/white" android:textSize="15sp" /></LinearLayout>
这样基本实现检测版本实现自动下载的 功能,最后检查一下权限
/*权限获取*/ compile 'com.yanzhenjie:permission:1.0.5' <!--网络请求--> <uses-permission android:name="android.permission.INTERNET" /> <!--保持手机唤醒--> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!--sd--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
本文总结:如果实现不了自动更新的话可以加我QQ939986850和我交流也可以扫描下面的二维码加入我的公众号了解更多,谢谢大家的支持,希望大家互相交流共同进步实现我们人生最大的价值而奋斗,!!!
阅读全文
0 0
- 自动检测版本更新的流程
- 软件版本的自动检测及更新
- iOS app自动检测版本更新的功能
- iOS自动检测版本更新
- Android 自动检测更新apk版本
- 自动检测更新apk版本问
- iOS 自动检测版本更新APP
- 自动检测版本更新及自动安装
- android版本自动检测更新 版本检测 自动更新 自动安装
- 联网更新版本功能的流程说明
- Android应用更新-自动检测版本及自动升级
- iOS程序自动检测更新的实现
- iOS程序自动检测更新的实现
- iOS程序自动检测更新的实现
- iOS程序自动检测更新的实现
- iOS程序自动检测AppStore更新的实现
- iOS程序自动检测更新的实现
- Android 自动检测更新功能的实现
- adns解析库——域名解析实例(C++、linux)
- 自动客服功能的微信小程序
- 42、我的C#学习笔记8
- idea svn upgrade
- 中国传统文化课程笔记
- 自动检测版本更新的流程
- SpringMVC的工作原理
- 技术分享:基于 Kubernetes 的 AI 训练实践
- matlab2014调用vs2015进行混合编译生成mex文件
- 11.Nginx启动流程之ngx_add_inherited_sockets
- MXNet官方文档中文版教程(5):加载数据(Iterators)
- MACS原理,使用,结果文件解析
- Oracle 11g中管理员用户sys,system密码不可用解决办法
- mysql 浅谈