实现原理:通过向服务器端发送请求,获取服务端的版本信息,然后再与本机上的软件进行比对,如果版本不一致的话,那就得更新版本!
首先需要一个打开的欢迎界面:
在这个欢迎界面打开的时候就要判断此软件的版本是否要更新!
需要说明的是在服务器端这边的时候,发给客户顿的是一个json数据,为了更加明确的说明一下,服务端的大概代码是这样的:
import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import cn.cxrh.daomain.mobile;
public class MobileSafeServlet extends HttpServlet {
File file = null;
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub
List mobiles.add(new mobile("2.0","http://192.168.128.1:8080/safemobile_server/software/qqliulanqi.apk","小白马提醒您,软件是否更新!^_^!"));
JSONArray json = JSONArray.fromObject(mobiles); resp.getOutputStream().write(json.toString().getBytes("utf-8"));
}
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doGet(req, resp); }
}
|
注意:这里要说明的是,在服务端进行json数据的发送的时候,还需要用到json的jar包!
然后就是客户端这边的处理了!
首先是需要的一个utils工具类:
package com.example.safemobile_test.utils;
import java.io.ByteArrayOutputStream; 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.ProtocolException; import java.net.URL;
import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject;
import android.app.ProgressDialog; import android.content.Context; import android.os.Environment; import android.util.Log;
import com.example.safemobile_test.daomain.Info;
public class Utils {
/** * 读取服务端发过来的输入流信息,并把它转化为字符串 * @param is 输入流 * @return * @throws Exception */ public static String readJson(InputStream is) throws Exception { ByteArrayOutputStream bao = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1;
while((len = is.read(buffer)) != -1) { bao.write(buffer, 0, len); } is.close(); bao.close();
return new String(bao.toByteArray());
} /** * 用json解析来获取服务端的信息 * @param path 这个得路径指的是需要访问服务器端的地址 * @return 返回的是一个javabean的对象 * @throws Exception */ public static Info getServerInfo(String path) throws MalformedURLException,ProtocolException,JSONException,IOException,Exception { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); int code = conn.getResponseCode();
if(code == 200) { InputStream is = conn.getInputStream();
JSONArray jsonArray = new JSONArray(readJson(is)); Info info = new Info();
for(int i=0; i < jsonArray.length(); i++) { JSONObject object = jsonArray.getJSONObject(i); info.setVersion(object.getString("version")); info.setDesc(object.getString("desc")); info.setPath(object.getString("path")); Log.i("Utils", object.getString("version"));
} return info; } return null;
} /** * 从服务端下载需要更新的软件 * @param file 要存放到sdcard的文件的对象 * @param path 要访问服务端的地址 * @param pd 进度条 * @return 返回存放文件的文件对象 */ public static File updateSoft(File file,String path,ProgressDialog pd) {
try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); int fileLength = conn.getContentLength(); pd.setMax(fileLength); int code = conn.getResponseCode(); if(code == 200) { FileOutputStream fos = new FileOutputStream(file);
InputStream is= conn.getInputStream(); byte[] buffer = new byte[1024];
int len = -1; int total = 0;
while((len = is.read(buffer)) != -1) { total += len; fos.write(buffer, 0, len); pd.setProgress(total); } fos.close(); is.close(); pd.dismiss(); return file; } } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
returnnull; } }
|
然后就是版本更新的主要代码,也是主类的代码:
package com.example.safemobile_test;
import java.io.File; import java.io.IOException; import java.net.MalformedURLException;
import org.apache.http.ProtocolException; import org.json.JSONException;
import com.example.safemobile_test.daomain.Info; import com.example.safemobile_test.utils.Utils; import com.example.service.BlackNumberService;
import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.Log; import android.widget.TextView; import android.widget.Toast;
public class splashactivity extends Activity { protected static final int URL_ERROR = 1; protected static final int PROTOCOL_ERROR = 2; protected static final int JSON_PARSER_ERROR = 3; protected static final int INTERNET_ERROR = 4; protected static final int READ_DATA_ERROR = 5; protected static final int LOAD_MAIN = 6; protected static final int SHOW_DIALOG = 7; protected static final int UPDADTE_SOFT = 8; protected static final int DOWNLOAD_FILE_FAILURE = 9; private TextView tv_splash_version; private Handler handler; private long startTime = 0; private Info info = null; private ProgressDialog pd; private File file;
@Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); tv_splash_version = (TextView) this.findViewById(R.id.te_splash_version); this.tv_splash_version.setText("版本:" + this.getVersion()); //获取当前的版本 handler = new Handler(){
@Override public void handleMessage(Message msg) { //接收消息队列里面的消息 // TODO Auto-generated method stub switch (msg.what) { case URL_ERROR: Toast.makeText(splashactivity.this, "url错误", Toast.LENGTH_LONG).show(); loadMain(); break; case PROTOCOL_ERROR: Toast.makeText(splashactivity.this, "请求方式错误", Toast.LENGTH_LONG).show(); loadMain(); break; case JSON_PARSER_ERROR: Toast.makeText(splashactivity.this, "JSON解析错误", Toast.LENGTH_LONG).show(); loadMain(); break; case INTERNET_ERROR: Toast.makeText(splashactivity.this, "网络链接错误", Toast.LENGTH_LONG).show(); loadMain(); break; case READ_DATA_ERROR: Toast.makeText(splashactivity.this, "数据解析错误", Toast.LENGTH_LONG).show(); loadMain(); break; case LOAD_MAIN: loadMain(); break; case SHOW_DIALOG: showDialog(); break; case UPDADTE_SOFT: File file = (File) msg.obj; installApk(file); break; case DOWNLOAD_FILE_FAILURE: Toast.makeText(splashactivity.this, "文件下载失败", Toast.LENGTH_LONG).show(); loadMain(); break; } }
}; /********************************************************************************************/ //子线程去检查服务器是否有新的版本 this.checkServiceVersion(); } /** * ***************此方法是查找此软件的版本是否要更新 */ private void checkServiceVersion() { new Thread() //开一个子线程,因为主线程不要太多的工作,不然会容易阻塞的 { public void run() { //连接互联网 startTime = System.currentTimeMillis();
String path = "http://192.168.128.1:8080/safemobile_server/safemobile_ser"; //访问服务端的地址 Message msg = Message.obtain(); //获得消息对象 try { //loadMain(); info = Utils.getServerInfo(path); //通过json解析获得需要的信息 Log.i("splashactivity", "版本号:"+ info.getVersion()); if(getVersion().equals(info.getVersion())) { msg.what = LOAD_MAIN; }else { msg.what = SHOW_DIALOG; } } catch (MalformedURLException e) { e.printStackTrace(); msg.what=URL_ERROR; } catch (ProtocolException e) { e.printStackTrace(); msg.what=PROTOCOL_ERROR; }catch (JSONException e) { msg.what=JSON_PARSER_ERROR; }catch (IOException e) { e.printStackTrace(); msg.what=INTERNET_ERROR; }catch (Exception e) { e.printStackTrace(); msg.what=READ_DATA_ERROR;
}finally { long edntime = System.currentTimeMillis(); long data = edntime-startTime; if(data < 2000) { try { Thread.sleep(2000 - data); }catch(Exception e) { e.printStackTrace(); }
handler.sendMessage(msg); } } } }.start(); } /** * 如果要更新的话就显示一个更新的对话框 */ public void showDialog() { AlertDialog.Builder builder = new Builder(this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("升级提醒"); builder.setMessage(info.getDesc()); builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override public void onCancel(DialogInterface dialog) { // TODO Auto-generated method stub loadMain(); } });
builder.setNegativeButton("否", new OnClickListener(){
@Override public void onClick(DialogInterface dialog, int which) { loadMain();
}
});
builder.setPositiveButton("是", new OnClickListener(){
@Override public void onClick(DialogInterface dialog, int which) {
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { file = new File(Environment.getExternalStorageDirectory(), info.getPath().substring(info.getPath().lastIndexOf("/")+1)); pd = new ProgressDialog(splashactivity.this); pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pd.setIcon(R.drawable.ic_launcher); pd.setTitle("下载文件"); pd.setMessage("文件正在下载,请稍后..."); pd.show();
new Thread(){ public void run() { File newFile = Utils.updateSoft(file, info.getPath(), pd); if(newFile !=null) { installApk(newFile); }else { Log.i("splashactivity-->newfile: ", newFile+"" + info.getPath()); Message msg = Message.obtain(); msg.what = DOWNLOAD_FILE_FAILURE; handler.sendMessage(msg); } } }.start(); }else { Toast.makeText(splashactivity.this, "sdcard不可用", Toast.LENGTH_LONG).show(); }
}
}); builder.show(); } /** * 跳转主页面的方法 */ public void loadMain() { Intent intent = new Intent(this,MainActivity.class); startActivity(intent); // Intent blackNumberintent = new Intent(this, BlackNumberService.class); // startService(blackNumberintent); finish(); } /** * * 安装应用 * @param file */ public void installApk(File file) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startActivity(intent); this.finish(); }
/** * 获取当前的版本 */ public String getVersion() { PackageManager packageManager = this.getPackageManager(); try { PackageInfo info = packageManager.getPackageInfo(getPackageName(), PackageManager.GET_ACTIVITIES); String version = info.versionName; return version; }catch(Exception e) { e.printStackTrace(); return ""; }
}
} |
如果地址错误或者连不上网的话,就出现这个:
如果连接正确的话就是:
然后就进行下载更新:
完成安装之后就进入到主界面: