open source
This commit is contained in:
+300
@@ -0,0 +1,300 @@
|
||||
package layaair.autoupdateversion;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
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.Locale;
|
||||
import java.util.Random;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
import android.webkit.ValueCallback;
|
||||
import layaair.autoupdateversion.data.VersionData;
|
||||
import layaair.game.config.config;
|
||||
|
||||
public class AutoUpdateAPK {
|
||||
//static public final String CHECK_VERSION_URL = "http://localhost:80/setuptest_update.xml";
|
||||
//static public final String APK_DOWNLOAD_PATH = "mnt/sdcard/";
|
||||
//static public final String DOWNLOAD_APK_NAME = "autoupdate.apk";
|
||||
|
||||
static private final int UPDATE_CHECKCOMPLETED = 1;
|
||||
static private final int UPDATE_DOWNLOADING = 2;
|
||||
static private final int UPDATE_DOWNLOAD_ERROR = 3;
|
||||
static private final int UPDATE_DOWNLOAD_COMPLETED = 4;
|
||||
static private final int UPDATE_DOWNLOAD_CANCELED = 5;
|
||||
|
||||
static private AutoUpdateAPK s_instance;
|
||||
|
||||
private layaair.autoupdateversion.IUpdateCallback m_callback;
|
||||
private String m_szDownloadAPKName;// = DOWNLOAD_APK_NAME;
|
||||
private String m_szDownloadPath;
|
||||
private int m_iVersionCode = 0;
|
||||
private int m_iProgressValue = 0;
|
||||
private Context m_context = null;
|
||||
private VersionData m_versionData = new VersionData();
|
||||
private boolean m_hasNewVersion = false;
|
||||
private boolean m_hasCanceled = false;
|
||||
private ValueCallback<Integer> m_pCallback;
|
||||
|
||||
public AutoUpdateAPK(Context p_context,ValueCallback<Integer> callback)
|
||||
{
|
||||
m_pCallback=callback;
|
||||
s_instance = this;
|
||||
m_callback = new UpdateCallback();
|
||||
m_context = p_context;
|
||||
this.m_szDownloadAPKName = config.GetInstance().getProperty("UpdateAPKFileName");
|
||||
this.m_szDownloadPath = config.GetInstance().getProperty("UpdateDownloadPath");
|
||||
setVersionCode(p_context);
|
||||
downloadVersionXML(config.GetInstance().getProperty("ApkUpdateUrl"));
|
||||
}
|
||||
public static void DelInstance()
|
||||
{
|
||||
s_instance=null;
|
||||
}
|
||||
|
||||
static public AutoUpdateAPK getInstance() {
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
public void cancelDownload() {
|
||||
m_hasCanceled = true;
|
||||
}
|
||||
|
||||
private static class UpdateHandle extends Handler
|
||||
{
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
AutoUpdateAPK that=AutoUpdateAPK.getInstance();
|
||||
switch (msg.what) {
|
||||
case UPDATE_CHECKCOMPLETED:
|
||||
that.m_callback.checkUpdateCompleted(that.getHasNewVersion(),
|
||||
that.m_versionData.getName() +that.m_versionData.getVersion());
|
||||
break;
|
||||
case UPDATE_DOWNLOADING:
|
||||
that.m_callback.downloadProgressChanged(that.m_iProgressValue);
|
||||
break;
|
||||
case UPDATE_DOWNLOAD_ERROR:
|
||||
onUpdateEnd(1);
|
||||
that.m_callback.downloadCompleted(false, msg.obj.toString());
|
||||
break;
|
||||
case UPDATE_DOWNLOAD_COMPLETED:
|
||||
onUpdateEnd(0);
|
||||
that.m_callback.downloadCompleted(true, "");
|
||||
break;
|
||||
case UPDATE_DOWNLOAD_CANCELED:
|
||||
that.m_callback.downloadCanceled();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void onUpdateEnd(int ecode)
|
||||
{
|
||||
if (ecode == 2 || ecode == 3) {
|
||||
s_instance.m_pCallback.onReceiveValue(1);
|
||||
} else {
|
||||
s_instance.m_pCallback.onReceiveValue(0);
|
||||
}
|
||||
}
|
||||
|
||||
Handler updateHandler = new UpdateHandle();
|
||||
|
||||
public void updateAPK() {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
|
||||
intent.setDataAndType(
|
||||
Uri.fromFile(new File(m_szDownloadPath, m_szDownloadAPKName)),
|
||||
"application/vnd.android.package-archive");
|
||||
m_context.startActivity(intent);
|
||||
}
|
||||
|
||||
public void downloadAPK() {
|
||||
new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
URL url = new URL(m_versionData.getDownloasURL());
|
||||
Log.i("","update apk url:"+url.toString());
|
||||
HttpURLConnection conn = (HttpURLConnection) url
|
||||
.openConnection();
|
||||
conn .setRequestProperty("Accept-Encoding", "identity");
|
||||
conn.setConnectTimeout(6 * 1000);
|
||||
conn.connect();
|
||||
// if (conn.getResponseCode() != 200)
|
||||
// throw new RuntimeException("请求url失败");
|
||||
|
||||
int length = conn.getContentLength();
|
||||
InputStream is = conn.getInputStream();
|
||||
|
||||
File fileAPK = new File(m_szDownloadPath,
|
||||
m_szDownloadAPKName);
|
||||
|
||||
if (fileAPK.exists()) {
|
||||
if(fileAPK.delete())
|
||||
{
|
||||
Log.i("","删除apk成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.e("","删除apk失败");
|
||||
}
|
||||
}
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(fileAPK);
|
||||
|
||||
int count = 0;
|
||||
byte buf[] = new byte[512];
|
||||
|
||||
int nLastProg=0;
|
||||
do {
|
||||
|
||||
int numread = is.read(buf);
|
||||
count += numread;
|
||||
m_iProgressValue = (int) (((float) count / length) * 100);
|
||||
if(m_iProgressValue!=nLastProg)
|
||||
{
|
||||
updateHandler.sendMessage(updateHandler.obtainMessage(UPDATE_DOWNLOADING));
|
||||
nLastProg = m_iProgressValue;
|
||||
}
|
||||
if (numread <= 0) {
|
||||
updateHandler.sendEmptyMessage(UPDATE_DOWNLOAD_COMPLETED);
|
||||
break;
|
||||
}
|
||||
fos.write(buf, 0, numread);
|
||||
} while (!m_hasCanceled);
|
||||
if (m_hasCanceled) {
|
||||
updateHandler.sendEmptyMessage(UPDATE_DOWNLOAD_CANCELED);
|
||||
}
|
||||
fos.close();
|
||||
is.close();
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
updateHandler.sendMessage(updateHandler.obtainMessage(UPDATE_DOWNLOAD_ERROR, e.getMessage()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
updateHandler.sendMessage(updateHandler.obtainMessage(UPDATE_DOWNLOAD_ERROR, e.getMessage()));
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
public void setVersionCode(Context p_context) {
|
||||
try {
|
||||
m_iVersionCode = p_context.getPackageManager().getPackageInfo(
|
||||
p_context.getPackageName(), 0).versionCode;
|
||||
} catch (NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void downloadVersionXML(final String p_szURL) {
|
||||
this.setHasNewVersion(false);
|
||||
new Thread() {
|
||||
// ***************************************************************
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Random rnd;
|
||||
rnd = new Random();
|
||||
String url=p_szURL+"?r="+rnd.nextInt();
|
||||
Log.i("","update url="+url);
|
||||
String verjson = NetHelper
|
||||
.httpStringGet(url);
|
||||
parseVersionXMLFromString(verjson);
|
||||
if (m_versionData.getVersionCode() > m_iVersionCode) {
|
||||
setHasNewVersion(true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("","自动更新失败,应该是无法连接到"+p_szURL);
|
||||
}
|
||||
updateHandler.sendEmptyMessage(UPDATE_CHECKCOMPLETED);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
public boolean parseVersionXMLFromString(String p_szContent) {
|
||||
DocumentBuilder db = null;
|
||||
Document document = null;
|
||||
try {
|
||||
db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
} catch (ParserConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
InputStream in = new ByteArrayInputStream(p_szContent.getBytes());
|
||||
assert db != null;
|
||||
document = db.parse(in);
|
||||
} catch (SAXException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Element root = null;
|
||||
if (document != null) {
|
||||
root = document.getDocumentElement();
|
||||
}
|
||||
// System.out.println("根节点名称:"+root.getTagName()); //根节点名称
|
||||
return doParseVersionXML(root);
|
||||
}
|
||||
|
||||
@SuppressLint({ "NewApi", "NewApi", "NewApi", "NewApi", "NewApi" })
|
||||
private boolean doParseVersionXML(Element p_root) {
|
||||
if(p_root==null)return false;
|
||||
NodeList __ls = p_root.getChildNodes();
|
||||
Node node;
|
||||
for (int i = 0; i < __ls.getLength(); i++) {
|
||||
node = __ls.item(i);
|
||||
if (node.getNodeName().toLowerCase(Locale.ENGLISH).equals("versioncode")) {
|
||||
m_versionData.setVersionCode(Integer.parseInt(node
|
||||
.getTextContent()));
|
||||
continue;
|
||||
}
|
||||
if (node.getNodeName().toLowerCase(Locale.ENGLISH).equals("version")) {
|
||||
m_versionData.setVersion(node.getTextContent());
|
||||
continue;
|
||||
}
|
||||
if (node.getNodeName().toLowerCase(Locale.ENGLISH).equals("name")) {
|
||||
m_versionData.setName(node.getTextContent());
|
||||
continue;
|
||||
}
|
||||
if (node.getNodeName().toLowerCase(Locale.ENGLISH).equals("url")) {
|
||||
m_versionData.setDownloasURL(node.getTextContent());
|
||||
}
|
||||
}
|
||||
//给apk地址加个参数,防止服务器的缓存
|
||||
m_versionData.setDownloasURL(m_versionData.getDownloasURL()+"?vc="+m_versionData.getVersionCode());
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean getHasNewVersion() {
|
||||
return m_hasNewVersion;
|
||||
}
|
||||
|
||||
public void setHasNewVersion(boolean m_hasNewVersion) {
|
||||
this.m_hasNewVersion = m_hasNewVersion;
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return this.m_context;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package layaair.autoupdateversion;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AlertDialog.Builder;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
|
||||
public class DialogHelper {
|
||||
|
||||
public static void Confirm(Context ctx, CharSequence title, CharSequence message,
|
||||
CharSequence okText, OnClickListener oklistener, CharSequence cancelText,
|
||||
OnClickListener cancellistener) {
|
||||
AlertDialog.Builder builder = createDialog(ctx, title, message);
|
||||
builder.setPositiveButton(okText, oklistener);
|
||||
builder.setNegativeButton(cancelText, cancellistener);
|
||||
AlertDialog dlg = builder.create();
|
||||
dlg.setCanceledOnTouchOutside(false); //防止点到外面自动关掉对话框。
|
||||
dlg.show();
|
||||
}
|
||||
|
||||
private static AlertDialog.Builder createDialog(Context ctx, CharSequence title,
|
||||
CharSequence message) {
|
||||
AlertDialog.Builder builder = new Builder(ctx);
|
||||
builder.setMessage(message);
|
||||
if(title!=null)
|
||||
{
|
||||
builder.setTitle(title);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static AlertDialog.Builder createDialog(Context ctx,int titleId, int messageId) {
|
||||
AlertDialog.Builder builder = new Builder(ctx);
|
||||
builder.setMessage(messageId);
|
||||
builder.setTitle(titleId);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package layaair.autoupdateversion;
|
||||
|
||||
public interface IUpdateCallback {
|
||||
void checkUpdateCompleted(Boolean hasUpdate,
|
||||
CharSequence updateInfo);
|
||||
|
||||
void downloadProgressChanged(int progress);
|
||||
void downloadCanceled();
|
||||
void downloadCompleted(Boolean sucess, CharSequence errorMsg);
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package layaair.autoupdateversion;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URL;
|
||||
|
||||
public class NetHelper {
|
||||
|
||||
public static String httpStringGet(String url) throws Exception {
|
||||
return httpStringGet(url, "utf-8");
|
||||
}
|
||||
|
||||
public static String httpStringGet(String url, String enc) throws Exception {
|
||||
HttpURLConnection connection = null;
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
URL u = new URL( url );
|
||||
connection = (HttpURLConnection) u.openConnection();
|
||||
connection.setRequestMethod( "GET" );
|
||||
connection.setConnectTimeout( 5000 );
|
||||
connection.setReadTimeout( 5000 );
|
||||
InputStream in = connection.getInputStream();
|
||||
reader = new BufferedReader( new InputStreamReader( in ) );
|
||||
StringBuilder result = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
result.append( line );
|
||||
}
|
||||
return String.valueOf( result );
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ProtocolException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (connection != null) {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package layaair.autoupdateversion;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.util.Log;
|
||||
|
||||
public class UpdateCallback implements IUpdateCallback {
|
||||
|
||||
static private final String DIALOG_DOWNLOAD_ERROR_TITLE = "下载失败";
|
||||
static private final String DIALOG_DOWNLOAD_ERROR_MSG = "下载更新文件失败";
|
||||
static private final String DIALOG_DOWNLOAD_BUTTON_TRY = "重试";
|
||||
static private final String DIALOG_DOWNLOAD_BUTTON_CANCEL= "取消";
|
||||
|
||||
static private final String DIALOG_UPDATE_TITLE = "更新";
|
||||
static private final String DIALOG_UPDATE_MSG = "立刻更新[";
|
||||
static private final String DIALOG_UPDATE_MSGEND = "]吗?";
|
||||
static private final String DIALOG_UPDATE_PROGRESS= "更新进度";
|
||||
static private final String DIALOG_UPDATE_BUTTON_TRY = "开始更新";
|
||||
static private final String DIALOG_UPDATE_BUTTON_CANCEL= "取消更新";
|
||||
|
||||
ProgressDialog updateProgressDialog = null;
|
||||
public void downloadProgressChanged(int progress) {
|
||||
if (updateProgressDialog != null
|
||||
&& updateProgressDialog.isShowing()) {
|
||||
updateProgressDialog.setProgress(progress);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void downloadCompleted(Boolean sucess, CharSequence errorMsg) {
|
||||
if (updateProgressDialog != null
|
||||
&& updateProgressDialog.isShowing()) {
|
||||
updateProgressDialog.dismiss();
|
||||
}
|
||||
if (sucess) {
|
||||
if (AutoUpdateAPK.getInstance() != null)
|
||||
AutoUpdateAPK.getInstance().updateAPK();
|
||||
} else {
|
||||
if (AutoUpdateAPK.getInstance() == null)
|
||||
return ;
|
||||
DialogHelper.Confirm(AutoUpdateAPK.getInstance().getContext(),
|
||||
DIALOG_DOWNLOAD_ERROR_TITLE,
|
||||
DIALOG_DOWNLOAD_ERROR_MSG,
|
||||
DIALOG_DOWNLOAD_BUTTON_TRY,
|
||||
new DialogInterface.OnClickListener() {
|
||||
|
||||
public void onClick(DialogInterface dialog,
|
||||
int which) {
|
||||
AutoUpdateAPK.getInstance().downloadAPK();
|
||||
|
||||
}
|
||||
}, DIALOG_DOWNLOAD_BUTTON_CANCEL, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void downloadCanceled() {
|
||||
Log.i("", "download canceled");
|
||||
}
|
||||
|
||||
public void checkUpdateCompleted(Boolean hasUpdate, CharSequence updateInfo) {
|
||||
if (AutoUpdateAPK.getInstance() == null)
|
||||
return ;
|
||||
if (hasUpdate)
|
||||
{
|
||||
DialogHelper.Confirm(
|
||||
AutoUpdateAPK.getInstance().getContext(),
|
||||
DIALOG_UPDATE_TITLE,
|
||||
DIALOG_UPDATE_MSG + updateInfo+ DIALOG_UPDATE_MSGEND,DIALOG_UPDATE_BUTTON_TRY,
|
||||
new DialogInterface.OnClickListener() {
|
||||
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
updateProgressDialog = new ProgressDialog(AutoUpdateAPK.getInstance().getContext());
|
||||
updateProgressDialog.setMessage(DIALOG_UPDATE_PROGRESS);
|
||||
updateProgressDialog.setIndeterminate(false);
|
||||
updateProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
updateProgressDialog.setMax(100);
|
||||
updateProgressDialog.setProgress(0);
|
||||
updateProgressDialog.setCancelable(false);
|
||||
updateProgressDialog.setCanceledOnTouchOutside(false);
|
||||
updateProgressDialog.show();
|
||||
|
||||
AutoUpdateAPK.getInstance().downloadAPK();
|
||||
}
|
||||
}, DIALOG_UPDATE_BUTTON_CANCEL,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
AutoUpdateAPK.onUpdateEnd(3);
|
||||
}
|
||||
}
|
||||
);
|
||||
}else{
|
||||
AutoUpdateAPK.onUpdateEnd(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package layaair.autoupdateversion.data;
|
||||
|
||||
public class VersionData {
|
||||
private int m_iVersionCode;
|
||||
private String m_szName;
|
||||
private String m_szVersion;
|
||||
private String m_szDownloasURL;
|
||||
|
||||
public int getVersionCode() {
|
||||
return m_iVersionCode;
|
||||
}
|
||||
|
||||
public void setVersionCode(int p_iVersionCode) {
|
||||
this.m_iVersionCode = p_iVersionCode;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return m_szName;
|
||||
}
|
||||
|
||||
public void setName(String p_szName) {
|
||||
this.m_szName = p_szName;
|
||||
}
|
||||
|
||||
public String getDownloasURL() {
|
||||
return m_szDownloasURL;
|
||||
}
|
||||
|
||||
public void setDownloasURL(String p_szDownloasURL) {
|
||||
this.m_szDownloasURL = p_szDownloasURL;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return m_szVersion;
|
||||
}
|
||||
|
||||
public void setVersion(String m_szVersion) {
|
||||
this.m_szVersion = m_szVersion;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user