最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

android 版本檢測(cè) Android程序的版本檢測(cè)與更新實(shí)現(xiàn)介紹

 更新時(shí)間:2013年01月06日 17:49:59   作者:  
做個(gè)網(wǎng)站的安卓客戶端,用戶安裝到自己手機(jī)上,如果我出了新版本怎么辦呢?要有版本更新功能,感興趣的朋友可以了解下
做個(gè)網(wǎng)站的安卓客戶端,用戶安裝到自己手機(jī)上,如果我出了新版本怎么辦呢?要有版本更新功能。
本來(lái)版本檢測(cè)最好可以自動(dòng)進(jìn)行。但如果每次開啟程序,都要先檢測(cè)一輪,是一種浪費(fèi),畢竟版本更新是小概率的事情?;蛟S可以程序開啟的時(shí)候,判斷一下時(shí)間,單日就檢測(cè),雙日就不檢測(cè),或者隨機(jī)什么的,降低一下檢測(cè)的頻率?

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

Version=1.0

 
這個(gè)會(huì)隨安裝包裝到用戶的手機(jī)上
然后在網(wǎng)站里面,設(shè)置一XML文件ver_apk.xml,內(nèi)容也只有這么一點(diǎn):
復(fù)制代碼 代碼如下:

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

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

//==========================================================================
// 菜單
//==========================================================================
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, "檢測(cè)更新").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, "正在檢測(cè)版本", Toast.LENGTH_LONG).show();
UpdateVer uv = new UpdateVer(urlApk,urlVer,MainActivity.this);
uv.checkVer();
break;
case Menu.FIRST + 2:
confirmExit();
break;
}
return false;
}

檢測(cè)更新因?yàn)榇a比較多,寫成一個(gè)類進(jìn)行封裝
UpdateVer.java
復(fù)制代碼 代碼如下:

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());//主要是避開手機(jī)的緩存
strURL = urlapk + ver;
VersionUri = urlver + ver;
mContext = context;
}
public void checkVer() {
// 解析Version網(wǎng)頁(yè),獲取版本號(hào)
getVersionxml(VersionUri);
}
private void compareVer() {
load();

//當(dāng)有最新版本的時(shí)候
if(PastVersion != null && !PastVersion.equals(NowVersion)){
Dialog dialog = new AlertDialog.Builder(mContext).setTitle("系統(tǒng)更新")
.setMessage(String.format("發(fā)現(xiàn)新版本%s,目前版本為%s,請(qǐng)更新!",NowVersion,PastVersion))// 設(shè)置內(nèi)容
// 設(shè)置確定按鈕
.setPositiveButton("確定"
,new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
pBar = new ProgressDialog(mContext);
pBar.setTitle("正在下載");
pBar.setMessage("請(qǐng)稍候...");
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) {
// 點(diǎn)擊"取消"按鈕之后退出程序
}
}).create();// 創(chuàng)建
// 顯示對(duì)話框
dialog.show();
}
else{
Toast.makeText(mContext, String.format("當(dāng)前為最新版本%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();
}
}
/*取得遠(yuǎn)程文件*/
private void getDataSource(String strPath) throws Exception {
if (!URLUtil.isNetworkUrl(strPath)) {
Log.d("Tag","error");
}
else {
/*取得URL*/
URL myURL = new URL(strPath);
/*建立聯(lián)機(jī)*/
URLConnection conn = myURL.openConnection();
conn.connect();
/*InputStream 下載文件*/
InputStream is = conn.getInputStream();
if (is == null) {
Log.d("tag","error");
throw new RuntimeException("沒有讀取到文件內(nèi)容");
}
/*建立臨時(shí)文件*/
File myTempFile = File.createTempFile(fileNa, "." + fileEx);
myTempFile.getAbsolutePath();
/*將文件寫入臨時(shí)盤*/
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);

/*打開文件進(jìn)行安裝*/
openFile(myTempFile);
try {
is.close();
}
catch (Exception ex){
Log.d("Tag","error");
Log.e(TAG, "error: " + ex.getMessage(), ex);
}
}
}
/* 在手機(jī)上打開文件 */
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);
/* 調(diào)用getMIMEType()來(lái)取得MimeType */
String type = getMIMEType(f);
/* 設(shè)定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();
/* 取得擴(kuò)展名 */
String end = fName.substring(fName.lastIndexOf(".")+1,fName.length()).toLowerCase();

/* 按擴(kuò)展名的類型決定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 = "*";
}
/*如果無(wú)法直接打開,就跳出軟件清單給使用者選擇 */
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);
//讀取文件內(nèi)容
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要加上幾句
復(fù)制代碼 代碼如下:

<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" />

相關(guān)文章

  • Android中三種注入事件方法比較

    Android中三種注入事件方法比較

    這篇文章主要介紹了Android中三種注入事件方法比較,本文分別講解了使用內(nèi)部APIs、使用instrumentation對(duì)象、直接注入事件到設(shè)備/dev/input/eventX等3種方法,需要的朋友可以參考下
    2015-02-02
  • android實(shí)現(xiàn)動(dòng)態(tài)顯隱進(jìn)度條

    android實(shí)現(xiàn)動(dòng)態(tài)顯隱進(jìn)度條

    這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)動(dòng)態(tài)顯隱進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Android精確測(cè)量文本寬高及基線位置的方法

    Android精確測(cè)量文本寬高及基線位置的方法

    這篇文章主要給大家介紹了關(guān)于Android精確測(cè)量文本寬高及基線位置的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • OpenGL實(shí)現(xiàn)Bezier曲線的方法示例

    OpenGL實(shí)現(xiàn)Bezier曲線的方法示例

    今天小編就為大家分享一篇關(guān)于OpenGL實(shí)現(xiàn)Bezier曲線的方法示例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • Android入門之Gallery+ImageSwitcher用法實(shí)例解析

    Android入門之Gallery+ImageSwitcher用法實(shí)例解析

    這篇文章主要介紹了Android入門之Gallery+ImageSwitcher用法,對(duì)Android初學(xué)者有很好的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-08-08
  • Android自定義View實(shí)現(xiàn)圓弧進(jìn)度的效果

    Android自定義View實(shí)現(xiàn)圓弧進(jìn)度的效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)圓弧進(jìn)度的效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • Android自定義View實(shí)現(xiàn)照片裁剪框與照片裁剪功能

    Android自定義View實(shí)現(xiàn)照片裁剪框與照片裁剪功能

    這篇文章主要介紹了Android自定義View實(shí)現(xiàn)照片裁剪框與照片裁剪功能的相關(guān)資料,需要的朋友可以參考下
    2016-07-07
  • Android實(shí)現(xiàn)收到新短信后自動(dòng)發(fā)郵件功能

    Android實(shí)現(xiàn)收到新短信后自動(dòng)發(fā)郵件功能

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)收到新短信后自動(dòng)發(fā)郵件功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 21天學(xué)習(xí)android開發(fā)教程之MediaPlayer

    21天學(xué)習(xí)android開發(fā)教程之MediaPlayer

    21天學(xué)習(xí)android開發(fā)教程之MediaPlayer,MediaPlayer可以播放音頻和視頻,操作相對(duì)簡(jiǎn)單,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Android主題切換之探究白天和夜間模式

    Android主題切換之探究白天和夜間模式

    所謂的主題切換,就是能夠根據(jù)不同的設(shè)定,呈現(xiàn)不同風(fēng)格的界面給用戶,也就是所謂的換膚。下面跟小編一起來(lái)看看怎么實(shí)現(xiàn)Android主題切換中的白天和夜間模式。
    2016-07-07

最新評(píng)論

连南| 乾安县| 巴林右旗| 鸡泽县| 洛浦县| 福海县| 邯郸县| 奈曼旗| 陵水| 塘沽区| 静乐县| 太白县| 清徐县| 威宁| 察雅县| 梁平县| 新营市| 西贡区| 搜索| 林州市| 甘德县| 岐山县| 木里| 邵武市| 老河口市| 大英县| 宜春市| 昔阳县| 逊克县| 遂宁市| 鄯善县| 易门县| 安国市| 灌南县| 上虞市| 巫溪县| 定襄县| 黄龙县| 遵义县| 错那县| 平原县|