欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

AndroidAPP更新升级完整实现Demo(搭建本地服务器),androidappdemo,Demo地址:http:

来源: 开发者 投稿于  被查看 7969 次 评论:74

AndroidAPP更新升级完整实现Demo(搭建本地服务器),androidappdemo,Demo地址:http:


市场上的Android应用都能够自动提示升级更新,这里就完整的来实现一下AndroidAPP,实现自动升级的功能。

Demo地址:http://download.csdn.net/detail/ericfantastic/9250609

效果图:


具体如何实现,其实不难,先看看流程:




本地AndroidApp必须要先有一个版本号用于标识当前版本,再从服务器获取服务器最新版本,进行相比较。


实现流程:

1、Manifest.xml添加联网权限,读写SD卡权限,版本号versionCode和版本名versionName,其中versionCode用来比较版本使用的变量,versionName为用于显示在界面上的版本字符串。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.eric.androidupdatedemo"
    android:versionCode="1"
    android:versionName="01.00.01" >
	<uses-permission android:name='android.permission.INTERNET'/>	<!-- 联网权限 -->
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  <!-- 写入SD卡权限 -->
	<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>	<!-- 在SD卡中创建和删除文件的权限 -->
    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="14" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

2、activity_main.xml布局文件,简单的几个控件。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.eric.androidupdatedemo.MainActivity" >

    <TextView
        android:id="@+id/textview_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    
	<Button 
	    android:id="@+id/button_id"
	    android:layout_width="fill_parent"
	    android:layout_height="40dp"
	    android:layout_below="@id/textview_id"
	    android:textColor="#FFF"
	    android:text="检查更新"
	    android:background="@drawable/buttonbg"
	    />
	<ProgressBar 
	    android:id="@+id/progressBar_id"
	    style="@android:style/Widget.ProgressBar.Horizontal"  
	    android:layout_width="match_parent"
	    android:layout_height="40dp"
	    android:layout_below="@id/button_id"
	    android:layout_marginTop="10dp"
	    android:visibility="gone"/>
</RelativeLayout>

3、MainActivity.java界面初始化,调用更新类的方法,刷新页面数据。

package com.eric.androidupdatedemo;

import java.io.File;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends Activity {
	private TextView textView;
	public static int version,serverVersion;
	public static String versionName,serverVersionName,downloadResult;
	private Button btn;
	private ProgressBar proBar;
	public static receiveVersionHandler handler;
	private UpdateManager manager = UpdateManager.getInstance();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		textView = (TextView) findViewById(R.id.textview_id);
		btn = (Button) findViewById(R.id.button_id);
		proBar=(ProgressBar)findViewById(R.id.progressBar_id);
		
		Context c = this;
		version = manager.getVersion(c);
		versionName = manager.getVersionName(c);
		
		textView.setText("当前版本号:"+version+"\n"+"当前版本名:"+versionName);
		
		handler = new receiveVersionHandler();
		
		//检查更新按钮点击事件
		btn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				manager.compareVersion(MainActivity.this);
			}
		});
	}
	
	
	public class receiveVersionHandler extends Handler{
		@Override
		public void handleMessage(Message msg) {
		   proBar.setProgress(msg.arg1);
		   proBar.setVisibility(R.id.button_id);
	       textView.setText("下载进度:"+msg.arg1);
	       if(msg.arg1 == 100){
	    	   Intent intent = new Intent(Intent.ACTION_VIEW); 
		       String path = Environment.getExternalStorageDirectory()+"/AndroidUpdateDemo.apk";
		       intent.setDataAndType(Uri.fromFile(new File(path)), 
		    		   "application/vnd.android.package-archive");   
		       startActivity(intent);
	       }
	       proBar.setVisibility(R.id.button_id);
		}

	}
}

4、UpdateManager.java更新工具类,包含获取本地版本信息,服务器版本信息,下载apk文件等方法。

package com.eric.androidupdatedemo;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.R.integer;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

/*
 *@author Eric 
 *@2015-11-7上午8:03:31
 */
public class UpdateManager {
	private static UpdateManager manager = null;
	private UpdateManager(){}
	public static UpdateManager getInstance(){
		manager = new UpdateManager();
		return manager;
	}
	
	//获取版本号
	public int getVersion(Context context){
		int version = 0;
		try {  
			version = context.getPackageManager().getPackageInfo(  
                    "com.eric.androidupdatedemo", 0).versionCode;  
        } catch (Exception e) {  
        	 System.out.println("获取版本号异常!");
        }  
		return version;
	}
	
	//获取版本名
	public String getVersionName(Context context){
		String versionName = null;
		try {
			versionName = context.getPackageManager().getPackageInfo(
					"com.eric.androidupdatedemo", 0).versionName;
		} catch (Exception e) {
			 System.out.println("获取版本名异常!");
		}
		return versionName;
	}
	
	//获取服务器版本号
	public String getServerVersion(){
		String serverJson = null;
		byte[] buffer = new byte[128];
		
		try {
			URL serverURL = new URL("http://192.168.226.106/ver.aspx");
			HttpURLConnection connect = (HttpURLConnection) serverURL.openConnection();
			BufferedInputStream bis = new BufferedInputStream(connect.getInputStream());
			int n = 0;
			while((n = bis.read(buffer))!= -1){
				serverJson = new String(buffer);
			}
		} catch (Exception e) {
			System.out.println("获取服务器版本号异常!"+e);
		}
		
		return serverJson;
	}	
	
	//比较服务器版本与本地版本弹出对话框
	public boolean compareVersion(Context context){
		
		final Context contextTemp = context;
		
		new Thread(){
			public void run() {
				Looper.prepare();
				String serverJson = manager.getServerVersion();
				
				//解析Json数据
				try {
					JSONArray array = new JSONArray(serverJson);
					JSONObject object = array.getJSONObject(0);
					String getServerVersion = object.getString("version");
					String getServerVersionName = object.getString("versionName");
					
					MainActivity.serverVersion = Integer.parseInt(getServerVersion);
					MainActivity.serverVersionName = getServerVersionName;
					
					if(MainActivity.version < MainActivity.serverVersion){
						//弹出一个对话框
			            AlertDialog.Builder builder  = new Builder(contextTemp);  
			            builder.setTitle("版本更新" ) ;  
			            builder.setMessage("当前版本:"+MainActivity.versionName
			            		+"\n"+"服务器版本:"+MainActivity.serverVersionName ) ;  
			            builder.setPositiveButton("立即更新",new DialogInterface.OnClickListener() {  
			                   @Override  
			                   public void onClick(DialogInterface dialog, int arg1) { 
			                       //开启线程下载apk
			                	   new Thread(){
			                		   public void run() {
			                			   Looper.prepare();
			                			   downloadApkFile(contextTemp);
			                			   Looper.loop();
			                		   };
			                	   }.start();
			                   }  
			               });  
			            builder.setNegativeButton("下次再说", null);  
			            builder.show();
					}else{
			            AlertDialog.Builder builder  = new Builder(contextTemp);  
			            builder.setTitle("版本信息" ) ;  
			            builder.setMessage("当前已经是最新版本" ) ;  
			            builder.setPositiveButton("确定",null);  
			            builder.show();
					}
				} catch (JSONException e) {
					e.printStackTrace();
					System.out.println("获取服务器版本线程异常!"+e);
				}
				
				Looper.loop();
			};
			
		}.start();
		
		
		
		
		
		return false;
	}
	
	
	//下载apk文件
	public void downloadApkFile(Context context){
		String savePath = Environment.getExternalStorageDirectory()+"/AndroidUpdateDemo.apk";
		String serverFilePath = "http://192.168.226.106/AndroidUpdateDemo.png";
		try {
			if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){  
				URL serverURL = new URL(serverFilePath);
				HttpURLConnection connect = (HttpURLConnection) serverURL.openConnection();
				BufferedInputStream bis = new BufferedInputStream(connect.getInputStream());
				File apkfile = new File(savePath);
				BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(apkfile));
				
				int fileLength = connect.getContentLength();
				int downLength = 0;
				int progress = 0;
				int n;
				byte[] buffer = new byte[1024];
				while((n=bis.read(buffer, 0, buffer.length))!=-1){
					bos.write(buffer, 0, n);
					downLength +=n;
					progress = (int) (((float) downLength / fileLength) * 100);
					Message msg = new Message();
					msg.arg1 = progress;
					MainActivity.handler.sendMessage(msg);
					//System.out.println("发送"+progress);
				}
				bis.close();
				bos.close();
				connect.disconnect();
	        } 
			
		} catch (Exception e) {
			System.out.println("下载出错!"+e);
		}
		

		/*AlertDialog.Builder builder  = new Builder(context);  
        builder.setTitle("下载apk" ) ;  
        builder.setMessage("正在下载" ) ;  
        builder.setPositiveButton("确定",null);  
        builder.show();*/
		
		
		
	}
}

具体实现都在UpdateManager类中,详细说明一下,其中,

getVersion(Context context)、getVersionName(Context context)本地版本的获取很简单一看就懂;

getServerVersion()服务器版本的获取:读取服务器目录下的ver.aspx文件,返回json字符串;

compareVersion(Context context)比较版本:启动线程,读取json字符串,并解析服务器版本赋值到serverVersion中,并且比较本地版本和服务器版本,如果低于服务器版本,就启动新线程下载apk文件;

downloadApkFile(Context context)下载apk文件:设置文件保存路径,服务器访问路径,通过HTTP协议下载文件,这里测试的时候,apk文件无法下载,故将服务器的apk修改扩展名为png格式,下载完成后保存为apk文件。










搭建本地Web服务器:

1、开启功能:控制面板-> 程序-> 程序和功能 -> 打开或关闭Windows功能,将“Internet信息服务”下的所有功能都打开。


2、设置防火墙:控制面板-> 系统安全 -> Windows防火墙 -> 允许程序通过Windows防火墙,勾选“万维网服务(HTTP)”。


3、以上步骤完成后,web服务器就搭好了,可以win+R,运行cmd,键入ipconfig /all ,查看本机IP地址,打开浏览器输入地址ip地址测试一下,如果打开的是IIS7网页,说明成功了。

然后就是将新版本的apk放到服务器目录下,一般是系统盘目录下C:\inetpub\wwwroot文件夹中。

放置两个文件,一个是2.0版本的apk文件,一个是ver.aspx文件用于获取服务器版本的json字符串,里面的内容为:[{"appname":"AndroidUpdateDemo","apkname":"AndroidUpdateDemo.apk","versionName":"02.00.01","version":"2"}] 。

由于测试时候apk文件无法直接下载,想了个办法将apk文件扩展名改为png,在Android端下载完成后把它在保存为apk文件。



上述操作结束后,服务器端就完全搭好了,可以开始测试升级流程。


用户评论