先看效果图: 这是本人的习惯,先上图显示效果,看是否是想要的,再看代码。有图有真相
代码:
main
1 package com.gem.hsx.appupdate; 2 3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.View; 7 import android.view.View.OnClickListener; 8 import android.widget.Button; 9 10 public class Main extends Activity { 11 12 @Override 13 public void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.main); 16 Button btnok=(Button) findViewById(R.id.btnok); 17 btnok.setOnClickListener(new BtnokOnClickListener()); 18 } 19 20 private class BtnokOnClickListener implements OnClickListener 21 { 22 23 @Override 24 public void onClick(View v) { 25 Intent updateIntent =new Intent(Main.this, UpdateService.class); 26 updateIntent.putExtra("titleId",R.string.app_name); 27 startService(updateIntent); 28 29 } 30 } 31 }
UpdateService:
1 package com.gem.hsx.appupdate; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.InputStream; 6 import java.net.HttpURLConnection; 7 import java.net.URL; 8 9 import android.app.Notification; 10 import android.app.NotificationManager; 11 import android.app.PendingIntent; 12 import android.app.Service; 13 import android.content.Intent; 14 import android.net.Uri; 15 import android.os.Environment; 16 import android.os.Handler; 17 import android.os.IBinder; 18 import android.os.Message; 19 20 public class UpdateService extends Service{ 21 //标题 22 private int titleId = 0; 23 private final static int DOWNLOAD_COMPLETE = 0; 24 private final static int DOWNLOAD_FAIL = 1; 25 //文件存储 26 private File updateDir = null; 27 private File updateFile = null; 28 29 //通知栏 30 private NotificationManager updateNotificationManager = null; 31 private Notification updateNotification = null; 32 //通知栏跳转Intent 33 private Intent updateIntent = null; 34 private PendingIntent updatePendingIntent = null; 35 @Override 36 public IBinder onBind(Intent intent) { 37 // TODO Auto-generated method stub 38 return null; 39 } 40 41 @Override 42 public void onCreate() { 43 44 super.onCreate(); 45 } 46 47 @Override 48 public int onStartCommand(Intent intent, int flags, int startId) { 49 //获取传值 50 titleId = intent.getIntExtra("titleId",0); 51 //创建文件 52 if(android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState())){ 53 updateDir = new File(Environment.getExternalStorageDirectory(),"app/download/"); 54 updateFile = new File(updateDir.getPath(),getResources().getString(titleId)+".apk"); 55 } 56 57 this.updateNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); 58 this.updateNotification = new Notification(); 59 60 //设置下载过程中,点击通知栏,回到主界面 61 updateIntent = new Intent(this, Main.class); 62 updatePendingIntent = PendingIntent.getActivity(this,0,updateIntent,0); 63 //设置通知栏显示内容 64 updateNotification.icon = R.drawable.ic_launcher; 65 updateNotification.tickerText = "开始下载"; 66 updateNotification.setLatestEventInfo(this,"上海地铁","0%",updatePendingIntent); 67 //发出通知 68 updateNotificationManager.notify(0,updateNotification); 69 70 //开启一个新的线程下载,如果使用Service同步下载,会导致ANR问题,Service本身也会阻塞 71 new Thread(new updateRunnable()).start();//这个是下载的重点,是下载的过程 72 73 return super.onStartCommand(intent, flags, startId); 74 } 75 private Handler updateHandler = new Handler(){ 76 @Override 77 public void handleMessage(Message msg) { 78 switch(msg.what){ 79 case DOWNLOAD_COMPLETE: 80 updateNotification.flags|=updateNotification.FLAG_AUTO_CANCEL; 81 //点击安装PendingIntent 82 Uri uri = Uri.fromFile(updateFile); 83 Intent installIntent = new Intent(Intent.ACTION_VIEW); 84 installIntent.setDataAndType(uri, "application/vnd.android.package-archive"); 85 updatePendingIntent = PendingIntent.getActivity(UpdateService.this, 0, installIntent, 0); 86 87 updateNotification.defaults = Notification.DEFAULT_SOUND;//铃声提醒 88 updateNotification.setLatestEventInfo(UpdateService.this, "上海地铁", "下载完成,点击安装。", updatePendingIntent); 89 updateNotificationManager.notify(0, updateNotification); 90 91 //停止服务 92 stopService(updateIntent); 93 case DOWNLOAD_FAIL: 94 //下载失败 95 updateNotification.setLatestEventInfo(UpdateService.this, "上海地铁", "下载完成,点击安装。", updatePendingIntent); 96 updateNotificationManager.notify(0, updateNotification); 97 default: 98 stopService(updateIntent); 99 } 100 } 101 }; 102 103 104 class updateRunnable implements Runnable { 105 Message message = updateHandler.obtainMessage(); 106 public void run() { 107 message.what = DOWNLOAD_COMPLETE; 108 try{ 109 //增加权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">; 110 if(!updateDir.exists()){ 111 updateDir.mkdirs(); 112 } 113 if(!updateFile.exists()){ 114 updateFile.createNewFile(); 115 } 116 //下载函数,以QQ为例子 117 //增加权限<uses-permission android:name="android.permission.INTERNET">; 118 long downloadSize = downloadUpdateFile("http://softfile.3g.qq.com:8080/msoft/179/1105/10753/MobileQQ1.0(Android)_Build0198.apk",updateFile); 119 if(downloadSize>0){ 120 //下载成功 121 updateHandler.sendMessage(message); 122 } 123 }catch(Exception ex){ 124 ex.printStackTrace(); 125 message.what = DOWNLOAD_FAIL; 126 //下载失败 127 updateHandler.sendMessage(message); 128 } 129 } 130 } 131 132 133 134 public long downloadUpdateFile(String downloadUrl, File saveFile) throws Exception { 135 //这样的下载代码很多,我就不做过多的说明 136 int downloadCount = 0; 137 int currentSize = 0; 138 long totalSize = 0; 139 int updateTotalSize = 0; 140 141 HttpURLConnection httpConnection = null; 142 InputStream is = null; 143 FileOutputStream fos = null; 144 145 try { 146 URL url = new URL(downloadUrl); 147 httpConnection = (HttpURLConnection)url.openConnection(); 148 httpConnection.setRequestProperty("User-Agent", "PacificHttpClient"); 149 if(currentSize > 0) { 150 httpConnection.setRequestProperty("RANGE", "bytes=" + currentSize + "-"); 151 } 152 httpConnection.setConnectTimeout(10000); 153 httpConnection.setReadTimeout(20000); 154 updateTotalSize = httpConnection.getContentLength(); 155 if (httpConnection.getResponseCode() == 404) { 156 throw new Exception("fail!"); 157 } 158 is = httpConnection.getInputStream(); 159 fos = new FileOutputStream(saveFile, false); 160 byte buffer[] = new byte[4096]; 161 int readsize = 0; 162 while((readsize = is.read(buffer)) > 0){ 163 fos.write(buffer, 0, readsize); 164 totalSize += readsize; 165 //为了防止频繁的通知导致应用吃紧,百分比增加10才通知一次 166 if((downloadCount == 0)||(int) (totalSize*100/updateTotalSize)-10>downloadCount){ 167 downloadCount += 10; 168 updateNotification.setLatestEventInfo(UpdateService.this, "正在下载", (int)totalSize*100/updateTotalSize+"%", updatePendingIntent); 169 updateNotificationManager.notify(0, updateNotification); 170 } 171 } 172 } finally { 173 if(httpConnection != null) { 174 httpConnection.disconnect(); 175 } 176 if(is != null) { 177 is.close(); 178 } 179 if(fos != null) { 180 fos.close(); 181 } 182 } 183 return totalSize; 184 } 185 186 }
AndroidManifest.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.gem.hsx.appupdate" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <uses-sdk android:minSdkVersion="15" /> 8 9 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 10 <uses-permission android:name="android.permission.INTERNET"/> 11 12 <application 13 android:icon="@drawable/ic_launcher" 14 android:label="@string/app_name" > 15 <activity 16 android:name=".Main" 17 android:label="@string/app_name" > 18 <intent-filter> 19 <action android:name="android.intent.action.MAIN" /> 20 21 <category android:name="android.intent.category.LAUNCHER" /> 22 </intent-filter> 23 </activity> 24 25 <service 26 android:name="UpdateService" 27 android:label="@string/app_name" > 28 </service> 29 </application> 30 31 </manifest>