1.安装下载下来的apk
String fileName = "/sdcard/TestB.apk";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" +new File(fileName)),"application/vnd.android.package-archive");
startActivity(intent);
2、卸载apk
private void startUninstall(final String pkg) {
if (!InstallUtils.isApkInstalled(mContext, pkg)) {
Toast.makeText(mContext, "程序未安装,无需卸载!", Toast.LENGTH_SHORT).show();
return;
} else {
Uri packageURI = Uri.parse("package:" + pkg);
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
startActivity(uninstallIntent);
}
}
3.更新apk
1. 准备知识
在AndroidManifest.xml里定义了每个Android apk的版本标识:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp"
android:versionCode="1"
android:versionName="1.0.0">
<application></application>
</manifest>
复制代码
其中,android:versionCode和android:versionName两个字段分别表示版本代码,版本名称。versionCode是整型数字,versionName是字符串。由于version是给用户看的,不太容易比较大小,升级检查时,可以以检查versionCode为主,方便比较出版本的前后大小。
那么,在应用中如何读取AndroidManifest.xml中的versionCode和versionName呢?可以使用PackageManager的API,参考以下代码:
public static int getVerCode(Context context) {
int verCode = -1;
try {
verCode = context.getPackageManager().getPackageInfo(
"com.myapp", 0).versionCode;
} catch (NameNotFoundException e) {
Log.e(TAG, e.getMessage());
}
return verCode;
}
public static String getVerName(Context context) {
String verName = "";
try {
verName = context.getPackageManager().getPackageInfo(
"com.myapp", 0).versionName;
} catch (NameNotFoundException e) {
Log.e(TAG, e.getMessage());
}
return verName;
}
复制代码或者在AndroidManifest中将android:versionName="1.2.0"写成android:versionName="@string/app_versionName",然后在values/strings.xml中添加对应字符串,这样实现之后,就可以使用如下代码获得版本名称:
public static String getVerName(Context context) {
String verName = context.getResources()
.getText(R.string.app_versionName).toString();
return verName;
}
复制代码同理,apk的应用名称可以这样获得:
public static String getAppName(Context context) {
String verName = context.getResources()
.getText(R.string.app_name).toString();
return verName;
}
复制代码2. 流程框架
3. 版本检查
在服务端放置最新版本的apk文件,如:http://localhost/myapp/myapp.apk
同时,在服务端放置对应此apk的版本信息调用接口或者文件,如:http://localhost/myapp/ver.json
ver.json中的内容为:
[{"appname":"jtapp12","apkname":"jtapp-12-updateapksamples.apk","verName":1.0.1,"verCode":2}]
复制代码
然后,在手机客户端上进行版本读取和检查:
private boolean getServerVer () {
try {
String verjson = NetworkTool.getContent(Config.UPDATE_SERVER
+ Config.UPDATE_VERJSON);
JSONArray array = new JSONArray(verjson);
if (array.length() > 0) {
JSONObject obj = array.getJSONObject(0);
try {
newVerCode = Integer.parseInt(obj.getString("verCode"));
newVerName = obj.getString("verName");
} catch (Exception e) {
newVerCode = -1;
newVerName = "";
return false;
}
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
return false;
}
return true;
}
复制代码比较服务器和客户端的版本,并进行更新操作。
if (getServerVerCode()) {
int vercode = Config.getVerCode(this); // 用到前面第一节写的方法
if (newVerCode > vercode) {
doNewVersionUpdate(); // 更新新版本
} else {
notNewVersionShow(); // 提示当前为最新版本
}
}
复制代码详细方法:
private void notNewVersionShow() {
int verCode = Config.getVerCode(this);
String verName = Config.getVerName(this);
StringBuffer sb = new StringBuffer();
sb.append("当前版本:");
sb.append(verName);
sb.append(" Code:");
sb.append(verCode);
sb.append(",/n已是最新版,无需更新!");
Dialog dialog = new AlertDialog.Builder(Update.this).setTitle("软件更新")
.setMessage(sb.toString())// 设置内容
.setPositiveButton("确定",// 设置确定按钮
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
finish();
}
}).create();// 创建
// 显示对话框
dialog.show();
}
private void doNewVersionUpdate() {
int verCode = Config.getVerCode(this);
String verName = Config.getVerName(this);
StringBuffer sb = new StringBuffer();
sb.append("当前版本:");
sb.append(verName);
sb.append(" Code:");
sb.append(verCode);
sb.append(", 发现新版本:");
sb.append(newVerName);
sb.append(" Code:");
sb.append(newVerCode);
sb.append(", 是否更新?");
Dialog dialog = new AlertDialog.Builder(Update.this)
.setTitle("软件更新")
.setMessage(sb.toString())
// 设置内容
.setPositiveButton("更新",// 设置确定按钮
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
pBar = new ProgressDialog(Update.this);
pBar.setTitle("正在下载");
pBar.setMessage("请稍候...");
pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
downFile(Config.UPDATE_SERVER + Config.UPDATE_APKNAME);
}
})
.setNegativeButton("暂不更新",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
// 点击"取消"按钮之后退出程序
finish();
}
}).create();// 创建
// 显示对话框
dialog.show();
}
复制代码4. 下载模块
void downFile(final String url) {
pBar.show();
new Thread() {
public void run() {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
HttpResponse response;
try {
response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream is = entity.getContent();
FileOutputStream fileOutputStream = null;
if (is != null) {
File file = new File(
Environment.getExternalStorageDirectory(),
Config.UPDATE_SAVENAME);
fileOutputStream = new FileOutputStream(file);
byte[] buf = new byte[1024];
int ch = -1;
int count = 0;
while ((ch = is.read(buf)) != -1) {
fileOutputStream.write(buf, 0, ch);
count += ch;
if (length > 0) {
}
}
}
fileOutputStream.flush();
if (fileOutputStream != null) {
fileOutputStream.close();
}
down();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
复制代码
下载完成,通过handler通知主ui线程将下载对话框取消。
void down() {
handler.post(new Runnable() {
public void run() {
pBar.cancel();
update();
}
});
}
复制代码5. 安装应用
void update() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), Config.UPDATE_SAVENAME)),
"application/vnd.android.package-archive");
startActivity(intent);
}
4.下载apk
下载:String url="http://apk包的路径";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
安装:Intent i = new Intent(Intent.ACTION_VIEW);
String filePath = "/sdcard/*.apk";
i.setDataAndType(Uri.parse("file://" + filePath),"application/vnd.android.package-archive");
startActivity(i);
5,检查apk是否安装
public static boolean isApkInstalled(Context context, final String pkgName) {
try {
context.getPackageManager().getPackageInfo(pkgName, 0);
return true;
} catch (NameNotFoundException e) {
//e.printStackTrace();
}
return false;
- package com.autoupdate;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.net.URL;
- import java.net.URLConnection;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.app.ProgressDialog;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.content.pm.PackageInfo;
- import android.content.pm.PackageManager.NameNotFoundException;
- import android.net.ConnectivityManager;
- import android.net.NetworkInfo;
- import android.net.Uri;
- import android.util.Log;
- import android.webkit.URLUtil;
- import com.autoupdate.R;
- /**
- * 版本检测,自动更新
- *
- * @author shenyj-ydrh 1.通过Url检测更新 2.下载并安装更新 3.删除临时路径
- *
- */
- public class MyAutoUpdate {
- // 调用更新的Activity
- public Activity activity = null;
- // 当前版本号
- public int versionCode = 0;
- // 当前版本名称
- public String versionName = "";
- // 控制台信息标识
- private static final String TAG = "AutoUpdate";
- // 文件当前路径
- private String currentFilePath = "";
- // 安装包文件临时路径
- private String currentTempFilePath = "";
- // 获得文件扩展名字符串
- private String fileEx = "";
- // 获得文件名字符串
- private String fileNa = "";
- // 服务器地址
- private String strURL = "http://127.0.0.1:8080/ApiDemos.apk";
- private ProgressDialog dialog;
- /**
- * 构造方法,获得当前版本信息
- *
- * @param activity
- */
- public MyAutoUpdate(Activity activity) {
- this.activity = activity;
- // 获得当前版本
- getCurrentVersion();
- }
- /**
- * 检测更新
- */
- public void check() {
- // 检测网络
- if (isNetworkAvailable(this.activity) == false) {
- return;
- }
- // 如果网络可用,检测到新版本
- if (true) {
- // 弹出对话框,选择是否需要更新版本
- showUpdateDialog();
- }
- }
- /**
- * 检测是否有可用网络
- *
- * @param context
- * @return 网络连接状态
- */
- public static boolean isNetworkAvailable(Context context) {
- try {
- ConnectivityManager cm = (ConnectivityManager) context
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- // 获取网络信息
- NetworkInfo info = cm.getActiveNetworkInfo();
- // 返回检测的网络状态
- return (info != null && info.isConnected());
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- }
- /**
- * 弹出对话框,选择是否需要更新版本
- */
- public void showUpdateDialog() {
- @SuppressWarnings("unused")
- AlertDialog alert = new AlertDialog.Builder(this.activity)
- .setTitle("新版本").setIcon(R.drawable.ic_launcher)
- .setMessage("是否更新?")
- .setPositiveButton("是", new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- // 通过地址下载文件
- downloadTheFile(strURL);
- // 显示更新状态,进度条
- showWaitDialog();
- }
- })
- .setNegativeButton("否", new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- }).show();
- }
- /**
- * 显示更新状态,进度条
- */
- public void showWaitDialog() {
- dialog = new ProgressDialog(activity);
- dialog.setMessage("正在更新,请稍候...");
- dialog.setIndeterminate(true);
- dialog.setCancelable(true);
- dialog.show();
- }
- /**
- * 获得当前版本信息
- */
- public void getCurrentVersion() {
- try {
- // 获取应用包信息
- PackageInfo info = activity.getPackageManager().getPackageInfo(
- activity.getPackageName(), 0);
- this.versionCode = info.versionCode;
- this.versionName = info.versionName;
- } catch (NameNotFoundException e) {
- e.printStackTrace();
- }
- }
- /**
- * 截取文件名称并执行下载
- *
- * @param strPath
- */
- private void downloadTheFile(final String strPath) {
- // 获得文件文件扩展名字符串
- fileEx = strURL.substring(strURL.lastIndexOf(".") + 1, strURL.length())
- .toLowerCase();
- // 获得文件文件名字符串
- fileNa = strURL.substring(strURL.lastIndexOf("/") + 1,
- strURL.lastIndexOf("."));
- try {
- if (strPath.equals(currentFilePath)) {
- doDownloadTheFile(strPath);
- }
- currentFilePath = strPath;
- new Thread(new Runnable() {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- try {
- // 执行下载
- doDownloadTheFile(strPath);
- } catch (Exception e) {
- Log.e(TAG, e.getMessage(), e);
- }
- }
- }).start();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 执行新版本进行下载,并安装
- *
- * @param strPath
- * @throws Exception
- */
- private void doDownloadTheFile(String strPath) throws Exception {
- Log.i(TAG, "getDataSource()");
- // 判断strPath是否为网络地址
- if (!URLUtil.isNetworkUrl(strPath)) {
- Log.i(TAG, "服务器地址错误!");
- } else {
- URL myURL = new URL(strPath);
- URLConnection conn = myURL.openConnection();
- conn.connect();
- InputStream is = conn.getInputStream();
- if (is == null) {
- throw new RuntimeException("stream is null");
- }
- //生成一个临时文件
- File myTempFile = File.createTempFile(fileNa, "." + fileEx);
- // 安装包文件临时路径
- currentTempFilePath = myTempFile.getAbsolutePath();
- FileOutputStream fos = new FileOutputStream(myTempFile);
- byte buf[] = new byte[128];
- do {
- int numread = is.read(buf);
- if (numread <= 0) {
- break;
- }
- fos.write(buf, 0, numread);
- } while (true);
- Log.i(TAG, "getDataSource() Download ok...");
- dialog.cancel();
- dialog.dismiss();
- // 打开文件
- openFile(myTempFile);
- try {
- is.close();
- } catch (Exception ex) {
- Log.e(TAG, "getDataSource() error: " + ex.getMessage(), ex);
- }
- }
- }
- /**
- * 打开文件进行安装
- *
- * @param f
- */
- private void openFile(File f) {
- Intent intent = new Intent();
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setAction(android.content.Intent.ACTION_VIEW);
- // 获得下载好的文件类型
- String type = getMIMEType(f);
- // 打开各种类型文件
- intent.setDataAndType(Uri.fromFile(f), type);
- // 安装
- activity.startActivity(intent);
- }
- /**
- * 删除临时路径里的安装包
- */
- public void delFile() {
- Log.i(TAG, "The TempFile(" + currentTempFilePath + ") was deleted.");
- File myFile = new File(currentTempFilePath);
- if (myFile.exists()) {
- myFile.delete();
- }
- }
- /**
- * 获得下载文件的类型
- *
- * @param f
- * 文件名称
- * @return 文件类型
- */
- private String getMIMEType(File f) {
- String type = "";
- // 获得文件名称
- String fName = f.getName();
- // 获得文件扩展名
- String end = fName
- .substring(fName.lastIndexOf(".") + 1, fName.length())
- .toLowerCase();
- if (end.equals("m4a") || end.equals("mp3") || end.equals("mid")
- || end.equals("xmf") || end.equals("ogg") || end.equals("wav")) {
- type = "audio";
- } else if (end.equals("3gp") || end.equals("mp4")) {
- type = "video";
- } else if (end.equals("jpg") || end.equals("gif") || end.equals("png")
- || end.equals("jpeg") || end.equals("bmp")) {
- type = "image";
- } else if (end.equals("apk")) {
- type = "application/vnd.android.package-archive";
- } else {
- type = "*";
- }
- if (end.equals("apk")) {
- } else {
- type += "/*";
- }
- return type;
- }
- }
market 更新方式
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:your.app.id"));
- startActivity(intent);
//android下载进度控制//
private void execDownloadApk(String url) {
// 下载文件 存放目的地
String downloadPath = Environment.getExternalStorageDirectory()
.getPath() + "/" +cache_data;
File file = new File(downloadPath);
if (!file.exists())
file.mkdir();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse httpResponse = new DefaultHttpClient()
.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
mTotalFileSize =(int)httpResponse.getEntity().getContentLength();
/*URL downUrl = new URL(url);
HttpURLConnection con = (HttpURLConnection) downUrl
.openConnection();
InputStream in = con.getInputStream();
mTotalFileSize = con.getContentLength();*/
InputStream is = httpResponse.getEntity().getContent();
// 开始下载apk文件
FileOutputStream fos = new FileOutputStream(downloadPath
+ "/demo.apk");
byte[] buffer = new byte[8192];
int count = 0;
//if (mTotalFileSize > 0) {
mHand.sendEmptyMessage(MSG_DOWNLOAD_SHOW_PROGRESS);
while ((count = is.read(buffer)) != -1) {
fos.write(buffer, 0, count);
mDownFileSize += count;
mHand.sendEmptyMessage(MSG_DOWNLOAD_PROGRESS);
}
fos.close();
is.close();
//} else {
// mHand.sendEmptyMessage(MSG_DOWNLOAD_ERROR_INFO);
// }
// 安装 apk 文件
installApk(downloadPath + "/demo.apk");
} else {
mHand.sendEmptyMessage(MSG_DOWNLOAD_ERROR_INFO);
}
} catch (Exception e) {
e.printStackTrace();
mHand.sendEmptyMessage(MSG_DOWNLOAD_ERROR_INFO);
}
}
private void showDownLoadProgress() {
mApkDLProgressDialog = CreateDialog.crateDialogByDownLoad(mContext, null,
0);
TextView tv = (TextView) mApkDLProgressDialog
.findViewById(R.id.download_title);
tv.setText(mContext.getResources().getString(
R.string.apk_download_progress));
mDoadloadProgress = (ProgressBar) mApkDLProgressDialog
.findViewById(R.id.down_progress);
mDoadloadProgress.setProgress(0);
mDoadloadProgress.incrementProgressBy(1);
mDoadloadProgress.setMax(mTotalFileSize);
mApkDLProgressDialog.show();
}