转 android客户端版本检测更新,服务下载,通知栏显示
看图, 只要点击取消或是下载完毕 通知才会消失!

代码是大部分是借用别人的,再自己修改,达到自己所需要的效果
xml文件
update.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/newlogin_bg"
- android:orientation="vertical" >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="4dp"
- android:layout_marginTop="10dp"
- android:text="正在下载..."
- android:textColor="#000" />
- <TextView
- android:id="@+id/currentPos"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="6dp"
- android:layout_marginLeft="4dp"
- android:layout_marginTop="10dp"
- android:textColor="#000" />
- <ProgressBar
- android:id="@+id/progressbar1"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_margin="4dp"
- android:max="100"
- android:progress="0" />
- <Button
- android:id="@+id/cancel"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="10dp"
- android:minWidth="200dp"
- android:text="取消" />
- </LinearLayout>
download_notification_layout.xml
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:orientation="vertical" >
- <LinearLayout
- android:layout_centerInParent="true"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="3dp"
- android:layout_marginRight="3dp"
- android:orientation="vertical" >
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal" >
- <ImageView
- android:id="@+id/image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/icon" />
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="3dp"
- android:layout_marginRight="3dp"
- android:orientation="vertical" >
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="2dp"
- android:orientation="horizontal" >
- <TextView
- android:id="@+id/name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:text="xxxx.apk"
- android:textColor="#000" />
- <TextView
- android:id="@+id/tv_progress"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:gravity="center"
- android:minWidth="60dp"
- android:textColor="#000" />
- </LinearLayout>
- <ProgressBar
- android:id="@+id/progressbar"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginRight="4dp"
- android:layout_marginTop="3dp"
- android:max="100"
- android:progress="0"
- android:text="xxxx.apk" />
- </LinearLayout>
- </LinearLayout>
- </LinearLayout>
- </RelativeLayout>
MyApp
- package com.zeng.update;
- import android.app.Application;
- public class MyApp extends Application {
- private boolean isDownload;
- @Override
- public void onCreate() {
- // TODO Auto-generated method stub
- super.onCreate();
- isDownload = false;
- }
- public boolean isDownload() {
- return isDownload;
- }
- public void setDownload(boolean isDownload) {
- this.isDownload = isDownload;
- }
- }
Main
- package com.zeng.update;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.content.pm.PackageInfo;
- import android.content.pm.PackageManager;
- import android.content.pm.PackageManager.NameNotFoundException;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class Main extends Activity {
- private Button btn_check;
- private MyApp app;
- private int currentVersionCode;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- app = (MyApp) getApplication();
- btn_check = (Button) findViewById(R.id.check);
- btn_check.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- PackageManager manager = Main.this.getPackageManager();
- try {
- PackageInfo info = manager.getPackageInfo(Main.this.getPackageName(), 0);
- String appVersion = info.versionName; // 版本名
- currentVersionCode = info.versionCode; // 版本号
- System.out.println(currentVersionCode + " " + appVersion);
- } catch (NameNotFoundException e) {
- // TODO Auto-generated catch blockd
- e.printStackTrace();
- }
- //上面是获取manifest中的版本数据,我是使用versionCode
- //在从服务器获取到最新版本的versionCode,比较
- showUpdateDialog();
- }
- });
- }
- private void showUpdateDialog() {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("检测到新版本");
- builder.setMessage("是否下载更新?");
- builder.setPositiveButton("下载", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub
- Intent it = new Intent(Main.this, NotificationUpdateActivity.class);
- startActivity(it);
- // MapApp.isDownload = true;
- app.setDownload(true);
- }
- }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub
- }
- });
- builder.show();
- }
- }
NotificationUpdateActivity 这个我加了一个启动模式 SingleTask
- package com.zeng.update;
- import com.zeng.update.DownloadService.DownloadBinder;
- import android.app.Activity;
- import android.content.ComponentName;
- import android.content.Context;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.content.SharedPreferences;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.IBinder;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.ProgressBar;
- import android.widget.TextView;
- public class NotificationUpdateActivity extends Activity {
- private Button btn_cancel;// btn_update,
- private TextView tv_progress;
- private DownloadBinder binder;
- private boolean isBinded;
- private ProgressBar mProgressBar;
- // 获取到下载url后,直接复制给MapApp,里面的全局变量
- private String downloadUrl;
- //
- private boolean isDestroy = true;
- private MyApp app;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.update);
- app = (MyApp) getApplication();
- // btn_update = (Button) findViewById(R.id.update);
- btn_cancel = (Button) findViewById(R.id.cancel);
- tv_progress = (TextView) findViewById(R.id.currentPos);
- mProgressBar = (ProgressBar) findViewById(R.id.progressbar1);
- btn_cancel.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- binder.cancel();
- binder.cancelNotification();
- finish();
- }
- });
- }
- ServiceConnection conn = new ServiceConnection() {
- @Override
- public void onServiceDisconnected(ComponentName name) {
- // TODO Auto-generated method stub
- isBinded = false;
- }
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- // TODO Auto-generated method stub
- binder = (DownloadBinder) service;
- System.out.println("服务启动!!!");
- // 开始下载
- isBinded = true;
- binder.addCallback(callback);
- binder.start();
- }
- };
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- if (isDestroy && app.isDownload()) {
- Intent it = new Intent(NotificationUpdateActivity.this, DownloadService.class);
- startService(it);
- bindService(it, conn, Context.BIND_AUTO_CREATE);
- }
- System.out.println(" notification onresume");
- }
- @Override
- protected void onNewIntent(Intent intent) {
- // TODO Auto-generated method stub
- super.onNewIntent(intent);
- if (isDestroy && app.isDownload()) {
- Intent it = new Intent(NotificationUpdateActivity.this, DownloadService.class);
- startService(it);
- bindService(it, conn, Context.BIND_AUTO_CREATE);
- }
- System.out.println(" notification onNewIntent");
- }
- @Override
- protected void onStart() {
- // TODO Auto-generated method stub
- super.onStart();
- }
- @Override
- protected void onPause() {
- // TODO Auto-generated method stub
- super.onPause();
- System.out.println(" notification onPause");
- }
- @Override
- protected void onStop() {
- // TODO Auto-generated method stub
- super.onStop();
- isDestroy = false;
- System.out.println(" notification onStop");
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (isBinded) {
- System.out.println(" onDestroy unbindservice");
- unbindService(conn);
- }
- if (binder != null && binder.isCanceled()) {
- System.out.println(" onDestroy stopservice");
- Intent it = new Intent(this, DownloadService.class);
- stopService(it);
- }
- }
- private ICallbackResult callback = new ICallbackResult() {
- @Override
- public void OnBackResult(Object result) {
- // TODO Auto-generated method stub
- if ("finish".equals(result)) {
- finish();
- return;
- }
- int i = (Integer) result;
- mProgressBar.setProgress(i);
- // tv_progress.setText("当前进度 => "+i+"%");
- // tv_progress.postInvalidate();
- mHandler.sendEmptyMessage(i);
- }
- };
- private Handler mHandler = new Handler() {
- public void handleMessage(android.os.Message msg) {
- tv_progress.setText("当前进度 : " + msg.what + "%");
- };
- };
- public interface ICallbackResult {
- public void OnBackResult(Object result);
- }
- }
DownloadService
- package com.zeng.update;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.util.List;
- import com.zeng.update.NotificationUpdateActivity.ICallbackResult;
- import android.app.Notification;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.app.Service;
- import android.content.Context;
- import android.content.Intent;
- import android.net.Uri;
- import android.os.Binder;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Message;
- import android.widget.RemoteViews;
- public class DownloadService extends Service {
- private static final int NOTIFY_ID = 0;
- private int progress;
- private NotificationManager mNotificationManager;
- private boolean canceled;
- // 返回的安装包url
- private String apkUrl = "http://softfile.3g.qq.com:8080/msoft/179/24659/43549/qq_hd_mini_1.4.apk";
- // private String apkUrl = MyApp.downloadApkUrl;
- /* 下载包安装路径 */
- private static final String savePath = "/sdcard/updateApkDemo/";
- private static final String saveFileName = savePath + "3GQQ_AppUpdate.apk";
- private ICallbackResult callback;
- private DownloadBinder binder;
- private MyApp app;
- private boolean serviceIsDestroy = false;
- private Context mContext = this;
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // TODO Auto-generated method stub
- super.handleMessage(msg);
- switch (msg.what) {
- case 0:
- app.setDownload(false);
- // 下载完毕
- // 取消通知
- mNotificationManager.cancel(NOTIFY_ID);
- installApk();
- break;
- case 2:
- app.setDownload(false);
- // 这里是用户界面手动取消,所以会经过activity的onDestroy();方法
- // 取消通知
- mNotificationManager.cancel(NOTIFY_ID);
- break;
- case 1:
- int rate = msg.arg1;
- app.setDownload(true);
- if (rate < 100) {
- RemoteViews contentview = mNotification.contentView;
- contentview.setTextViewText(R.id.tv_progress, rate + "%");
- contentview.setProgressBar(R.id.progressbar, 100, rate, false);
- } else {
- System.out.println("下载完毕!!!!!!!!!!!");
- // 下载完毕后变换通知形式
- mNotification.flags = Notification.FLAG_AUTO_CANCEL;
- mNotification.contentView = null;
- Intent intent = new Intent(mContext, NotificationUpdateActivity.class);
- // 告知已完成
- intent.putExtra("completed", "yes");
- // 更新参数,注意flags要使用FLAG_UPDATE_CURRENT
- PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent,
- PendingIntent.FLAG_UPDATE_CURRENT);
- mNotification.setLatestEventInfo(mContext, "下载完成", "文件已下载完毕", contentIntent);
- //
- serviceIsDestroy = true;
- stopSelf();// 停掉服务自身
- }
- mNotificationManager.notify(NOTIFY_ID, mNotification);
- break;
- }
- }
- };
- //
- // @Override
- // public int onStartCommand(Intent intent, int flags, int startId) {
- // // TODO Auto-generated method stub
- // return START_STICKY;
- // }
- @Override
- public IBinder onBind(Intent intent) {
- // TODO Auto-generated method stub
- System.out.println("是否执行了 onBind");
- return binder;
- }
- @Override
- public void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- System.out.println("downloadservice ondestroy");
- // 假如被销毁了,无论如何都默认取消了。
- app.setDownload(false);
- }
- @Override
- public boolean onUnbind(Intent intent) {
- // TODO Auto-generated method stub
- System.out.println("downloadservice onUnbind");
- return super.onUnbind(intent);
- }
- @Override
- public void onRebind(Intent intent) {
- // TODO Auto-generated method stub
- super.onRebind(intent);
- System.out.println("downloadservice onRebind");
- }
- @Override
- public void onCreate() {
- // TODO Auto-generated method stub
- super.onCreate();
- binder = new DownloadBinder();
- mNotificationManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);
- setForeground(true);// 这个不确定是否有作用
- app = (MyApp) getApplication();
- }
- public class DownloadBinder extends Binder {
- public void start() {
- if (downLoadThread == null || !downLoadThread.isAlive()) {
- progress = 0;
- setUpNotification();
- new Thread() {
- public void run() {
- // 下载
- startDownload();
- };
- }.start();
- }
- }
- public void cancel() {
- canceled = true;
- }
- public int getProgress() {
- return progress;
- }
- public boolean isCanceled() {
- return canceled;
- }
- public boolean serviceIsDestroy() {
- return serviceIsDestroy;
- }
- public void cancelNotification() {
- mHandler.sendEmptyMessage(2);
- }
- public void addCallback(ICallbackResult callback) {
- DownloadService.this.callback = callback;
- }
- }
- private void startDownload() {
- // TODO Auto-generated method stub
- canceled = false;
- downloadApk();
- }
- //
- Notification mNotification;
- // 通知栏
- /**
- * 创建通知
- */
- private void setUpNotification() {
- int icon = R.drawable.icon;
- CharSequence tickerText = "开始下载";
- long when = System.currentTimeMillis();
- mNotification = new Notification(icon, tickerText, when);
- ;
- // 放置在"正在运行"栏目中
- mNotification.flags = Notification.FLAG_ONGOING_EVENT;
- RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.download_notification_layout);
- contentView.setTextViewText(R.id.name, "腾讯QQ.apk 正在下载...");
- // 指定个性化视图
- mNotification.contentView = contentView;
- Intent intent = new Intent(this, NotificationUpdateActivity.class);
- // 下面两句是 在按home后,点击通知栏,返回之前activity 状态;
- // 有下面两句的话,假如service还在后台下载, 在点击程序图片重新进入程序时,直接到下载界面,相当于把程序MAIN 入口改了 - -
- // 是这么理解么。。。
- // intent.setAction(Intent.ACTION_MAIN);
- // intent.addCategory(Intent.CATEGORY_LAUNCHER);
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent,
- PendingIntent.FLAG_UPDATE_CURRENT);
- // 指定内容意图
- mNotification.contentIntent = contentIntent;
- mNotificationManager.notify(NOTIFY_ID, mNotification);
- }
- //
- /**
- * 下载apk
- *
- * @param url
- */
- private Thread downLoadThread;
- private void downloadApk() {
- downLoadThread = new Thread(mdownApkRunnable);
- downLoadThread.start();
- }
- /**
- * 安装apk
- *
- * @param url
- */
- private void installApk() {
- File apkfile = new File(saveFileName);
- if (!apkfile.exists()) {
- return;
- }
- Intent i = new Intent(Intent.ACTION_VIEW);
- i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
- mContext.startActivity(i);
- callback.OnBackResult("finish");
- }
- private int lastRate = 0;
- private Runnable mdownApkRunnable = new Runnable() {
- @Override
- public void run() {
- try {
- URL url = new URL(apkUrl);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.connect();
- int length = conn.getContentLength();
- InputStream is = conn.getInputStream();
- File file = new File(savePath);
- if (!file.exists()) {
- file.mkdirs();
- }
- String apkFile = saveFileName;
- File ApkFile = new File(apkFile);
- FileOutputStream fos = new FileOutputStream(ApkFile);
- int count = 0;
- byte buf[] = new byte[1024];
- do {
- int numread = is.read(buf);
- count += numread;
- progress = (int) (((float) count / length) * 100);
- // 更新进度
- Message msg = mHandler.obtainMessage();
- msg.what = 1;
- msg.arg1 = progress;
- if (progress >= lastRate + 1) {
- mHandler.sendMessage(msg);
- lastRate = progress;
- if (callback != null)
- callback.OnBackResult(progress);
- }
- if (numread <= 0) {
- // 下载完成通知安装
- mHandler.sendEmptyMessage(0);
- // 下载完了,cancelled也要设置
- canceled = true;
- break;
- }
- fos.write(buf, 0, numread);
- } while (!canceled);// 点击取消就停止下载.
- fos.close();
- is.close();
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- };
- }
参照博客
http://blog.csdn.net/liuhe688/article/details/6623924
还有些代码是另一个下载的demo的 不过忘了哪下的~
源码下载
http://download.csdn.net/detail/zgf1991/5725471
转 android客户端版本检测更新,服务下载,通知栏显示的更多相关文章
- 体验极速Android SDK的更新与下载
首先:国内明确一点,国内由于天朝限制了google,更新和下载Android相关资料都比较吃力,因此,本文正式宣告,此问题不再是问题-------别说话,吻我 先给点福利: 关于java(Androi ...
- Android应用程序更新并下载
创建一个新类,名为UpdateManager,代码如下: package com.af.service; import java.io.BufferedReader; import java.io.F ...
- android客户端app和服务端交互token的作用
Android客户端和服务端如何使用Token和Session niceheart关注1人评论34644人阅读2014-09-16 16:38:44 对于初学者来说,对Token和Session的 ...
- 微信app支付android客户端以及.net服务端实现
由于公司运营需要,需要在客户端(android/ios)增加微信以及支付宝支付,在调用微信app支付时遇到一些问题,也算是一些踩过的坑,记录下来 ,希望能对.net开发者服务端网站更快的集成微信app ...
- Android客户端与PC服务端、android服务端通过WiFi通信
前期准备:我的是Linux Mint操作系统(总之折腾的过程中怀疑过是不是系统的问题),首先是要创建wifi热点给android手机使用,这个时候笔记本作为通信的服务器端,android手机作为客户端 ...
- Android客户端与PHP服务端交互(一)---框架概述
背景 作为一个普通上班族,总是想做一些自认为有意义的事情,于是乎准备成立一个工作室,尽管目前正在筹备阶段,但是之前有些朋友提出一些需求的时候,我发现自己的能力还是有限,直到最近和一些技术牛朋友聊起这事 ...
- 解决Android SDK Manager 更新、下载慢以及待安装包列表不显示
参考地址:http://www.cnblogs.com/tc310/archive/2012/12/21/2828450.html 问题描述: Android SDK Manager 无法下载更新,或 ...
- Android客户端中Bitmap的下载过程和缓存机制
加载流程: if(内存命中){ 从内存中读取 }else{ create AsyncTasks,task中的多个Runnable是通过堆栈先进后出的方式来调度,而非队列式的先进先出 ...
- android客户端向java服务端post发送json
android 端: private void HttpPostData() { try { HttpClient httpclient = new DefaultHttpClient( ...
随机推荐
- CTRL key
ctrl key其实是用于扩展键盘,单独一个ctrl键没有什么作用,也没有ascii码,当与其他键相结合时,相当于创造出一个新键.例如:用getchar()侦测输入的字符,当按下ctrl+a时,只输出 ...
- Windows系统与Linux系统之间资源samba共享【转】
配置SAMBA服务器来实现在Windows计算机与Linux计算机之间的用户级的资源共享,九河网络TOM[2694339173]教你怎样操作: SAMBA服务器的基本配置 配置SAMBA服务器来实现在 ...
- C陷阱与缺陷 第一章
1. 使用 e1=e2的赋值方式 作为 条件语句内部的判断,请使用显示的判断 不使用: if( x =y ) foo(); 而使用: ) foo(); 2. 注意编码规范,一定要在赋值号 “=”两边, ...
- Boost的VS开发环境搭建
1. 下载并解压Boost C++ Libs 下载地址: SourceForge:http://sourceforge.net/projects/boost/files/boost/1.48.0/ B ...
- Win7 “Bluetooth设置”对话框无法打开,及无法查找到设备
方法是在百度上找到的,试用成功. 1.打开开始菜单中的运行选项,然后在对话框中输入services.msc,回车打开服务界面: 2.然后在弹出来的服务窗口中查找到Bluetooth Support S ...
- rs.Open sql,conn,0,2,1
例子:rs.Open sql,conn,0,2,1 CursorType = 0,默认值,打开仅向前类型游标.LockType = 2, 开放式锁定Options = 1, 指示 ADO 生成 SQL ...
- windows MySQL 安装
MySQL安装文件分为两种,一种是msi格式的,一种是zip格式的.如果是msi格式的可以直接点击安装,按照它给出的安装提示进行安装(相信大家的英文可以看懂英文提示),一般MySQL将会安装在C:\P ...
- javaScript 新学习:Array.contains 函数
Array.contains 函数 确定指定对象是否是 Array 对象中的元素. 此函数是静态的,可在不创建对象实例的情况下调用. var itemExists = Array.contains(a ...
- java方法:flush()
flush本意是冲刷,这个方法大概取自它引申义冲马桶的意思,马桶有个池子,你往里面扔东西,会暂时保存在池子里,只有你放水冲下去,东西才会进入下水道. 同理很多流都有一个这样的池子,专业术语叫缓冲区,当 ...
- easyui formatter 返回easyui组件
<table id="dg2" title="标题" style="width:400px;float: left;"> < ...