亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

android 版本檢測 Android程序的版本檢測與更新實現介紹

2020-04-11 12:36:27
字體:
來源:轉載
供稿:網友
做個網站的安卓客戶端,用戶安裝到自己手機上,如果我出了新版本怎么辦呢?要有版本更新功能。
本來版本檢測最好可以自動進行。但如果每次開啟程序,都要先檢測一輪,是一種浪費,畢竟版本更新是小概率的事情?;蛟S可以程序開啟的時候,判斷一下時間,單日就檢測,雙日就不檢測,或者隨機什么的,降低一下檢測的頻率?

我采取的做法是將檢測功能做到了菜單上,用戶有需要,就手動打開自己檢測一下。反正我們這個是網站客戶端,有版本更新,在網站上發個通告就行了。
版本檢測與更新有以下幾個關鍵步驟
1、檢測有無新版本
2、下載新版本
3、安裝替換新版本
我處理的方案是
1、在assets文件夾新增一個文件:ver.cfg,記錄版本信息,純文本格式,內容只有一句話:
復制代碼 代碼如下:

Version=1.0

 
這個會隨安裝包裝到用戶的手機上
然后在網站里面,設置一XML文件ver_apk.xml,內容也只有這么一點:
復制代碼 代碼如下:

<?xml version="1.0" encoding="utf-8" ?>
<string>1.0</string>

檢測的時候,就先訪問網站的這個XML,得到最新版本號,然后與手機上的ver.cfg文件里記錄的進行比對,不同的話就可以認為存在新版本,提示進行更新。
2、下載的話就是直接下載的,我還不知道怎么弄斷點續傳
3、安裝替換,關鍵在于簽名。就是每個版本的簽名要保持一致。否則新的無法替換舊的,提示安裝未完成。
------------------- 天氣太冷,咯咯咯 ------------------------------------
這個功能做在菜單上,觸發代碼如下:
復制代碼 代碼如下:

//==========================================================================
// 菜單
//==========================================================================
private static final String urlApk = "http://3g.***.com/tool/***.apk";
private static final String urlVer = "http://3g.***.com/tool/ver_apk.xml";
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE, Menu.FIRST + 1, 5, "檢測更新").setIcon(
android.R.drawable.ic_menu_upload);
menu.add(Menu.NONE,Menu.FIRST+2,4,"退出").setIcon(android.R.drawable.ic_lock_power_off);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Menu.FIRST + 1:
Toast.makeText(this, "正在檢測版本", Toast.LENGTH_LONG).show();
UpdateVer uv = new UpdateVer(urlApk,urlVer,MainActivity.this);
uv.checkVer();
break;
case Menu.FIRST + 2:
confirmExit();
break;
}
return false;
}

檢測更新因為代碼比較多,寫成一個類進行封裝
UpdateVer.java
復制代碼 代碼如下:

package android.***;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import android.webkit.URLUtil;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Properties;
import org.xml.sax.InputSource;
import java.text.SimpleDateFormat;
import java.util.Date;
public class UpdateVer extends Activity{
private static final String TAG = "DOWNLOADAPK";
private String PastVersion;
private String NowVersion;
public ProgressDialog pBar;
private String currentFilePath = "";
private String fileEx="";
private String fileNa="";
private String strURL="";
private String VersionUri ="";
private Context mContext;
private final String fileVer = "ver.cfg";
public UpdateVer(String urlapk,String urlver,final Context context){
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String ver = "?ver=" + df.format(new Date());//主要是避開手機的緩存
strURL = urlapk + ver;
VersionUri = urlver + ver;
mContext = context;
}
public void checkVer() {
// 解析Version網頁,獲取版本號
getVersionxml(VersionUri);
}
private void compareVer() {
load();

//當有最新版本的時候
if(PastVersion != null && !PastVersion.equals(NowVersion)){
Dialog dialog = new AlertDialog.Builder(mContext).setTitle("系統更新")
.setMessage(String.format("發現新版本%s,目前版本為%s,請更新!",NowVersion,PastVersion))// 設置內容
// 設置確定按鈕
.setPositiveButton("確定"
,new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
pBar = new ProgressDialog(mContext);
pBar.setTitle("正在下載");
pBar.setMessage("請稍候...");
pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
fileEx = strURL.substring(strURL.lastIndexOf(".") + 1,strURL.length()).toLowerCase();
fileEx = fileEx.substring(0,fileEx.lastIndexOf("?"));
fileNa = strURL.substring(strURL.lastIndexOf("/") + 1,strURL.lastIndexOf("."));
getFile(strURL);
}
}).setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int whichButton) {
// 點擊"取消"按鈕之后退出程序
}
}).create();// 創建
// 顯示對話框
dialog.show();
}
else{
Toast.makeText(mContext, String.format("當前為最新版本%s",PastVersion), Toast.LENGTH_LONG).show();
}
}
private void getFile(final String strPath)
{
pBar.show();
try{
if (strPath.equals(currentFilePath) ){
getDataSource(strPath);
}
currentFilePath = strPath;
Runnable r = new Runnable(){
@Override
public void run()
{
try{
getDataSource(strPath);
}
catch (Exception e){
Log.e(TAG, e.getMessage(), e);
}
}
};
new Thread(r).start();
}
catch(Exception e){
e.printStackTrace();
}
}
/*取得遠程文件*/
private void getDataSource(String strPath) throws Exception {
if (!URLUtil.isNetworkUrl(strPath)) {
Log.d("Tag","error");
}
else {
/*取得URL*/
URL myURL = new URL(strPath);
/*建立聯機*/
URLConnection conn = myURL.openConnection();
conn.connect();
/*InputStream 下載文件*/
InputStream is = conn.getInputStream();
if (is == null) {
Log.d("tag","error");
throw new RuntimeException("沒有讀取到文件內容");
}
/*建立臨時文件*/
File myTempFile = File.createTempFile(fileNa, "." + fileEx);
myTempFile.getAbsolutePath();
/*將文件寫入臨時盤*/
FileOutputStream fos = new FileOutputStream(myTempFile);
byte buf[] = new byte[128];
do{
int numread = is.read(buf);
if (numread <= 0) {
break;
}
fos.write(buf, 0, numread);
}while (true);

/*打開文件進行安裝*/
openFile(myTempFile);
try {
is.close();
}
catch (Exception ex){
Log.d("Tag","error");
Log.e(TAG, "error: " + ex.getMessage(), ex);
}
}
}
/* 在手機上打開文件 */
private void openFile(File f) {
pBar.cancel();
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(android.content.Intent.ACTION_VIEW);
/* 調用getMIMEType()來取得MimeType */
String type = getMIMEType(f);
/* 設定intent的file與MimeType */
intent.setDataAndType(Uri.fromFile(f),type);
mContext.startActivity(intent);
}
/* 判斷文件MimeType的method */
private String getMIMEType(File f) {
String type = "";
String fName = f.getName();
/* 取得擴展名 */
String end = fName.substring(fName.lastIndexOf(".")+1,fName.length()).toLowerCase();

/* 按擴展名的類型決定MimeType */
if(end.equals("m4a")
|| end.equals("mp3")
|| end.equals("mid")
|| end.equals("xmf")
|| end.equals("ogg")
|| end.equals("wav")){
type = "audio";
}
else if(end.equals("3gp") || end.equals("mp4")){
type = "video";
}
else if(end.equals("jpg")
|| end.equals("gif")
|| end.equals("png")
|| end.equals("jpeg")
|| end.equals("bmp")){
type = "image";
}
else if(end.equals("apk")){
/* android.permission.INSTALL_PACKAGES */
type = "application/vnd.android.package-archive";
}
else{
type = "*";
}
/*如果無法直接打開,就跳出軟件清單給使用者選擇 */
if(!end.equals("apk")){
type += "/*";
}
return type;
}
private void getVersionxml(String resourceUrl){
GetVer gv = new GetVer();
gv.execute(resourceUrl);
}
private boolean load(){
Properties properties = new Properties();
try{
InputStream stream = mContext.getAssets().open(fileVer);
//FileInputStream stream = mContext.openFileInput(fileVer);
//讀取文件內容
properties.load(stream);
}
catch (FileNotFoundException e){
return false;
}
catch(IOException e){
return false;
}
catch(Exception e){
return false;
}
PastVersion = String.valueOf(properties.get("Version").toString());
return true;
}

//==========================================================================
// GetVer
//==========================================================================
class GetVer extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... urlVer) {
String db = null;
URL url = null;

try {
url = new URL(urlVer[0]);
}
catch (MalformedURLException e) {
e.printStackTrace();
}
InputSource is = null;
try {
is = new InputSource(url.openStream());
is.setEncoding("UTF-8");
db = SAXGetVersionService.readRssXml(is);
}
catch (Exception e) {
e.printStackTrace();
}
return db;
}
@Override
protected void onCancelled() {
super.onCancelled();
}
@Override
protected void onPostExecute(String result) {
NowVersion = result;
compareVer();
}
}
}

AndroidManifest.xml要加上幾句
復制代碼 代碼如下:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RESTART_PACKAGES" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品99久久久久久久久| 亚洲一区亚洲二区| 午夜精品久久久久久久99热浪潮| 国产视频精品自拍| 国产精品jvid在线观看蜜臀| 国产亚洲欧洲黄色| 国产成人鲁鲁免费视频a| 在线观看久久久久久| 亚洲乱码国产乱码精品精天堂| 高清欧美性猛交xxxx| 国产裸体写真av一区二区| 国产欧美日韩免费看aⅴ视频| 亚洲成色777777女色窝| 成人写真视频福利网| 色av中文字幕一区| 久青草国产97香蕉在线视频| 98精品国产自产在线观看| 国产不卡在线观看| 国产视频精品va久久久久久| 久久精品国产久精国产思思| 日韩在线观看av| 性色av香蕉一区二区| 亚洲最大av网| 爱福利视频一区| 亚洲天堂第二页| 川上优av一区二区线观看| 深夜福利国产精品| 国产精品一区二区av影院萌芽| 欧美日韩亚洲高清| 久久久999国产精品| 日韩欧美亚洲综合| 日韩电影中文字幕在线| 国产欧美亚洲视频| 欧美国产亚洲精品久久久8v| 国产一区香蕉久久| 国产精品久久9| 亚洲国内精品视频| 中文字幕精品www乱入免费视频| 亚洲韩国日本中文字幕| 日韩女优人人人人射在线视频| 欧美成人全部免费| 欧美精品少妇videofree| 精品欧美一区二区三区| 精品日韩美女的视频高清| 亚洲国产一区二区三区四区| 中文字幕亚洲一区二区三区| 亚洲在线观看视频| 久久91亚洲精品中文字幕奶水| 国产精品国产三级国产aⅴ9色| 在线视频亚洲欧美| 国产成人97精品免费看片| 午夜精品美女自拍福到在线| 在线视频精品一| 成人97在线观看视频| 中文字幕亚洲色图| 亚洲乱码国产乱码精品精天堂| 疯狂做受xxxx欧美肥白少妇| 久久在线视频在线| 日韩中文字幕视频在线观看| 欧美色视频日本版| 国产精品十八以下禁看| 黑人精品xxx一区一二区| 色综合亚洲精品激情狠狠| 黑人与娇小精品av专区| 91国内精品久久| 91成人性视频| 日韩中文字幕在线视频| 国产日韩欧美在线看| 91成人在线播放| 久久香蕉精品香蕉| 麻豆精品精华液| 久久久久久久久久婷婷| 欧美精品一本久久男人的天堂| 中文字幕精品在线视频| 国内精品中文字幕| 精品无人国产偷自产在线| 一区二区三区四区视频| 欧美孕妇与黑人孕交| 国产精品com| 欧美成人亚洲成人日韩成人| 精品国产老师黑色丝袜高跟鞋| 欧美大尺度激情区在线播放| 久久精品一区中文字幕| 另类天堂视频在线观看| 亚洲精美色品网站| 亚洲福利影片在线| 国产精品av网站| 久久国产天堂福利天堂| 国产精品女主播| 国产一区二区三区在线观看网站| 日韩有码片在线观看| 高清欧美性猛交xxxx黑人猛交| 黄色成人av在线| 欧美中文在线视频| 欧美性猛交xxxxx水多| 国内伊人久久久久久网站视频| 精品国产一区av| 亚洲小视频在线观看| 伊人av综合网| 欧美中文字幕视频在线观看| 欧美激情亚洲自拍| 欧美激情视频在线| 久久天天躁狠狠躁夜夜av| 国产精品自拍小视频| 福利一区视频在线观看| 久久欧美在线电影| 亚洲天堂第二页| 欧美激情中文字幕乱码免费| 亚洲人午夜色婷婷| 亚洲精品影视在线观看| 精品亚洲一区二区三区四区五区| 久久久国产一区| 国产一区二区视频在线观看| 国产精品激情av在线播放| 91免费综合在线| 91精品在线一区| 亚洲最大福利视频网站| 亚洲少妇中文在线| 一个人看的www欧美| 黑人狂躁日本妞一区二区三区| 久久国产一区二区三区| 亚洲国产欧美一区二区三区同亚洲| 国产精品普通话| 中文字幕在线国产精品| 日韩福利伦理影院免费| 另类图片亚洲另类| 成人免费高清完整版在线观看| 91精品国产综合久久男男| 久久久久国产精品一区| 国产999精品| 欧美做爰性生交视频| 97久久超碰福利国产精品…| 久久久久国产一区二区三区| 亚洲国产精品免费| 一区二区三区视频在线| 中文字幕日韩欧美| 色婷婷av一区二区三区在线观看| 亚洲人成在线一二| 国产精品麻豆va在线播放| 久久久久久这里只有精品| 欧美有码在线观看视频| 性视频1819p久久| 欧美日韩在线影院| 性金发美女69hd大尺寸| 国产成人啪精品视频免费网| 亚洲精品短视频| 欧美视频在线视频| 久久久久久久网站| 永久免费看mv网站入口亚洲| 日韩免费观看高清| 欧美精品电影在线| 成人福利在线视频| 国产亚洲精品一区二555| 成人国产精品一区| 日韩在线资源网| 亚洲伊人一本大道中文字幕| 色噜噜久久综合伊人一本| 国产美女精品免费电影| 欧美肥老太性生活视频| 精品久久久久久久中文字幕| 欧美日韩国产一中文字不卡| 欧美一区二区大胆人体摄影专业网站| 日产日韩在线亚洲欧美| 欧美裸体xxxx极品少妇|