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

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

2015-07-01 09:44 851 查看


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

看图, 只要点击取消或是下载完毕 通知才会消失!






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

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

版权声明:本文为博主原创文章,未经博主允许不得转载。



上一篇类似网易新闻客户端首页的图片浏览,右下角显示当前第几个图片

下一篇schedule(TimerTask
task, long delay, long period) 抛 IllegalArgumentException

主题推荐android

猜你在找

iOS8开发技术(Swift版):iOS基础知识
反编译Android应用
Struts实战-使用SSH框架技术开发学籍管理系统
零基础学Java系列从入门到精通
火星人敏捷开发1001问(第一季)

android ScrollView中嵌套GridViewListView只显示一行的解决办法
Android Service 详解四开始停止service
MIUI的root权限管理分析
android ListView几个比较特别的属性
Android网络连接的理解

准备好了么? 跳吧 !更多职位尽在 CSDN
JOB

HTML/CSS/JS前端工程师

百洋健康网
|

5-8K/月
我要跳槽

java,android,ios开发

杭州洽诚网络技术有限公司
|

10-15K/月
我要跳槽

J***A/JSP开发工程师

天津信航惠民商务信息咨询有限公司
|

8-12K/月
我要跳槽

J***A(JSP)软件工程师

同方知好乐教育科技(北京)有限公司
|

15-20K/月
我要跳槽

查看评论

4楼 宠爱是种习惯 2014-01-02 11:39发表 [回复]


请问您判断了版本是否更新吗?我没有找到方法,问下

Re: zgf1991 2014-01-03 12:35发表 [回复]


回复u010246312:这个是测试demo,没有。这个调接口就行啊,具体怎么体现需要更新,和服务器协商好就行

Re: 宠爱是种习惯 2014-01-03 14:42发表 [回复]


回复zgf1991:好的,谢谢你了!

3楼 androidk123 2013-07-08 16:07发表 [回复]


求manifest.xml文件

Re: zgf1991 2013-07-09 14:24发表 [回复]


回复u011338758: 已上传资源

2楼 yang735642758 2013-06-19 11:56发表 [回复] [引用] [举报]


邮箱1657369437@qq.com

Re: zgf1991 2013-07-02 15:40发表 [回复] [引用] [举报]


回复yang735642758:不好意思,上次回家后就忘了,这么久了 不用了吧.... 有时间我上传个资源.

1楼 yang735642758 2013-06-19 11:56发表 [回复]


有没有源码能不能发一份给我

我照着写没有错但是下载不了

求源码行吗
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: