1.在Android應用當中都有應用檢查更新的要求,每每都是在打開應用的時候去更新下載。php
實現的方法是:服務器端提供接口,接口中能夠包含在最新APK下載的URL,最新APK的VersionCode,等附帶信息。android
將最新APK的Versioncode與當前的APP的VersionCode作大小比較就能夠知道是不是最新版本,若是是最新版本就下載安裝。json
2.效果圖:服務器
4.上代碼:app
借用別人的接口:http://jcodecraeer.com/update.phpide
AppVersion:是版本信息的模型類,基本上和服務端返回的東西是相對應的。工具
DownloadService:是下載模塊。post
UpdateChecker:是檢查更新,調用下載模塊,下載完安裝的工具類。ui
PS:注意Service在Manifest.xml中要申明。this
AppVersion:
按 Ctrl+C 複製代碼
public class AppVersion {
private String updateMessage; private String apkUrl; private int apkCode; public static final String APK_DOWNLOAD_URL = "url"; public static final String APK_UPDATE_CONTENT = "updateMessage"; public static final String APK_VERSION_CODE = "versionCode"; public String getUpdateMessage() { return updateMessage; } public void setUpdateMessage(String updateMessage) { this.updateMessage = updateMessage; } public String getApkUrl() { return apkUrl; } public void setApkUrl(String apkUrl) { this.apkUrl = apkUrl; } public int getApkCode() { return apkCode; } public void setApkCode(int apkCode) { this.apkCode = apkCode; }
} 按 Ctrl+C 複製代碼
DownloadService:
按 Ctrl+C 複製代碼
public class DownloadService extends IntentService {
public static final int UPDATE_PROGRESS = 8344; public DownloadService() { super("DownloadService"); } @Override protected void onHandleIntent(Intent intent) { String urlToDownload = intent.getStringExtra("url"); System.out.println("URLtOdOWNLOAD-->>" +urlToDownload); String fileDestination = intent.getStringExtra("dest"); ResultReceiver receiver = (ResultReceiver) intent .getParcelableExtra("receiver"); try { URL url = new URL(urlToDownload); URLConnection connection = url.openConnection(); connection.connect(); // this will be useful so that you can show a typical 0-100% // progress bar int fileLength = connection.getContentLength(); // download the file InputStream input = new BufferedInputStream( connection.getInputStream()); OutputStream output = new FileOutputStream(fileDestination); byte data[] = new byte[100]; long total = 0; int count; while ((count = input.read(data)) != -1) { total += count; // publishing the progress.... Bundle resultData = new Bundle(); resultData.putInt("progress", (int) (total * 100 / fileLength)); receiver.send(UPDATE_PROGRESS, resultData); output.write(data, 0, count); } output.flush(); output.close(); input.close(); } catch (IOException e) { e.printStackTrace(); } Bundle resultData = new Bundle(); resultData.putInt("progress", 100); receiver.send(UPDATE_PROGRESS, resultData); }
} 按 Ctrl+C 複製代碼
UpdateChecker:
按 Ctrl+C 複製代碼
public class UpdateChecker { private static final String TAG = "UpdateChecker"; private Context mContext; // 檢查版本信息的線程 private Thread mThread; // 版本對比地址 private String mCheckUrl; private AppVersion mAppVersion; // 下載apk的對話框 private ProgressDialog mProgressDialog;
private File apkFile; public void setCheckUrl(String url) { mCheckUrl = url; } public UpdateChecker(Context context) { mContext = context; // instantiate it within the onCreate method mProgressDialog = new ProgressDialog(context); mProgressDialog.setMessage("正在下載"); mProgressDialog.setIndeterminate(false); mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mProgressDialog.setCancelable(true); mProgressDialog .setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { } }); mProgressDialog .setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { // TODO Auto-generated method stub } }); } public void checkForUpdates() { if (mCheckUrl == null) { // throw new Exception("checkUrl can not be null"); return; } final Handler handler = new Handler() { public void handleMessage(Message msg) { if (msg.what == 1) { mAppVersion = (AppVersion) msg.obj; try { int versionCode = mContext.getPackageManager() .getPackageInfo(mContext.getPackageName(), 0).versionCode; System.out.println("version-->" + versionCode + " mAppVersion.getApkCode()-->>" + mAppVersion.getApkCode()); if (mAppVersion.getApkCode() > versionCode) { showUpdateDialog(); } else { Toast.makeText(mContext, "已是最新版本", Toast.LENGTH_SHORT).show(); } } catch (PackageManager.NameNotFoundException ignored) { // } } } }; mThread = new Thread() { @Override public void run() { // if (isNetworkAvailable(mContext)) { Message msg = new Message(); String json = sendPost(); Log.i("jianghejie", "json = " + json); if (json != null) { AppVersion appVersion = parseJson(json); msg.what = 1; msg.obj = appVersion; handler.sendMessage(msg); } else { Log.e(TAG, "can't get app update json"); } } }; mThread.start(); } protected String sendPost() { HttpURLConnection uRLConnection = null; InputStream is = null; BufferedReader buffer = null; String result = null; try { URL url = new URL(mCheckUrl); uRLConnection = (HttpURLConnection) url.openConnection(); uRLConnection.setDoInput(true); uRLConnection.setDoOutput(true); uRLConnection.setRequestMethod("POST"); uRLConnection.setUseCaches(false); uRLConnection.setConnectTimeout(10 * 1000); uRLConnection.setReadTimeout(10 * 1000); uRLConnection.setInstanceFollowRedirects(false); uRLConnection.setRequestProperty("Connection", "Keep-Alive"); uRLConnection.setRequestProperty("Charset", "UTF-8"); uRLConnection .setRequestProperty("Accept-Encoding", "gzip, deflate"); uRLConnection .setRequestProperty("Content-Type", "application/json"); uRLConnection.connect(); is = uRLConnection.getInputStream(); String content_encode = uRLConnection.getContentEncoding(); if (null != content_encode && !"".equals(content_encode) && content_encode.equals("gzip")) { is = new GZIPInputStream(is); } buffer = new BufferedReader(new InputStreamReader(is)); StringBuilder strBuilder = new StringBuilder(); String line; while ((line = buffer.readLine()) != null) { strBuilder.append(line); } result = strBuilder.toString(); } catch (Exception e) { Log.e(TAG, "http post error", e); } finally { if (buffer != null) { try { buffer.close(); } catch (IOException e) { e.printStackTrace(); } } if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if (uRLConnection != null) { uRLConnection.disconnect(); } } return result; } private AppVersion parseJson(String json) { AppVersion appVersion = new AppVersion(); try { JSONObject obj = new JSONObject(json); String updateMessage = obj.getString(AppVersion.APK_UPDATE_CONTENT); String apkUrl = obj.getString(AppVersion.APK_DOWNLOAD_URL); int apkCode = obj.getInt(AppVersion.APK_VERSION_CODE); System.out.println("updateMessage-->" + updateMessage + " apkUrl-->>" + apkUrl + " apkCode-->>" + apkCode); appVersion.setApkCode(apkCode); appVersion.setApkUrl(apkUrl); appVersion.setUpdateMessage(updateMessage); } catch (JSONException e) { Log.e(TAG, "parse json error", e); } return appVersion; } public void showUpdateDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(mContext); // builder.setIcon(R.drawable.icon); builder.setTitle("有新版本"); builder.setMessage(mAppVersion.getUpdateMessage()); builder.setPositiveButton("下載", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { downLoadApk(); } }); builder.setNegativeButton("忽略", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }); builder.show(); } public void downLoadApk() { String apkUrl = mAppVersion.getApkUrl(); System.out.println("apkUrl-->>" + apkUrl); String dir = mContext.getExternalFilesDir("apk").getAbsolutePath(); File folder = Environment.getExternalStoragePublicDirectory(dir); if (folder.exists() && folder.isDirectory()) { // do nothing } else { folder.mkdirs(); } String filename = apkUrl.substring(apkUrl.lastIndexOf("/"), apkUrl.length()); String destinationFilePath = dir + "/" + filename; apkFile = new File(destinationFilePath); mProgressDialog.show(); Intent intent = new Intent(mContext, DownloadService.class); intent.putExtra("url", apkUrl); intent.putExtra("dest", destinationFilePath); intent.putExtra("receiver", new DownloadReceiver(new Handler())); mContext.startService(intent); } private class DownloadReceiver extends ResultReceiver { public DownloadReceiver(Handler handler) { super(handler); } @Override protected void onReceiveResult(int resultCode, Bundle resultData) { super.onReceiveResult(resultCode, resultData); if (resultCode == DownloadService.UPDATE_PROGRESS) { int progress = resultData.getInt("progress"); mProgressDialog.setProgress(progress); if (progress == 100) { mProgressDialog.dismiss(); // 若是沒有設置SDCard寫權限,或者沒有sdcard,apk文件保存在內存中,須要授予權限才能安裝 String[] command = { "chmod", "777", apkFile.toString() }; try { ProcessBuilder builder = new ProcessBuilder(command); builder.start(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive"); mContext.startActivity(intent); } catch (Exception e) { } } } } }
} 按 Ctrl+C 複製代碼 MainActivity:
按 Ctrl+C 複製代碼
public class MainActivity extends Activity { UpdateChecker update; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); update = new UpdateChecker(MainActivity.this); findViewById(R.id.btn).setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) { update.setCheckUrl("http://jcodecraeer.com/update.php"); update.checkForUpdates(); } }); }
} 按 Ctrl+C 複製代碼
源碼下載:下載