功能:版本更新、文件后台下载以及Notification显示进度条。
效果图:
主要代码:
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。
相关推荐
android实现Service后台下载Notification进度条
本篇文章主要介绍了Android实现Service下载文件,Notification显示下载进度,具有一定的参考价值,有兴趣的可以了解一下。
2.2.2 Android SDK版本说明 10 2.2.3 ADT配置 10 2.3 Android开发模拟器 11 2.3.1 创建模拟器 11 2.3.2 启动模拟器 13 2.3.3 键盘映射与模拟器控制 13 2.3.4 横屏与竖屏切换 14 第3章 第一个Android程序 15 ...
android用户界面之Notification教程实例汇总 android用户界面之TextView教程实例汇总 android用户界面之ScrollView教程实例汇总 android用户界面之PopupWindow教程实例汇总 android用户界面之ImageView教程实例汇总 ...
17.1 Android原始码下载 17.2 实机测试 17.2.1 NeoFreeRunner介绍 17.2.2 烧录androidfs.jffs2 17.3 Android移植技术概论 17.3.1 Android底层技术的重要性 17.3.2 Android移植项目介绍 17.3.3 Android的技术优点
2.3 Android SDK的下载和安装 2.3.1 下载Android SDK 2.3.2 安装Android SDK 2.3.3 创建Android虚拟设备 2.4 Eclipse的下载和安装 2.4.1 下载和安装Eclipse 2.4.2 安装和配置Eclipse中Android插件 2.5 使用Eclipse...
进度条Progress通知效果,该项目实现了实现Service后台下载Notification进度条,通过点击“开始下载”按钮,会弹出一个对话框,点击“确认下载”,会出现带有下载百分比的进度条,如效果图所示。
41、AIDL Service android中的跨进程调用 客户端,服务端见AidlService 42、BroadcastReceiver 接收广播消息 43、非UI线程中不能操作UI线程中的View测试 44、ImageSwitcher animation gesture实现可以滑动的跑马灯...
17.1 Android原始码下载 17.2 实机测试 17.2.1 NeoFreeRunner介绍 17.2.2 烧录androidfs.jffs2 17.3 Android移植技术概论 17.3.1 Android底层技术的重要性 17.3.2 Android移植项目介绍 17.3.3 Android的技术优点
17.1 android原始码下载 334 17.2 实机测试 335 17.2.1 neo freerunner 介绍 335 17.2.2 烧录androidfs.jffs2 336 17.3 android移植技术概论 337 17.3.1 android底层技术的重要性 337 17.3.2 ...
41、AIDL Service android中的跨进程调用 客户端,服务端见AidlService 42、BroadcastReceiver 接收广播消息 43、非UI线程中不能操作UI线程中的View测试 44、ImageSwitcher animation gesture实现可以滑动的跑马灯...
1.2.1 下载和安装Android SDK 5 1.2.2 安装Eclipse和ADT插件 7 1.3 Android常用开发工具的用法 10 1.3.1 创建、删除和浏览AVD 10 1.3.2 使用Android模拟器 (Emulator) 14 1.3.3 使用DDMS进行调试 15...
17.1 Android原始码下载 17.2 实机测试 17.2.1 NeoFreeRunner介绍 17.2.2 烧录androidfs.jffs2 17.3 Android移植技术概论 17.3.1 Android底层技术的重要性 17.3.2 Android移植项目介绍 17.3.3 Android的技术优点 ·...
17.1 Android原始码下载 334 17.2 实机测试 335 17.2.1 Neo FreeRunner 介绍 335 17.2.2 烧录androidfs.jffs2 336 17.3 Android移植技术概论 337 17.3.1 Android底层技术的重要性 337 17.3.2 ...
Notification 普通通知,大通知,进度条通知,自定义通知 service 普通service 和 intentservice(自带线程,只需实现onHandleIntent方法)
11.3.3 文件下载 11.3.4 文件上传 11.4 HttpClient 11.4.1 HttpGet请求 11.4.2 HttpPost请求 11.5 本章小结 第12章 数据解析 12.1 XML 12.1.1 DOM 12.1.2 SAX 12.1.3 PULL 12.2 JSON格式 12.2.1 基本类型 12.2.2 ...
1.2.1 下载和安装Android SDK 5 1.2.2 安装Eclipse和ADT插件 7 1.3 Android常用开发工具的用法 10 1.3.1 创建、删除和浏览AVD 10 1.3.2 使用Android模拟器 (Emulator) 14 1.3.3 使用DDMS进行调试 15 1.3.4 Android...