android_apk的在线安装,除了要设计Android 客户端的代码外,还要搭建服务器的代码,仿真实现中Android软件的在线升级。
Android 客户端的代码截图如下。
MainActivity
[java] view plaincopy
package com.example.f03_packmanager;
import java.io.File;
import java.util.concurrent.ExecutionException;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
// 先在文件清单添加获取网络访问权限和准许读写sdcard的permission;
private Button button;
private ProgressDialog dialog;// 查询版本更新信息的进度对话框
private String messagePath = "http://111.0.124.108:8080/http/servlet/Install";// 获取版本更新的URL
private Message message;
private PackUtiles packUtiles;// 获取当前版本信息的封装类
private AlertDialog.Builder builder;// 下载更新的对话框
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialog = new ProgressDialog(MainActivity.this);
dialog.setTitle("提示");
dialog.setMessage("download.....");
builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("下载更新");
builder.setMessage("是否下载最新的版本?");
builder.setCancelable(false);// 设置不能随意关闭提示下载更新的对话框
button = (Button) this.findViewById(R.id.button1);
packUtiles = new PackUtiles(MainActivity.this);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
message = new getAPKUrl().execute(messagePath)
.get();
boolean flag = packUtiles.update(packUtiles.getVersion(),
message.getVsersionCode());
Log.i("tag", "------->" + flag);
if (flag) {
builder.setPositiveButton("确定", new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
new downLoadAPK().execute(message.getApkUrl());
}
});
builder.setNegativeButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}
});
builder.create().show();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
// 获取版本更新信息的异步任务
public class getAPKUrl extends AsyncTask<String, Void, Message> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
dialog.show();
}
@Override
protected Message doInBackground(String... params) {
// TODO Auto-generated method stub
return HttpUtiles.getMessage(params[0]);
}
@Override
protected void onPostExecute(Message result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
}
}
public class downLoadAPK extends AsyncTask<String, Void, Void> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
String uri=HttpUtiles.downLoadApk(params[0]);
Log.i("TAG2", "-------->"+uri);
//通过文件路径安装指定版本
Uri uri2=Uri.fromFile(new File(uri));
Intent intent=new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri2, "application/vnd.android.package-archive");
startActivity(intent);
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
}
HttpUtiles获取服务器的版本信息,一个方法为以json格式获取版本的数据,一个为下载最新的版本到sdcard中
[java] view plaincopy
package com.example.f03_packmanager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.Environment;
import android.util.Log;
public class HttpUtiles {
//下载版本信息,格式为json
public static Message getMessage(String path) {
Message message = new Message();
HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(path);
try {
HttpResponse httpResponse = client.execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode()==200){
String json=EntityUtils.toString(httpResponse.getEntity());
try {
JSONObject jsonObject=new JSONObject(json).getJSONObject("message");
message.setVsersionCode(jsonObject.getInt("vsersionCode"));
message.setApkUrl(jsonObject.getString("apkUrl"));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return message;
}
//下载指定版本到sdcard中
public static String downLoadApk(String path){
byte[]data=null;
String uri=null;
HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(path);
FileOutputStream fileOutputStream=null;
try {
HttpResponse httpResponse = client.execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode()==200){
data=EntityUtils.toByteArray(httpResponse.getEntity());
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File file=Environment.getExternalStorageDirectory();
String name=path.substring(path.lastIndexOf("/")+1,path.length());
fileOutputStream=new FileOutputStream(new File(file, name));
fileOutputStream.write(data, 0, data.length);
uri=file.getAbsolutePath()+"/"+name;
}
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(fileOutputStream!=null){
try {
fileOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Log.i("HTTP", "-------->"+uri);
return uri;
}
}
Message类指定数据返回的格式
[java] view plaincopy
package com.example.f03_packmanager;
public class Message {
private int vsersionCode;
private String apkUrl;
public int getVsersionCode() {
return vsersionCode;
}
public void setVsersionCode(int vsersionCode) {
this.vsersionCode = vsersionCode;
}
public String getApkUrl() {
return apkUrl;
}
public void setApkUrl(String apkUrl) {
this.apkUrl = apkUrl;
}
@Override
public String toString() {
return "Message [vsersionCode=" + vsersionCode + ", apkUrl=" + apkUrl
+ "]";
}
}
PackUtilse获取软件当前的版本信息
[java] view plaincopy
package com.example.f03_packmanager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
public class PackUtiles {
private Context context;
private PackageManager manager;
private PackageInfo info;
public PackUtiles(Context context) {
// TODO Auto-generated constructor stub
this.context = context;
initDate();
}
public void initDate() {
manager = context.getPackageManager();
try {
info = manager.getPackageInfo(context.getPackageName(),
PackageManager.GET_ACTIVITIES);
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public int getVersion() {
return info.versionCode;
}
public String getVersionName(){
return info.versionName;
}
//比较本地版本和服务器的版本号的大小
public boolean update(int oldVersion,int newVersion){
boolean flag=newVersion>oldVersion?true:false;
return flag;
}
}
到此Android的代码就编写完成了,下面我们来介绍一下服务器端的代码,事先要导入json的jar包,另外一点注意的是所有的http地址在自己使用的时候都记得改成自己笔记本的ip地址,此外别忘了把要更新的软件apk放在webroot目录下。
[java] view plaincopy
package com.login.install;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONSerializer;
public class Install extends HttpServlet {
/**
* Constructor of the object.
*/
public Install() {
super();
}
/**
* Destruction of the servlet. <br>
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
Message message=new Message();
message.setVsersionCode(2);
message.setApkUrl("http://111.0.124.108:8080/http/F03_PackManager.apk");
Map<String, Object> map=new HashMap<String, Object>();
map.put("message", message);
out.print(JSONSerializer.toJSON(map));
out.flush();
out.close();
}
/**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occurs
*/
public void init() throws ServletException {
// Put your code here
}
}
评论