AndroidAPP更新升级完整实现Demo(搭建本地服务器) .
来源:互联网 发布:c 浏览器源码 编辑:程序博客网 时间:2024/05/18 12:34
市场上的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>
<?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>
<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>
- 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);
- }
- }
- }
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();@Overrideprotected 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() {@Overridepublic void onClick(View v) {manager.compareVersion(MainActivity.this);}});}public class receiveVersionHandler extends Handler{@Overridepublic 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);}}}
- 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();*/
- }
- }
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文件。
上述操作结束后,服务器端就完全搭好了,可以开始测试升级流程。
- AndroidAPP更新升级完整实现Demo(搭建本地服务器)
- AndroidAPP更新升级完整实现Demo(搭建本地服务器) .
- tomcat搭建本地服务器 实现apk更新下载(Android )
- Android 中tomcat搭建本地服务器 实现apk更新下载
- Android 中tomcat搭建本地服务器 实现apk更新下载
- Android 中tomcat搭建本地服务器 实现apk更新下载
- 搭建本地SVN服务器完整流程
- 导航界面的搭建(完整demo)
- Mac简单实现服务器搭建(本地)与iOS调试
- 简单直播实现(一:创建本地rtmp服务器)Mac上搭建直播服务器Nginx+rtmp
- 本地CocoaPods版本更新升级
- 基于Quick-cocos2dx 2.2.3 的动态更新实现完整篇。(打包,服务器接口,模块自更新)
- 大陆AndroidApp开发者更新SDK
- 完整使用SSM框架(Spring SpringMVC Mybatis)搭建web服务器实现登录功能
- 本地Web服务器搭建
- 搭建Git本地服务器
- 搭建本地邮件服务器
- maven本地服务器搭建
- cmstop框架中顶级类总结
- 191. Number of 1 Bits
- 设计模式之观察者模式(关于OC中的KVO\KVC\NSNotification)
- Android学习笔记之AndroidManifest.xml文件解析
- pip安装lxml出错的问题解决
- AndroidAPP更新升级完整实现Demo(搭建本地服务器) .
- 同一个Activity中不同Fragment的数据传递
- Android 学习 2016.03.08
- java 遍历map 方法 集合 五种的方法
- kibana
- 关于接口和抽象类
- 检索所有正在运行的进程的列表
- C++中各大有名的科学计算库
- 顺序存储结构的插入与删除