功能:版本更新、文件后台下载以及Notification显示进度条。

效果图:
Android版本更新(Service下载 Notification进度条)_第1张图片
主要代码:

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();    }  }

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后一定能重启。

更多相关文章

  1. Android 5.0低版本出现Error inflating class
  2. framework之 ContextImpl文件解析
  3. Android外部存储(/storage/emulated/0)无法创建文件夹
  4. AndroidManifest.xml文件详解(uses-feature)
  5. Android开源项目分类汇总【老外汇总版本】
  6. Android Studio 导入so文件
  7. Android 开发 TextView中出现参差不齐状态解决方法
  8. Android的string.xml文件中的特殊字符显示

随机推荐

  1. 简解selector的几个属性
  2. Android布局属性介绍
  3. Android在layout xml中使用include
  4. Android(安卓)文件的上传
  5. Android 编译系统分析之返璞归真(一)
  6. Android极致优化
  7. Android的多语言文件转IOS多语言文件格式
  8. 安卓系统框架介绍
  9. Android与JNI(一)
  10. textview中自动换行显示文本内容