先不讲那么多看效果图:

下面来讲解一些更新CODE,原理大家都知道,不废话,直接上代码。里面有一些是我自己做的测试例子,所以大家可以直接删掉就好了

第一个:activity_main.xml

 <?xml version="1.0" encoding="utf-8"?>
<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.example.fucm.wms_jianh.MainActivity"> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_sq"
android:id="@+id/btn_sq"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="197dp" /> <ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/listView"
android:layout_toStartOf="@+id/btn_sq"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true" /> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="更新"
android:id="@+id/button"
android:layout_below="@+id/btn_sq"
android:layout_centerHorizontal="true"/> </RelativeLayout>

第二个:MainActivity.java

package com.example.fucm.wms_jianh;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView; import org.json.JSONArray;
import org.json.JSONObject; import java.util.ArrayList;
import java.util.List; import MyClass.HttpHelper;
import MyClass.SoftUpdate; public class MainActivity extends Activity implements OnClickListener{
Button btn1,btn2;
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads().detectDiskWrites().detectAll() // or
// .detectAll()
// for all
// detectable
// problems
.penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
.penaltyLog().penaltyDeath().build());
setContentView(R.layout.activity_main);
btn1 = (Button) findViewById(R.id.btn_sq);
btn2 = (Button) findViewById(R.id.button);
btn1.setOnClickListener(this);
listView = (ListView)findViewById(R.id.listView);
btn2.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
SoftUpdate manager = new SoftUpdate(MainActivity.this);
// 检查软件更新
manager.checkUpdate();
}
});
}
}

第三个:HttpHelper.java

package MyClass;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject; import java.io.IOException; public class HttpHelper {
private static final int REQUEST_TIMEOUT = * ;
private static final int SO_TIMEOUT = * ; public static String sendHttpRequest(String pUrl) {
String result;
result = doGet(pUrl);
return result;
}
public static String doGet(String url) {
String result = null;
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, REQUEST_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
HttpClient httpClient = new DefaultHttpClient(httpParams);
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse response = httpClient.execute(httpGet); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { }
result = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (IOException e) {
//Log.i("GET", "Bad Request!");
}
return result;
}
public static String GetJsonListValue(String str) {
String strError="";
try {
JSONObject json1 = new JSONObject(str);
JSONObject tmp = json1.getJSONObject("d");
return tmp.getString("a");
} catch (Exception e) {
strError=e.toString();
}
return strError; } public static JSONArray GetJsonValue(String str) { try {
JSONArray json1 = new JSONArray(str);
return json1;
} catch (Exception e) {
//strError=e.toString();
}
return null;
}
}

第四个:SoftUpdate.java

package MyClass;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast; import com.example.fucm.wms_jianh.R; import org.json.JSONArray; 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; /**
* Created by fucm on 2016-07-06.
*/
public class SoftUpdate { /* 下载中 */
private static final int DOWNLOAD = ;
/* 下载结束 */
private static final int DOWNLOAD_FINISH = ;
/* 保存解析的XML信息 */
private Long str_version;
private String str_appname;
private String str_downurl;
/* 下载保存路径 */
private String mSavePath;
/* 记录进度条数量 */
private int progress;
/* 是否取消更新 */
private boolean cancelUpdate = false; private Context mContext;
/* 更新进度条 */
private ProgressBar mProgress;
private Dialog mDownloadDialog; public SoftUpdate(Context context)
{
this.mContext = context;
} 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()
{
if (isUpdate())
{
// 显示提示对话框
showNoticeDialog();
} else
{
Toast.makeText(mContext, R.string.soft_update_no, Toast.LENGTH_LONG).show();
}
} /**
* 检查软件是否有更新版本
*
* @return
*/
private boolean isUpdate(){
// 获取当前软件版本
int versionCode = getVersionCode(mContext);
//通过服务器获得版本号
try {
String str = HttpHelper.sendHttpRequest("http://127.0.0.1/Service1.svc/get_version");
JSONArray json1 =HttpHelper.GetJsonValue(str);
str_version=json1.getLong();
str_appname=json1.getString();
str_downurl=json1.getString();
if (str_version > versionCode) {
return true;
}
}
catch (Exception e) {
//strError=e.toString();
}
return false;
} /**
* 获取软件版本号
*
* @param context
* @return
*/
private int getVersionCode(Context context)
{
int versionCode = ;
try
{
// 获取软件版本号,对应AndroidManifest.xml下android:versionCode
versionCode = context.getPackageManager().getPackageInfo("com.example.fucm.wms_jianh", ).versionCode;
} catch (PackageManager.NameNotFoundException e)
{
e.printStackTrace();
}
return versionCode;
} /**
* 显示软件更新对话框
*/
private void showNoticeDialog()
{
// 构造对话框
AlertDialog.Builder builder = new Builder(mContext);
builder.setTitle(R.string.soft_update_title);
builder.setMessage(R.string.soft_update_info);
// 更新
builder.setPositiveButton(R.string.soft_update_updatebtn, new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
// 显示下载对话框
showDownloadDialog();
}
});
// 稍后更新
builder.setNegativeButton(R.string.soft_update_later, 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(R.string.soft_updating);
// 给下载对话框增加进度条
final LayoutInflater inflater = LayoutInflater.from(mContext);
View v = inflater.inflate(R.layout.soft_update, null);
mProgress = (ProgressBar) v.findViewById(R.id.update_progress);
builder.setView(v);
// 取消更新
builder.setNegativeButton(R.string.soft_update_cancel, 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();
} /**
* 下载文件线程
*
* @author coolszy
*@date 2012-4-26
*@blog http://blog.92coding.com
*/
private class downloadApkThread extends Thread
{
@Override
public void run()
{
try
{
// 判断SD卡是否存在,并且是否具有读写权限
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
// 获得存储卡的路径
String sdpath = Environment.getExternalStorageDirectory() + "/";
mSavePath = sdpath + "download";
URL url= new URL(str_downurl);
// 创建连接
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, str_appname);
FileOutputStream fos = new FileOutputStream(apkFile);
int count = ;
// 缓存
byte buf[] = new byte[];
// 写入到文件中
do
{
int numread = is.read(buf);
count += numread;
// 计算进度条位置
progress = (int) (((float) count / length) * );
// 更新进度
mHandler.sendEmptyMessage(DOWNLOAD);
if (numread <= )
{
// 下载完成
mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
break;
}
// 写入文件
fos.write(buf, , 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, str_appname);
if (!apkfile.exists())
{
return;
}
// 通过Intent安装APK文件
Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
mContext.startActivity(i);
} }

第五个:soft_update.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/update_progress"/>
</LinearLayout>

第六个:AndroidManifest.xml(创建的时候自带)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.fucm.wms_jianh"
android:versionCode=""
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".RwdMxActivity">
</activity>
</application> </manifest>

更正一下:有的APK的版本信息是在build.gradle这个里面

第七个:strings.xml(创建的时候自带)

<resources>
<string name="app_name">WMS_JIANH</string>
<string name="btn_sq">任务索取</string>
<string name="soft_update_no">已经是最新版本</string>
<string name="soft_update_title">软件更新</string>
<string name="soft_update_info">检测到新版本,立即更新吗</string>
<string name="soft_update_updatebtn">更新</string>
<string name="soft_update_later">稍后更新</string>
<string name="soft_updating">正在更新</string>
<string name="soft_update_cancel">取消</string>
</resources>

第八个:看看工程结构

提供源码下载:https://yunpan.cn/cBFKmGJKqiLct  访问密码 6e01

Android Studio实现APK的更新、下载、安装的更多相关文章

  1. [Android Studio 权威教程]Windows下安装Android Studio

    从AS 0.5版本号開始使用.也是AS的推行者,在ApkBus公布的第一篇Android Studio Perview 2 获得了50K的浏览,1800多条回复下载. 在我的[Android Stud ...

  2. android studio gradle 两种更新方法更新

    android studio gradle 两种更新方法更新 第一种.Android studio更新 第一步:在你所在项目文件夹下:你项目根目录gradlewrappergradle-wrapper ...

  3. android studio从1.5更新到2.0后terminal无法运行gradle命令,提示无法找到gradle命令

    android studio从1.5更新到2.0后terminal无法运行gradle命令,提示无法找到gradle命令. 'gradle' 不是内部或外部命令,也不是可运行的程序 或批处理文件. 设 ...

  4. Android Studio 每次运行都会再下载一遍,修改

    Android Studio 每次运行都会再下载一遍 把 gradle 设置 use local gradle distribution

  5. Android tips(八)-->Android Studio打包apk,aar,jar包

    文本我们将讲解android studio打包apk,aar,jar包的相关知识.apk包就是android系统的安装包,这里没什么好说的,aar包是android中独有的类库包,而jar包是java ...

  6. Android Studio 打包APK时,出现3个或多个APK

    Android Studio 打包APK时,原来只会出现一个apk,结果现在出现3个apk,仔细检查了一下项目文件发现: Android Studio 的 buid.gradle文件里有个配置项被更改 ...

  7. Android Studio打包apk,aar,jar包

    转载请标明出处:一片枫叶的专栏 文本我们将讲解android studio打包apk,aar,jar包的相关知识.apk包就是android系统的安装包,这里没什么好说的,aar包是android中独 ...

  8. Android Studio Analyze APK 一直显示 Parsing Manifest探因及解决

    一.背景 大家都知道,Android Studio开发工具自带了Analyze Apk,可以很方便的分析Apk文件.具体位于菜单build >> Analyze APK...路径下,点击后 ...

  9. Android程序版本更新--通知栏更新下载安装(转)

    Android应用检查版本更新后,在通知栏下载,更新下载进度,下载完成自动安装,效果图如下: 检查当前版本号 AndroidManifest文件中的versionCode用来标识版本,在服务器放一个新 ...

随机推荐

  1. Optimistic Concurrency VS. Pessimistic Concurrency Control

    原创地址:http://www.cnblogs.com/jfzhu/p/4009918.html 转载请注明出处   (一)为什么需要并发控制机制 并发控制机制是为了防止多个用户同时更改同一条数据,也 ...

  2. DataTable转Entity(Emit版)

    public static List<T> ToList<T>(DataTable dt)        {            List<T> list = n ...

  3. 精通visual c++指纹模式识别系统算法及实现

    通过学习,掌握以下几个问题: 1.核心算法,并且向GVF衍生: 2.核心库封装的方法 2016年11月16日06:52:51 昨日实现了梯度场和频率场的计算.最大的感觉就是建立基础代码库的重要性. 如 ...

  4. OleDB Destination 用法

    第一部分:简介 OleDB Destination component 是将数据流load 到destination,共有5种Data Access Mode,一般的Destination compo ...

  5. SQL Server 默认跟踪(Default Trace)

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 基础知识(Rudimentary Knowledge) 查看默认跟踪信息(Default Tr ...

  6. 解读sencha touch移动框架的核心架构(二)

    本来这行要详解Ext.extend的,但是发现网站有很详细的,那么就跳过去吧 为保持一个系列的分析,还是先搬过来吧,下章开始分析Ext4.0的新架构 在Java中,我们在实现继承的时候存在下面几个事实 ...

  7. Minor【 PHP框架】2.第一个应用与请求的生命周期

    框架Github地址:github.com/Orlion/Minor (如果觉得还不错给个star哦(^-^)V) 框架作者: Orlion 知乎:https://www.zhihu.com/peop ...

  8. mpi4py实践

    版权声明:本文为博主原创文章,未经博主允许不得转载. 1.概述 MPI(Message Passing Interface),消息传递接口,是一个标准化和轻便的能够运行在各种各样并行计算机上的消息传递 ...

  9. MVC4做网站Demo进行重写的问题。

    自从学习MVC4开始,边学边写这个demo,写了也有一年多了.开始觉得是一个小例子把所有的代码都写在一个项目中,边写边改越写越混乱,越到后来很多东西自己都理不清了.后来在群里跟 @怒放 在讨论这个问题 ...

  10. FragmentPagerAdapter+ViewPager实现Tab切换效果

    1.Activity  加载布局文件,获取Viewpager控件   给ViewPager填充适配器. import android.app.ActionBar; import android.app ...