Android中的应用更新

来源:互联网 发布:优化人才培养方案 编辑:程序博客网 时间:2024/05/17 22:43

实现思路:通过启动service,新建一个线程进行下载,handler通知到notification。
1、下载接口

public interface UpdateDownloadListener {    /**     * 下载请求开始回调     */    public void onStarted();    /**     * 请求成功,下载前的准备回调     *      * @param contentLength     *            文件长度     * @param downloadUrl     *            下载地址     */    public void onPrepared(long contentLength, String downloadUrl);    /**     * 进度更新回调     *      * @param progress     * @param downloadUrl     */    public void onProgressChanged(int progress, String downloadUrl);    /**     * 下载过程中暂停的回调     *      * @param completeSize     * @param downloadUrl     */    public void onPaused(int progress, int completeSize, String downloadUrl);    /**     * 下载完成回调     *      * @param completeSize     * @param downloadUrl     */    public void onFinished(int completeSize, String downloadUrl);    /**     * 下载失败回调     */    public void onFailure();}

2、下载请求

public class UpdateDownloadRequest implements Runnable {    private int startPos = 0;    //下载路径    private String downloadUrl;    //文件保存路径    private String localFilePath;    //事件回调    private UpdateDownloadListener downloadListener;    private DownloadResponseHandler downloadHandler;    //下载的标志位    private boolean isDownloading = false;    //文件长度    private long contentLength;    public UpdateDownloadRequest(String downloadUrl, String localFilePath, UpdateDownloadListener downloadListener) {        this.downloadUrl = downloadUrl;        this.localFilePath = localFilePath;        this.downloadListener = downloadListener;        downloadHandler = new DownloadResponseHandler();        isDownloading = true;    }    //真正建立连接的方法    private void makeRequest() throws IOException, InterruptedException {        if (!Thread.currentThread().isInterrupted()) {            try {                URL url = new URL(downloadUrl);                HttpURLConnection connection = (HttpURLConnection) url.openConnection();                connection.setConnectTimeout(5000);                connection.setRequestMethod("GET");                connection.setRequestProperty("Range", "bytes=" + startPos + "-");                connection.setRequestProperty("Connection", "Keep-Alive");                connection.connect();                contentLength = connection.getContentLength();                if (!Thread.currentThread().isInterrupted()) {                    if (downloadHandler != null) {                        downloadHandler.sendResponseMessage(connection.getInputStream());//取得与远程文件的流                    }                }            } catch (IOException e) {                if (!Thread.currentThread().isInterrupted()) {                    throw e;                }            }        }    }    @Override    public void run() {        try {            makeRequest();        } catch (IOException e) {            if (downloadHandler != null) {                downloadHandler.sendFailureMessage(FailureCode.IO);            }        } catch (InterruptedException e) {            if (downloadHandler != null) {                downloadHandler.sendFailureMessage(FailureCode.Interrupted);            }        }    }    public boolean isDownloading() {        return isDownloading;    }    public void stopDownloading() {        isDownloading = false;    }    /**     * 用来真正的去下载文件,并发送消息和回调接口     */    public class DownloadResponseHandler {        protected static final int SUCCESS_MESSAGE = 0;        protected static final int FAILURE_MESSAGE = 1;        protected static final int START_MESSAGE = 2;        protected static final int FINISH_MESSAGE = 3;        protected static final int NETWORK_OFF = 4;        private Handler handler;        public DownloadResponseHandler() {            if (Looper.myLooper() != null) {                handler = new Handler() {                    @Override                    public void handleMessage(Message msg) {                        handleSelfMessage(msg);                    }                };            }        }        public void onFinish() {            downloadListener.onFinished(mCompleteSize, "");        }        public void onFailure(FailureCode failureCode) {            downloadListener.onFailure();        }        private void sendPausedMessage() {            sendMessage(obtainMessage(PAUSED_MESSAGE, null));        }        private void sendProgressChangedMessage(int progress) {            sendMessage(obtainMessage(PROGRESS_CHANGED, new Object[] { progress }));        }        protected void sendFailureMessage(FailureCode failureCode) {            sendMessage(obtainMessage(FAILURE_MESSAGE, new Object[] { failureCode }));        }        //        // Pre-processing of messages (in original calling thread, typically the        // UI thread)        //        protected void handlePausedMessage() {            downloadListener.onPaused(progress, mCompleteSize, "");        }        protected void handleProgressChangedMessage(int progress) {            downloadListener.onProgressChanged(progress, "");        }        protected void handleFailureMessage(FailureCode failureCode) {            onFailure(failureCode);        }        protected void sendFinishMessage() {            sendMessage(obtainMessage(FINISH_MESSAGE, null));        }        // Methods which emulate android's Handler and Message methods        protected void handleSelfMessage(Message msg) {            Object[] response;            switch (msg.what) {            case FAILURE_MESSAGE:                response = (Object[]) msg.obj;                handleFailureMessage((FailureCode) response[0]);                break;            case PROGRESS_CHANGED:                response = (Object[]) msg.obj;                handleProgressChangedMessage(((Integer) response[0]).intValue());                break;            case PAUSED_MESSAGE:                handlePausedMessage();                break;            case FINISH_MESSAGE:                onFinish();                break;            }        }        protected void sendMessage(Message msg) {            if (handler != null) {                handler.sendMessage(msg);            } else {                handleSelfMessage(msg);            }        }        protected Message obtainMessage(int responseMessage, Object response) {            Message msg = null;            if (handler != null) {                msg = this.handler.obtainMessage(responseMessage, response);            } else {                msg = Message.obtain();                msg.what = responseMessage;                msg.obj = response;            }            return msg;        }        private String getTwoPointFloatStr(float value) {            DecimalFormat fnum = new DecimalFormat("0.00");            return fnum.format(value);        }        private int mCompleteSize = 0;        private int progress = 0;        private static final int PROGRESS_CHANGED = 5;        private static final int PAUSED_MESSAGE = 7;        //文件 下载方法,会发送各种类型的事件        void sendResponseMessage(InputStream is) {            RandomAccessFile randomAccessFile = null;            mCompleteSize = 0;            try {                byte[] buffer = new byte[1024];                int length = -1;                int limit = 0;                randomAccessFile = new RandomAccessFile(localFilePath, "rwd");                randomAccessFile.seek(startPos);                boolean isPaused = false;                while ((length = is.read(buffer)) != -1) {                    if (isDownloading) {                        randomAccessFile.write(buffer, 0, length);                        mCompleteSize += length;                        if ((startPos + mCompleteSize) < (contentLength + startPos)) {                            progress = (int) (Float.parseFloat(getTwoPointFloatStr(                                    (float) (startPos + mCompleteSize) / (contentLength + startPos))) * 100);                            if (limit % 30 == 0 &&progress <= 100) {                                //为了显示我们notification的更新频率                                sendProgressChangedMessage(progress); //在子线程中读取流数据,后转发到主线程中去。                            }                        }                        limit++;                    } else {                        isPaused = true;                        sendPausedMessage();                        break;                    }                }                stopDownloading();                if (!isPaused) {                    sendFinishMessage();                }            } catch (IOException e) {                sendPausedMessage();                stopDownloading();                e.printStackTrace();            } finally {                try {                    if (is != null) {                        is.close();                    }                    if (randomAccessFile != null) {                        randomAccessFile.close();                    }                } catch (IOException e) {                    stopDownloading();                    e.printStackTrace();                }            }        }    }    /**     * 失败码     */    public enum FailureCode {        UnknownHost, Socket, SocketTimeout, ConnectTimeout, IO, HttpResponse, JSON, Interrupted    }}

3、下载调度管理器

public class UpdateManager {    private static UpdateManager manager;    private ThreadPoolExecutor threadPool;    private UpdateDownloadRequest downloadRequest;    private UpdateManager() {        threadPool = (ThreadPoolExecutor) Executors.newCachedThreadPool();    }    static {        manager = new UpdateManager();    }    public static UpdateManager getInstance() {        return manager;    }    public void startDownload(String downloadUrl, String localFilePath,                              UpdateDownloadListener downloadListener) {        if (downloadRequest != null && downloadRequest.isDownloading()) {            return;        }        checkLocalFilePath(localFilePath);        downloadRequest = new UpdateDownloadRequest(downloadUrl, localFilePath,                downloadListener);        Future<?> request = threadPool.submit(downloadRequest);        new WeakReference<Future<?>>(request);    }    //检查路径是否合法    private void checkLocalFilePath(String localFilePath) {        File path = new File(localFilePath.substring(0,                localFilePath.lastIndexOf("/") + 1));        File file = new File(localFilePath);        if (!path.exists()) {            path.mkdirs();        }        if (!file.exists()) {            try {                file.createNewFile();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

4、下载的service

public class UpdateService extends Service {    /**     * 服务器固定地址     */    private static final String APK_URL_TITLE = "http://www.imooc.com/mobile/mukewang.apk";    /**     * 文件存放路经     */    private String filePath;    /**     * 文件下载地址     */    private String apkUrl;    private NotificationManager notificationManager;    private Notification mNotification;    @Override    public void onCreate() {        notificationManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);        filePath = Environment.getExternalStorageDirectory() + "/imooc/imooc.apk";    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        apkUrl = APK_URL_TITLE;        notifyUser(getString(R.string.update_download_start), getString(R.string.update_download_start), 0);        startDownload();        return super.onStartCommand(intent, flags, startId);    }    private void startDownload() {        UpdateManager.getInstance().startDownload(apkUrl, filePath, new UpdateDownloadListener() {            @Override            public void onStarted() {            }            @Override            public void onProgressChanged(int progress, String downloadUrl) {                notifyUser(getString(R.string.update_download_processing),                    getString(R.string.update_download_processing), progress);            }            @Override            public void onPrepared(long contentLength, String downloadUrl) {            }            @Override            public void onPaused(int progress, int completeSize, String downloadUrl) {                notifyUser(getString(R.string.update_download_failed),                    getString(R.string.update_download_failed_msg), 0);                deleteApkFile();                stopSelf();// 停掉服务自身            }            @Override            public void onFinished(int completeSize, String downloadUrl) {                notifyUser(getString(R.string.update_download_finish), getString(R.string.update_download_finish),                    100);                stopSelf();// 停掉服务自身                startActivity(getInstallApkIntent());            }            @Override            public void onFailure() {                notifyUser(getString(R.string.update_download_failed),                    getString(R.string.update_download_failed_msg), 0);                deleteApkFile();                stopSelf();// 停掉服务自身            }        });    }    @Override    public IBinder onBind(Intent intent) {        return null;    }    public void notifyUser(String tickerMsg, String message, int progress) {        notifyThatExceedLv21(tickerMsg, message, progress);    }    private void notifyThatExceedLv21(String tickerMsg, String message, int progress) {        NotificationCompat.Builder notification = new NotificationCompat.Builder(this);        notification.setSmallIcon(R.drawable.bg_message_imooc);        notification.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.bg_message_imooc));        notification.setContentTitle(getString(R.string.app_name));        if (progress > 0 && progress < 100) {            notification.setProgress(100, progress, false);        } else {            /**             * 0,0,false,可以将进度条影藏             */            notification.setProgress(0, 0, false);            notification.setContentText(message);        }        notification.setAutoCancel(true);        notification.setWhen(System.currentTimeMillis());        notification.setTicker(tickerMsg);        notification.setContentIntent(progress >= 100 ? getContentIntent() : PendingIntent.getActivity(this, 0,            new Intent(), PendingIntent.FLAG_UPDATE_CURRENT));        mNotification = notification.build();        notificationManager.notify(0, mNotification);    }    private PendingIntent getContentIntent() {        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, getInstallApkIntent(),            PendingIntent.FLAG_UPDATE_CURRENT);        return contentIntent;    }    /**     * 下载完成,安装     */    private Intent getInstallApkIntent() {        File apkfile = new File(filePath);        Intent intent = new Intent(Intent.ACTION_VIEW);        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        intent.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");        return intent;    }    /**     * 删除无用apk文件     */    private boolean deleteApkFile() {        File apkFile = new File(filePath);        if (apkFile.exists() && apkFile.isFile()) {            return apkFile.delete();        }        return false;    }}
0 0
原创粉丝点击