Android实现版本更新通知栏下载
来源:互联网 发布:网络拓扑绘制开源工具 编辑:程序博客网 时间:2024/05/27 03:28
一、概述
本篇文章主要实现在应用内发现新版本,用户点击下载apk,同时在通知栏下实现下载进度更新,下载完成后自动弹出安装窗口等等功能,这是apk常见的功能模块!代码亲测有效。
实现效果图如下:
二、具体实现
1.下载监听回调接口UpdateDownloadListener.java
package com.czhappy.appupdate.utils;/** * Description: * User: chenzheng * Date: 2016/12/14 0014 * Time: 16:23 */public interface UpdateDownloadListener { public void onStarted(); public void onProgressChanged(int progress, String downloadUrl); public void onFinished(float completeSize, String downloadUrl); public void onFailure();}
2.文件下载及线程通信UpdateDownloadRequest.java
package com.czhappy.appupdate.utils;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.Log;import java.io.IOException;import java.io.InputStream;import java.io.InterruptedIOException;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;import java.text.DecimalFormat;/** * Description:文件下载及线程间通信 * User: chenzheng * Date: 2016/12/14 0014 * Time: 16:24 */public class UpdateDownloadRequest implements Runnable{ private String downloadUrl; private String localFilePath; private UpdateDownloadListener listener; private boolean isDownloading = false; private long currentLength; private DownloadResponseHandler downloadResponseHandler; public UpdateDownloadRequest(String downloadUrl, String localFilePath, UpdateDownloadListener listener){ this.downloadUrl = downloadUrl; this.localFilePath = localFilePath; this.listener = listener; this.isDownloading = true; downloadResponseHandler = new DownloadResponseHandler(); } private String getTwoPointFloatStr(float value){ DecimalFormat df = new DecimalFormat("0.00000000000"); return df.format(value); } private void makeRequest() throws IOException, InterruptedIOException{ if(!Thread.currentThread().isInterrupted()){ try { URL url = new URL(downloadUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setRequestProperty("Connection", "Keep-Alive"); connection.connect(); currentLength = connection.getContentLength(); if(!Thread.currentThread().isInterrupted()){ downloadResponseHandler.sendResponseMessage(connection.getInputStream()); } }catch (Exception e){ throw e; } } } @Override public void run() { try{ makeRequest(); }catch (IOException e){ } } /** * 下载过程中的异常 */ public enum FailureCode{ UnknownHost, Socket, SocketTimeout, connectionTimeout,IO, HttpResponse, Json, Interrupted } 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 static final int PROGRESS_CHANGED = 5; private float completeSize = 0; private int progress = 0; private Handler handler; public DownloadResponseHandler(){ handler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { handleSelfMessage(msg); } }; } protected void sendFinishMessage(){ sendMessage(obtainMessage(FINISH_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})); } protected void sendMessage(Message msg){ if(handler!=null){ handler.sendMessage(msg); }else{ handleSelfMessage(msg); } } protected Message obtainMessage(int responseMessge, Object response){ Message msg = null; if(handler!=null){ msg = handler.obtainMessage(responseMessge, response); }else{ msg = Message.obtain(); msg.what = responseMessge; msg.obj = response; } return msg; } protected void handleSelfMessage(Message msg){ Object[] response; switch (msg.what){ case FAILURE_MESSAGE: response = (Object[]) msg.obj; sendFailureMessage((FailureCode) response[0]); break; case PROGRESS_CHANGED: response = (Object[]) msg.obj; handleProgressChangedMessage(((Integer)response[0]).intValue()); break; case FINISH_MESSAGE: onFinish(); break; } } protected void handleProgressChangedMessage(int progress){ listener.onProgressChanged(progress, downloadUrl); } protected void onFinish(){ listener.onFinished(completeSize, ""); } private void handleFailureMessage(FailureCode failureCode){ onFailure(failureCode); } protected void onFailure(FailureCode failureCode){ listener.onFailure(); } void sendResponseMessage(InputStream is){ RandomAccessFile randomAccessFile = null; completeSize=0; try{ byte[] buffer = new byte[1024]; int length=-1;//读写长度 int limit=0; randomAccessFile = new RandomAccessFile(localFilePath, "rwd"); while((length = is.read(buffer))!=-1){ if(isDownloading){ randomAccessFile.write(buffer, 0 ,length); completeSize += length; if(completeSize < currentLength){ Log.e("tag", "completeSize="+completeSize); Log.e("tag", "currentLength="+currentLength); progress = (int)(Float.parseFloat(getTwoPointFloatStr(completeSize/currentLength))*100); Log.e("tag", "下载进度:"+progress); if(limit % 30==0 && progress <= 100){//隔30次更新一次notification sendProgressChangedMessage(progress); } limit++; } } } sendFinishMessage(); }catch(IOException e){ sendFailureMessage(FailureCode.IO); }finally{ try{ if(is!=null){ is.close(); } if(randomAccessFile!=null){ randomAccessFile.close(); } }catch(IOException e){ sendFailureMessage(FailureCode.IO); } } } }}
3.文件下载对外方法UpdateManager.java
package com.czhappy.appupdate.utils;import android.util.Log;import java.io.File;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.ThreadPoolExecutor;/** * Description: * User: chenzheng * Date: 2016/12/14 0014 * Time: 16:24 */public class UpdateManager { private static UpdateManager updateManager; private ThreadPoolExecutor threadPoolExecutor; private UpdateDownloadRequest request; private UpdateManager(){ threadPoolExecutor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); } static{ updateManager = new UpdateManager(); } public static UpdateManager getInstance(){ return updateManager; } public void startDownloads(String downloadUrl, String localPath, UpdateDownloadListener listener){ if(request != null){ return; } checkLocalFilePath(localPath); request = new UpdateDownloadRequest(downloadUrl, localPath, listener); Future<?> future = threadPoolExecutor.submit(request); } /** * 检查文件路径是否存在 * @param path */ private void checkLocalFilePath(String path) { Log.e("tag", path); File dir = new File(path.substring(0, path.lastIndexOf("/")+1)); if(!dir.exists()){ dir.mkdir(); } File file = new File(path); if(!file.exists()){ try{ file.createNewFile(); }catch (Exception e){ } } }}
4.通知栏进度更新进程UpdateService.java
package com.czhappy.appupdate.utils;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.Intent;import android.graphics.BitmapFactory;import android.net.Uri;import android.os.Environment;import android.os.IBinder;import android.support.annotation.Nullable;import android.support.v7.app.NotificationCompat;import android.util.Log;import com.czhappy.appupdate.R;import java.io.File;/** * Description:更新下载后台进程 * User: chenzheng * Date: 2016/12/14 0014 * Time: 16:24 */public class UpdateService extends Service{ private String apkUrl; private String filePath; private NotificationManager notificationManager; private Notification notification; @Override public void onCreate() { Log.e("tag", "UpdateService onCreate()"); notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); filePath = Environment.getExternalStorageDirectory()+"/AppUpdate/czhappy.apk"; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e("tag", "UpdateService onStartCommand()"); if(intent==null){ notifyUser(getString(R.string.update_download_failed), getString(R.string.update_download_failed), 0); stopSelf(); } apkUrl = intent.getStringExtra("apkUrl"); 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().startDownloads(apkUrl, filePath, new UpdateDownloadListener() { @Override public void onStarted() { Log.e("tag", "onStarted()"); } @Override public void onProgressChanged(int progress, String downloadUrl) { Log.e("onProgressChanged", progress+""); notifyUser(getString(R.string.update_download_progressing), getString(R.string.update_download_progressing), progress); } @Override public void onFinished(float completeSize, String downloadUrl) { Log.e("tag", "onFinished()"); notifyUser(getString(R.string.update_download_finish), getString(R.string.update_download_finish), 100); stopSelf(); } @Override public void onFailure() { Log.e("tag", "onFailure()"); notifyUser(getString(R.string.update_download_failed), getString(R.string.update_download_failed), 0); stopSelf(); } }); } /** * 更新notification * @param result * @param msg * @param progress */ private void notifyUser(String result, String msg, int progress){ NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setSmallIcon(R.mipmap.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)) .setContentTitle(getString(R.string.app_name)); if(progress>0 && progress<=100){ builder.setProgress(100,progress,false); }else{ builder.setProgress(0, 0, false); } builder.setAutoCancel(true); builder.setWhen(System.currentTimeMillis()); builder.setTicker(result); builder.setContentIntent(progress>=100 ? getContentIntent() : PendingIntent.getActivity(this, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT)); notification = builder.build(); notificationManager.notify(0, notification); } /** * 进入apk安装程序 * @return */ private PendingIntent getContentIntent() { Log.e("tag", "getContentIntent()"); 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.getAbsolutePath()), "application/vnd.android.package-archive"); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); startActivity(intent); return pendingIntent; } @Nullable @Override public IBinder onBind(Intent intent) { return null; }}
5.测试类MainActivity.java
package com.czhappy.appupdate.activity;import android.content.DialogInterface;import android.content.Intent;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import com.czhappy.appupdate.R;import com.czhappy.appupdate.dialog.CommonDialog;import com.czhappy.appupdate.utils.UpdateService;public class MainActivity extends AppCompatActivity { private Button update_btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); update_btn = (Button) this.findViewById(R.id.update_btn); update_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { checkVersion(); } }); checkVersion(); } private void checkVersion(){ //这里不发送检测新版本网络请求,直接进入下载新版本安装 CommonDialog.Builder builder = new CommonDialog.Builder(this); builder.setTitle("升级提示"); builder.setMessage("发现新版本,请及时更新"); builder.setPositiveButton("立即升级", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); Intent intent = new Intent(MainActivity.this, UpdateService.class); intent.putExtra("apkUrl", "http://121.42.53.175:8080/hello_project/resources/upload/TianQiBao201605231.apk"); startService(intent); } }); builder.setNegativeButton("下次再说", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.create().show(); }}
三、源代码下载
http://download.csdn.net/detail/chenzheng8975/9712326
0 0
- Android实现版本更新通知栏下载
- Android 实现通知栏通知APP版本更新
- android客户端版本检测更新,服务下载,通知栏显示
- android客户端版本检测更新,服务下载,通知栏显示
- android 客户端版本检测更新,服务下载,通知栏显示
- Android Service 实现下载,实现前台、通知栏同步更新
- android实现通知栏下载更新app示例
- Android下载,在通知栏更新进度
- android 实现版本更新和下载安装
- Android通知栏实现APP下载更新(DownloadManager和自定义Notification2种方式实现)
- Android通知栏实现APP下载更新(DownloadManager和自定义Notification2种方式实现)
- 安卓自动更新,静默更新,替换友盟更新可以在通知栏里显示更新下载进度,几行代码快速实现Android下载更新
- android 实现apk下载展现通知栏
- Android 检查更新版本(带有通知栏,进度条,Notification)
- 【Android】Web开发之通知栏下载更新APP
- 【Android】Web开发之通知栏下载更新APP
- Android APP 版本更新通知代码
- Android版本更新及下载进度条的实现
- ubuntu14.04搭建git服务器及初次推送错误解决办法
- 翼机门禁网络不能PING通的解决办法
- Android TV机顶盒开发简单介绍
- 使用iOS多媒体框架实现视频倒放
- Systrace工具
- Android实现版本更新通知栏下载
- 微信HTML5小游戏之飞机大战
- 导入第三方库unknown type name 'NSString'解决
- 【BZOJ2242】[SDOI2011]计算器
- Eclipse快捷键
- Java7语法新特性
- Android中的5种数据存储方式
- 常用的cmd命令
- c#定时器