Android版本更新(Service下载 Notification进度条)
功能:版本更新、文件后台下载以及Notification显示进度条。
效果图:
主要代码:
- <strong style="color: #262626; font-family: Simsun;">package com.ljp.download;
- import java.io.File;
- import android.app.ActivityGroup;
- import android.app.AlertDialog;
- import android.app.Dialog;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.net.Uri;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import com.ljp.download.service.AppUpgradeService;
- import com.ljp.version.R;
- public class MainActivity extends ActivityGroup {
- private Button button1;
- private String mDownloadUrl = "http://gdown.baidu.com/data/wisegame/ba226d3cf2cfc97b/baiduyinyue_4920.apk";
- private String apkUpdateMsg = "1.内容1\n2.内容2\n3.内容3";
- private Dialog updateVersionDialog;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.layout_main);
- button1 = (Button) findViewById(R.id.button1);
- button1.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- showDialog();
- }
- });
- }
- private void showDialog() {
- updateVersionDialog = new AlertDialog.Builder(MainActivity.this).setTitle("有新版本需要更新").setMessage(apkUpdateMsg)
- .setPositiveButton("现在更新", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- downLoadApk();
- }
- }).setNegativeButton("以后再说", new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- dialog.dismiss();
- }
- }).create();
- updateVersionDialog.show();
- }
- /**
- * 文件下载
- */
- private void downLoadApk() {
- Intent intent = new Intent(MainActivity.this, AppUpgradeService.class);
- intent.putExtra("mDownloadUrl", mDownloadUrl);
- startService(intent);
- updateVersionDialog.dismiss();
- }
- }</strong>
- package com.ljp.download.service;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.net.URLEncoder;
- import java.util.HashMap;
- import java.util.Map;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import android.app.Notification;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.app.Service;
- import android.content.Intent;
- import android.content.pm.PackageInfo;
- import android.content.pm.PackageManager;
- import android.graphics.drawable.Drawable;
- import android.net.Uri;
- import android.os.Bundle;
- import android.os.Environment;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Message;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
- import android.widget.ImageView;
- import android.widget.ProgressBar;
- import android.widget.RemoteViews;
- import android.widget.TextView;
- import android.widget.Toast;
- import com.ljp.download.DownloadUtils;
- import com.ljp.download.MainActivity;
- import com.ljp.version.R;
- /**
- * 程序版本更新Service
- * @author yingjun10627
- *
- */
- public class AppUpgradeService extends Service {
- private NotificationManager mNotificationManager = null;
- private Notification mNotification = null;
- private PendingIntent mPendingIntent = null;
- private String mDownloadUrl;
- private File destDir = null;
- private File destFile = null;
- public static final String downloadPath = "/winner";
- public static final int mNotificationId = 111;
- private static final int DOWNLOAD_FAIL = -1;
- private static final int DOWNLOAD_SUCCESS = 0;
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case DOWNLOAD_SUCCESS:
- Toast.makeText(getApplicationContext(), "下载成功", Toast.LENGTH_LONG).show();
- install(destFile);
- mNotificationManager.cancel(mNotificationId);
- break;
- case DOWNLOAD_FAIL:
- Toast.makeText(getApplicationContext(), "下载失败", Toast.LENGTH_LONG).show();
- mNotificationManager.cancel(mNotificationId);
- break;
- default:
- break;
- }
- }
- };
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if(intent==null){
- stopSelf();
- return super.onStartCommand(intent, flags, startId);
- }
- mDownloadUrl = intent.getStringExtra("mDownloadUrl");
- if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
- destDir = new File(Environment.getExternalStorageDirectory().getPath() + downloadPath);
- if (destDir.exists()) {
- File destFile = new File(destDir.getPath() + "/" + URLEncoder.encode(mDownloadUrl));
- if (destFile.exists() && destFile.isFile() && checkApkFile(destFile.getPath())) {
- install(destFile);
- stopSelf();
- return super.onStartCommand(intent, flags, startId);
- }
- }
- } else {
- return super.onStartCommand(intent, flags, startId);
- }
- mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
- mNotification = new Notification();
- Intent completingIntent = new Intent();
- completingIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
- completingIntent.setClass(getApplicationContext(), AppUpgradeService.class);
- // 创建Notifcation对象,设置图标,提示文字,策略
- mPendingIntent = PendingIntent.getActivity(AppUpgradeService.this, R.string.app_name, completingIntent,
- PendingIntent.FLAG_UPDATE_CURRENT);
- mNotification.icon = R.drawable.ic_launcher;
- mNotification.tickerText = "开始下载";
- mNotification.contentIntent = mPendingIntent;
- mNotification.contentView = new RemoteViews(getPackageName(), R.layout.app_upgrade_notification);
- mNotification.contentView.setProgressBar(R.id.app_upgrade_progressbar, 100, 0, false);
- mNotification.contentView.setTextViewText(R.id.app_upgrade_title, "正在下载...");
- mNotification.contentView.setTextViewText(R.id.app_upgrade_text, "当前进度:0%");
- mNotificationManager.cancel(mNotificationId);
- mNotificationManager.notify(mNotificationId, mNotification);
- new AppUpgradeThread().start();
- return super.onStartCommand(intent, flags, startId);
- }
- /**
- * 用于监听文件下载
- */
- private DownloadUtils.DownloadListener downloadListener = new DownloadUtils.DownloadListener() {
- @Override
- public void downloading(int progress) {
- System.out.println(progress);
- mNotification.contentView.setProgressBar(R.id.app_upgrade_progressbar, 100, progress, false);
- mNotification.contentView.setTextViewText(R.id.app_upgrade_text, "当前进度:" + progress + "%");
- mNotificationManager.notify(mNotificationId, mNotification);
- }
- @Override
- public void downloaded() {
- mNotification.contentView.setViewVisibility(R.id.app_upgrade_progressbar, View.GONE);
- mNotification.defaults = Notification.DEFAULT_SOUND;
- mNotification.contentIntent = mPendingIntent;
- mNotification.contentView.setTextViewText(R.id.app_upgrade_title, "下载完成");
- mNotificationManager.notify(mNotificationId, mNotification);
- if (destFile.exists() && destFile.isFile() && checkApkFile(destFile.getPath())) {
- Message msg = mHandler.obtainMessage();
- msg.what = DOWNLOAD_SUCCESS;
- mHandler.sendMessage(msg);
- }
- mNotificationManager.cancel(mNotificationId);
- }
- };
- /**
- * 用于文件下载线程
- * @author yingjun10627
- *
- */
- class AppUpgradeThread extends Thread {
- @Override
- public void run() {
- if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
- if (destDir == null) {
- destDir = new File(Environment.getExternalStorageDirectory().getPath() + downloadPath);
- }
- if (destDir.exists() || destDir.mkdirs()) {
- destFile = new File(destDir.getPath() + "/" + URLEncoder.encode(mDownloadUrl));
- if (destFile.exists() && destFile.isFile() && checkApkFile(destFile.getPath())) {
- install(destFile);
- } else {
- try {
- DownloadUtils.download(mDownloadUrl, destFile, false, downloadListener);
- } catch (Exception e) {
- Message msg = mHandler.obtainMessage();
- msg.what = DOWNLOAD_FAIL;
- mHandler.sendMessage(msg);
- e.printStackTrace();
- }
- }
- }
- }
- stopSelf();
- }
- }
- /**
- * apk文件安装
- *
- * @param apkFile
- */
- public void install(File apkFile) {
- Uri uri = Uri.fromFile(apkFile);
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setDataAndType(uri, "application/vnd.android.package-archive");
- startActivity(intent);
- }
- /**
- * 判断文件是否完整
- *
- * @param apkFilePath
- * @return
- */
- public boolean checkApkFile(String apkFilePath) {
- boolean result = false;
- try {
- PackageManager pManager = getPackageManager();
- PackageInfo pInfo = pManager.getPackageArchiveInfo(apkFilePath, PackageManager.GET_ACTIVITIES);
- if (pInfo == null) {
- result = false;
- } else {
- result = true;
- }
- } catch (Exception e) {
- result = false;
- e.printStackTrace();
- }
- return result;
- }
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- }
- package com.ljp.download;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.zip.GZIPInputStream;
- import org.apache.http.Header;
- import org.apache.http.HttpResponse;
- import org.apache.http.HttpStatus;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.params.BasicHttpParams;
- import org.apache.http.params.HttpConnectionParams;
- import org.apache.http.params.HttpParams;
- public class DownloadUtils {
- private static final int CONNECT_TIMEOUT = 10000;
- private static final int DATA_TIMEOUT = 40000;
- private final static int DATA_BUFFER = 8192;
- public interface DownloadListener {
- public void downloading(int progress);
- public void downloaded();
- }
- public static long download(String urlStr, File dest, boolean append, DownloadListener downloadListener) throws Exception {
- int downloadProgress = 0;
- long remoteSize = 0;
- int currentSize = 0;
- long totalSize = -1;
- if (!append && dest.exists() && dest.isFile()) {
- dest.delete();
- }
- if (append && dest.exists() && dest.exists()) {
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(dest);
- currentSize = fis.available();
- } catch (IOException e) {
- throw e;
- } finally {
- if (fis != null) {
- fis.close();
- }
- }
- }
- HttpGet request = new HttpGet(urlStr);
- if (currentSize > 0) {
- request.addHeader("RANGE", "bytes=" + currentSize + "-");
- }
- HttpParams params = new BasicHttpParams();
- HttpConnectionParams.setConnectionTimeout(params, CONNECT_TIMEOUT);
- HttpConnectionParams.setSoTimeout(params, DATA_TIMEOUT);
- HttpClient httpClient = new DefaultHttpClient(params);
- InputStream is = null;
- FileOutputStream os = null;
- try {
- HttpResponse response = httpClient.execute(request);
- if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
- is = response.getEntity().getContent();
- remoteSize = response.getEntity().getContentLength();
- Header contentEncoding = response.getFirstHeader("Content-Encoding");
- if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
- is = new GZIPInputStream(is);
- }
- os = new FileOutputStream(dest, append);
- byte buffer[] = new byte[DATA_BUFFER];
- int readSize = 0;
- int temp=0;
- while ((readSize = is.read(buffer)) > 0) {
- os.write(buffer, 0, readSize);
- os.flush();
- totalSize += readSize;
- if (downloadListener != null) {
- downloadProgress = (int) (totalSize * 100 / remoteSize);
- if(downloadProgress>=temp){
- temp++;
- downloadListener.downloading(downloadProgress);
- }
- }
- }
- if (totalSize < 0) {
- totalSize = 0;
- }
- }
- } finally {
- if (os != null) {
- os.close();
- }
- if (is != null) {
- is.close();
- }
- }
- if (totalSize < 0) {
- throw new Exception("Download file fail: " + urlStr);
- }
- if (downloadListener != null) {
- downloadListener.downloaded();
- }
- return totalSize;
- }
- }
Service启动方式说明:
START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

浙公网安备 33010602011771号