Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> app自動升級(初級版)

app自動升級(初級版)

編輯:關於Android編程

提醒一下,更新的操作不要放到Application中,有的人想程序啟動的時候就馬上檢查更新,然後就把更新的操作放在了Application中,Application不是可見界面,所以不會有彈出框提醒,我測試的時候是這樣的,不知道我解釋的對不對,不對了請指正。謝謝

可以優化的地方:

判斷當前網絡是不是數據連接,數據連接下應該彈出對話框讓用戶再次確認,為用戶流量考慮

這個是初級版的,更新條顯示在了前台

項目需要,學習了一下app自動升級,網上查了好多資料,好多都不能直接用。下面我自己寫了一個,下次用到了直接拷貝就行了

加上權限防止忘記

 
    
    
    
    

新建布局文件:

updateversion.xml

 



	

更新類UpdateVersion.java
package com.example.updateversion;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;

public class UpdateVersion {
	private static final int DOWNLOAD = 1;
	private static final int DOWNLOAD_FINISH = 2;
	private static final int CONNECT_FAILED = 0;
	private static final int CONNECT_SUCCESS = 1;
	HashMap mHashMap;
	private String mSavePath;
	private int progress;
	private boolean cancelUpdate = false;
	private Context mContext;
	private ProgressBar mProgress;
	private Dialog mDownloadDialog;
	private String mXmlPath; // 服務器更新xml存放地址

	public UpdateVersion(Context context, String xmlPath, String savePath) {
		this.mContext = context;
		this.mXmlPath = xmlPath;
		this.mSavePath = savePath;
	}

	private Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case DOWNLOAD:
				mProgress.setProgress(progress);
				break;
			case DOWNLOAD_FINISH:
				installApk();
				break;
			default:
				break;
			}
		};
	};

	/**
	 * 檢查更新
	 */
	public void checkUpdate() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {

					URL url = new URL(mXmlPath);
					HttpURLConnection conn = (HttpURLConnection)url.openConnection();
					conn.setReadTimeout(5*1000);
					conn.setRequestMethod("GET");
					if(conn.getResponseCode()==200){
						Log.i("TAG", "dfdfd");
						Log.i("TAG", conn.getResponseCode()+"");
						InputStream inStream = conn.getInputStream();
						Log.i("TAG", "dfdfd");
						mHashMap = parseXml(inStream);

						Message msg = new Message();
						msg.what = CONNECT_SUCCESS;
						handler.sendMessage(msg);
					}
				} catch (Exception e) {
					Message msg = new Message();
					msg.what = CONNECT_FAILED;
					handler.sendMessage(msg);
				}
			}
		}).start();

	}

	/**
	 * 訪問服務器更新XML
	 */
	Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case CONNECT_FAILED:
				Toast.makeText(mContext, "訪問服務器失敗!", Toast.LENGTH_SHORT).show();
				break;
			case CONNECT_SUCCESS:
				if (null != mHashMap) {
					int serviceCode = Integer.valueOf(mHashMap.get("version"));
					if (serviceCode > getVersionCode(mContext)) {
						showNoticeDialog();
					}
				}
				break;
			}
		}
	};

	/**
	 * 獲取程序版本號
	 */
	private int getVersionCode(Context context) {
		int versionCode = 0;
		try {
			versionCode = context.getPackageManager().getPackageInfo(
					mContext.getPackageName(), 0).versionCode;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return versionCode;
	}

	/**
	 * 是否更新提示窗口
	 */
	private void showNoticeDialog() {
		AlertDialog.Builder builder = new Builder(mContext);
		builder.setTitle("有重要更新");
		builder.setMessage(mHashMap.get("updateInfo"));
		builder.setPositiveButton("更新",
				new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				showDownloadDialog();
			}
		});

		builder.setNegativeButton("忽略",
				new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});
		Dialog noticeDialog = builder.create();
		noticeDialog.show();
	}

	/**
	 * 下載等待窗口
	 */
	private void showDownloadDialog() {
		AlertDialog.Builder builder = new Builder(mContext);
		builder.setTitle("正在更新");
		final LayoutInflater inflater = LayoutInflater.from(mContext);
		View v = inflater.inflate(R.layout.updateversion, null);
		mProgress = (ProgressBar) v.findViewById(R.id.update_progress);
		builder.setView(v);
		builder.setNegativeButton("取消下載",
				new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				cancelUpdate = true;
			}
		});
		mDownloadDialog = builder.create();
		mDownloadDialog.show();
		downloadApk();
	}

	/**
	 * 下載apk
	 */
	private void downloadApk() {
		new downloadApkThread().start();
	}

	/**
	 * 下載程序
	 */
	private class downloadApkThread extends Thread {
		@Override
		public void run() {
			try {
				if (Environment.getExternalStorageState().equals(
						Environment.MEDIA_MOUNTED)) {

					URL url = new URL(mHashMap.get("url"));
					HttpURLConnection conn = (HttpURLConnection) url
							.openConnection();
					conn.connect();
					int length = conn.getContentLength();
					InputStream is = conn.getInputStream();

					File file = new File(mSavePath);
					if (!file.exists()) {
						file.mkdir();
					}
					File apkFile = new File(mSavePath, mHashMap.get("name"));
					FileOutputStream fos = new FileOutputStream(apkFile);
					int count = 0;
					byte buf[] = new byte[1024];
					do {
						int numread = is.read(buf);
						count += numread;
						progress = (int) (((float) count / length) * 100);
						mHandler.sendEmptyMessage(DOWNLOAD);
						if (numread <= 0) {
							mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
							break;
						}

						fos.write(buf, 0, numread);
					} while (!cancelUpdate);
					fos.close();
					is.close();
				}
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			mDownloadDialog.dismiss();
		}
	};

	/**
	 * 安裝apk
	 */
	private void installApk() {
		File apkfile = new File(mSavePath, mHashMap.get("name"));
		if (!apkfile.exists()) {
			return;
		}

		Intent i = new Intent(Intent.ACTION_VIEW);
		i.setDataAndType(Uri.parse("file://" + apkfile.toString()),
				"application/vnd.android.package-archive");
		mContext.startActivity(i);
	}

	private HashMap parseXml(InputStream inStream)
			throws Exception {
		HashMap hashMap = new HashMap();
		// 實例化一個文檔構建器工廠
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// 通過文檔構建器工廠獲取一個文檔構建器
		DocumentBuilder builder = factory.newDocumentBuilder();
		// 通過文檔通過文檔構建器構建一個文檔實例
		Document document = builder.parse(inStream);
		// 獲取XML文件根節點
		Element root = document.getDocumentElement();
		// 獲得所有子節點
		NodeList childNodes = root.getChildNodes();
		for (int j = 0; j < childNodes.getLength(); j++) {
			// 遍歷子節點
			Node childNode = (Node) childNodes.item(j);
			if (childNode.getNodeType() == Node.ELEMENT_NODE) {
				Element childElement = (Element) childNode;
				// 版本號
				if ("version".equals(childElement.getNodeName())) {
					hashMap.put("version", childElement.getFirstChild()
							.getNodeValue());
				}
				// 軟件名稱
				else if (("name".equals(childElement.getNodeName()))) {
					hashMap.put("name", childElement.getFirstChild()
							.getNodeValue());
				}
				// 下載地址
				else if (("url".equals(childElement.getNodeName()))) {
					hashMap.put("url", childElement.getFirstChild()
							.getNodeValue());
				}
				else if (("updateInfo".equals(childElement.getNodeName()))) {
					hashMap.put("updateInfo", childElement.getFirstChild()
							.getNodeValue());
				}
			}
		}
		return hashMap;
	}

	//當不需要的時候,清除之前的下載文件,避免浪費用戶空間
	public void deletFile(){
		File updateFile = new File(mSavePath,mContext.getResources().getString(R.string.app_name)+".apk");
		if(updateFile.exists()){

			updateFile.delete();
		}
	}

}

在MainActivity中使用:

 

 

package com.example.updateversion;

import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;


public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		update();

	}

	private void update() {  

		if(isNetworkAvailable(this)){//判斷網絡是否有效


			if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){

				String sdpath = Environment.getExternalStorageDirectory() + "/";
				String	mSavePath = sdpath + "download/";//文件的下載路徑
				UpdateVersion updateManager = new UpdateVersion(this,  
						"http://192.168.8.227:8080/manyiApp/UpdateVersion.xml", mSavePath);  
				updateManager.checkUpdate(); 
				
			}else{
				Toast.makeText(this, "SD卡不可用", 1).show();
				Log.i("TAG", "11213");
			}
		}else{
			Toast.makeText(this, "網絡沒有連接", 1).show();
		}

	} 
	public boolean isNetworkAvailable(Context context) { 
			ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);   
		NetworkInfo info = cm.getActiveNetworkInfo();  //沒有網絡的時候會返回 null
		Log.i("TAG", "INFOddd");
		if (info == null || !cm.getBackgroundDataSetting()) {  
			return false;   
		}else
			return true;   
	}
}


服務器端需要放置UpdateVersion.xml文件

 

 


	12
	BoilerAndroid_1.1
	http://192.168.8.227:8080/manyiApp/AndroidTest.apk
	1.增加收藏功能

	

url是服務器apk存放的路徑

 

服務器段工程結構

\

 

 

下載完成後點擊打開新版本
/**
* 安裝APK文件
*/
private void installApk() {
File apkfile = new File(mSavePath,Constant.appFileName);
if (!apkfile.exists()) {
return;
}
// 通過Intent安裝APK文件
Intent i = new Intent(Intent.ACTION_VIEW);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.parse("file://" + apkfile.toString()),
"application/vnd.android.package-archive");
mContext.startActivity(i);
android.os.Process.killProcess(android.os.Process.myPid());

}

 

如果沒有android.os.Process.killProcess(android.os.Process.myPid());最後不會提示完成、打開。
如果沒有i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);這一步的話,最後安裝好了,點打開,是不會打開新版本應用的。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved