您的位置:首页 > 移动开发 > Android开发

android客户端版本检测更新,服务下载,通知栏显示

2013-08-29 14:14 645 查看
看图, 只要点击取消或是下载完毕 通知才会消失!





代码是大部分是借用别人的,再自己修改,达到自己所需要的效果

xml文件

update.xml

[html] view
plaincopy

<?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

[html] view
plaincopy

<?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

[java] view
plaincopy

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

[java] view
plaincopy

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

[java] view
plaincopy

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

[java] view
plaincopy

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐