复兴C2016手机09体系安装包(复兴手机安装包下载)「复兴手机官网」

  各位同砚,早上好,本日为各人保举的是Teprinciple同砚投稿的文章,文章的内容是先容了他的开源库实如今线下载的思绪,以及期间必要留意思量的一些题目,值得对这块不认识的同砚学习一下,作者在末了还总结了当火线案的一些不敷。固然,假如你以为这个方案尚有更好的发起,也欢迎在下方留言。

  作者简书:https://www.jianshu.com/p/9c91bb984c85

UpdateAppUtils

  一行代码,快速实现app在线下载更新,先看结果图:

  快速利用

中兴C2016手机09系统安装包(中兴手机安装包下载) 复兴
C2016手机09体系
安装包(复兴
手机安装包下载)「复兴手机官网」 行业资讯

  先来看看怎样一行代码实现更新:

  dependencies{compile'com.teprinciple:updateapputils:1.3.1'}UpdateAppUtils.from(this).checkBy(UpdateAppUtils.CHECK_BY_VERSION_NAME)//更新检测方式,默以为VersionCode.serverVersionCode(2).serverVersionName("2.0").apkPath(apkPath).showNotification(false)//是否表现下载进度到关照栏,默以为true.updateInfo(info)//更新日记信息String.downloadBy(UpdateAppUtils.DOWNLOAD_BY_BROWSER)//下载方式:app下载、手机欣赏器下载。默认app下载.isForce(true)//是否逼迫更新,默认false逼迫更新环境下用户差别意更新则不能利用app.update();实现原理

  利用很简单吧,着实实现过程也很简单,大抵分为三步:

  1、根据初入参数判定是否必要更新

  3、安装最新apk

中兴C2016手机09系统安装包(中兴手机安装包下载) 复兴
C2016手机09体系
安装包(复兴
手机安装包下载)「复兴手机官网」 行业资讯

  下面我们来看看源码:

  第一步:初始化参数并判定。根据传入的服务器版本号与本地版本号做出判定是否必要更新,并设置好下载地点,下载方式等参数。

  /***CreatedbyTeprincipleon2016/11/15.*/publicclassUpdateAppUtils{privatefinalStringTAG="UpdateAppUtils";publicstaticfinalintCHECK_BY_VERSION_NAME=1001;publicstaticfinalintCHECK_BY_VERSION_CODE=1002;publicstaticfinalintDOWNLOAD_BY_APP=1003;publicstaticfinalintDOWNLOAD_BY_BROWSER=1004;privateActivityactivity;privateintcheckBy=CHECK_BY_VERSION_CODE;privateintdownloadBy=DOWNLOAD_BY_APP;privateintserverVersionCode=0;privateStringapkPath="";privateStringserverVersionName="";privatebooleanisForce=false;//是否逼迫更新privateintlocalVersionCode=0;privateStringlocalVersionName="";publicstaticbooleanshowNotification=true;privateStringupdateInfo="";privateUpdateAppUtils(Activityactivity){this.activity=activity;getAPPLocalVersion(activity);}publicstaticUpdateAppUtilsfrom(Activityactivity){returnnewUpdateAppUtils(activity);}publicUpdateAppUtilscheckBy(intcheckBy){this.checkBy=checkBy;returnthis;}publicUpdateAppUtilsapkPath(StringapkPath){this.apkPath=apkPath;returnthis;}publicUpdateAppUtilsdownloadBy(intdownloadBy){this.downloadBy=downloadBy;returnthis;}publicUpdateAppUtilsshowNotification(booleanshowNotification){this.showNotification=showNotification;returnthis;}publicUpdateAppUtilsupdateInfo(StringupdateInfo){this.updateInfo=updateInfo;returnthis;}publicUpdateAppUtilsserverVersionCode(intserverVersionCode){this.serverVersionCode=serverVersionCode;returnthis;}publicUpdateAppUtilsserverVersionName(StringserverVersionName){this.serverVersionName=serverVersionName;returnthis;}publicUpdateAppUtilsisForce(booleanisForce){this.isForce=isForce;returnthis;}//获取apk的版本号currentVersionCodeprivatevoidgetAPPLocalVersion(Contextctx){PackageManagermanager=ctx.getPackageManager();try{PackageInfoinfo=manager.getPackageInfo(ctx.getPackageName(),0);localVersionName=info.versionName;//版本名localVersionCode=info.versionCode;//版本号}catch(PackageManager.NameNotFoundExceptione){e.printStackTrace();}}publicvoidupdate(){switch(checkBy){caseCHECK_BY_VERSION_CODE:if(serverVersionCodelocalVersionCode){toUpdate();}else{Log.i(TAG,"当前版本是最新版本"+serverVersionCode+"/"+serverVersionName);}break;caseCHECK_BY_VERSION_NAME:if(!serverVersionName.equals(localVersionName)){toUpdate();}else{Log.i(TAG,"当前版本是最新版本"+serverVersionCode+"/"+serverVersionName);}break;}}privatevoidtoUpdate(){realUpdate();}privatevoidrealUpdate(){ConfirmDialogdialog=newConfirmDialog(activity,newCallback(){@Overridepublicvoidcallback(intposition){switch(position){case0://cancleif(isForce)System.exit(0);break;case1://sureif(downloadBy==DOWNLOAD_BY_APP){if(isWifiConnected(activity)){DownloadAppUtils.downloadForAutoInstall(activity,apkPath,"demo.apk",serverVersionName);}else{newConfirmDialog(activity,newCallback(){@Overridepublicvoidcallback(intposition){if(position==1){DownloadAppUtils.downloadForAutoInstall(activity,apkPath,"demo.apk",serverVersionName);}else{if(isForce)activity.finish();}}}).setContent("如今手机不是WiFi状态n确认是否继承下载更新?").show();}}elseif(downloadBy==DOWNLOAD_BY_BROWSER){DownloadAppUtils.downloadForWebView(activity,apkPath);}break;}}});Stringcontent="发现新版本:"+serverVersionName+"n是否下载更新?";if(!TextUtils.isEmpty(updateInfo)){content="发现新版本:"+serverVersionName+"是否下载更新?nn"+updateInfo;}dialog.setContent(content);dialog.setCancelable(false);dialog.show();}//检测wifi是否毗连publicstaticbooleanisWifiConnected(Contextcontext){ConnectivityManagercm=(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);if(cm!=null){NetworkInfonetworkInfo=cm.getActiveNetworkInfo();if(networkInfo!=nullnetworkInfo.getType()==ConnectivityManager.TYPE_WIFI){returntrue;}}returnfalse;}}/***CreatedbyTeprincipleon2016/12/13.*/publicclassDownloadAppUtils{privatestaticfinalStringTAG=DownloadAppUtils.class.getSimpleName();publicstaticlongdownloadUpdateApkId=-1;//下载更新Apk下载任务对应的IdpublicstaticStringdownloadUpdateApkFilePath;//下载更新Apk文件路径/***通过欣赏器下载APK包*@paramcontext*@paramurl*/publicstaticvoiddownloadForWebView(Contextcontext,Stringurl){Uriuri=Uri.parse(url);Intentintent=newIntent(Intent.ACTION_VIEW,uri);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent);}/***下载更新apk包*权限:1,uses-permissionandroid:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/*@paramcontext*@paramurl*/publicstaticvoiddownloadForAutoInstall(Contextcontext,Stringurl,StringfileName,Stringtitle){if(TextUtils.isEmpty(url)){return;}try{Uriuri=Uri.parse(url);DownloadManagerdownloadManager=(DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);DownloadManager.Requestrequest=newDownloadManager.Request(uri);//在关照栏中表现request.setVisibleInDownloadsUi(true);request.setTitle(title);//VISIBILITY_VISIBLE:下载过程中可见,下载完后主动消散(默认)//VISIBILITY_VISIBLE_NOTIFY_COMPLETED:下载过程中和下载完成后均可见//VISIBILITY_HIDDEN:始终不表现关照if(!UpdateAppUtils.showNotification)request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);StringfilePath=null;if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//外部存储卡filePath=Environment.getExternalStorageDirectory().getAbsolutePath();}else{Log.i(TAG,"没有SD卡");return;}downloadUpdateApkFilePath=filePath+File.separator+fileName;deleteFile(downloadUpdateApkFilePath);//若存在,则删除UrifileUri=Uri.fromFile(newFile(downloadUpdateApkFilePath));request.setDestinationUri(fileUri);downloadUpdateApkId=downloadManager.enqueue(request);}catch(Exceptione){e.printStackTrace();downloadForWebView(context,url);}}privatestaticbooleandeleteFile(StringfileStr){Filefile=newFile(fileStr);returnfile.delete();}}

  第三步、安装apk。DownloadManager下载完成后,会发送关照。我们在UpdateAppReceiver,担当到关照后实行安装操纵。

  /***注册*actionandroid:name="android.intent.action.DOWNLOAD_COMPLETE"/*actionandroid:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED"/*/publicclassUpdateAppReceiverextendsBroadcastReceiver{publicUpdateAppReceiver(){}@OverridepublicvoidonReceive(Contextcontext,Intentintent){//处理惩罚下载完成Cursorc=null;if(DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())){if(DownloadAppUtils.downloadUpdateApkId=0){longdownloadId=DownloadAppUtils.downloadUpdateApkId;DownloadManager.Queryquery=newDownloadManager.Query();query.setFilterById(downloadId);DownloadManagerdownloadManager=(DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);c=downloadManager.query(query);if(c.moveToFirst()){intstatus=c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));if(status==DownloadManager.STATUS_FAILED){downloadManager.remove(downloadId);}elseif(status==DownloadManager.STATUS_SUCCESSFUL){if(DownloadAppUtils.downloadUpdateApkFilePath!=null){Intenti=newIntent(Intent.ACTION_VIEW);FileapkFile=newFile(DownloadAppUtils.downloadUpdateApkFilePath);if(Build.VERSION.SDK_INT=Build.VERSION_CODES.N){i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);UricontentUri=FileProvider.getUriForFile(context,context.getPackageName()+".fileprovider",apkFile);i.setDataAndType(contentUri,"application/vnd.android.package-archive");}else{i.setDataAndType(Uri.fromFile(apkFile),"application/vnd.android.package-archive");}i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(i);}}}c.close();}}}}

  通过上面三个类就可以实如今线下载更新app了。下面我们看看关于Android6.0以及Android7.0的适配。

  适配Android7.0

  安卓官方为了进步私有文件的安全性,对于Android7.0及更高版本的应用私有目次被限定访问。因此,在利用Intent方式安装时,实行转达file://URI会触发FileUriExposedException。办理方法是利用FileProvider,如下:

  1、注册provider

  providerandroid:name="android.support.v4.content.FileProvider"android:authorities="${applicationId}.fileprovider"android:exported="false"android:grantUriPermissions="true"meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths"//provider

  2、新建file_paths.xml文件

  ?xmlversion="1.0"encoding="utf-8"?pathsexternal-pathpath="Android/data/包名/"name="files_root"/external-pathpath="."name="external_storage_root"//paths适配Android6.0

  关于6.0适配,请自行在调用API时申请WRITE_EXTERNAL_STORAGE权限,可以参考demo中的代码

  如今不敷之处

  UpdateAppUtils很简单方便实现了app的在线下载更新。但是本库如今有存在有一些不敷之处:

  1、如今利用DownloadManager作为下载模块,但是国内部分手机DownloadManager功能已被阉割,造成不能下载。

  2、如今更新弹窗临时没提供自界说UI接口。

  3、如今每次查抄需更新后都实行下载,没有判定本地是否已有最新apk文件。

  这些题目我会在背面举行美满。假如你发现本库有其他的不敷,大概对本库有好的发起都可以issue我。盼望能通过各人的力气,一起把UpdateAppUtils做的更好。

  具体原理及源码可见https://github.com/teprinciple/UpdateAppDemo

  以为文章不错,欢迎转发,点赞,赞赏支持作者。更多出色,欢迎连续关注“Android程序员”。

客户评论

我要评论