apk下載服務(wù):
package com.xxx.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 com.xxx.base.SczwApplication;
import com.xxx.sczwdemo.R;
import com.xxx.update.UpdateNotifiActivity.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.util.Log;
import android.widget.RemoteViews;
/**
* @Date 2016-5-31 上午11:32:59
* @Author Arvin
* @Description 后臺(tái)下載新版apk服務(wù)
*/
public class DownloadService extends Service {
private static final String TAG = "DownloadService";
private Context mContext = this;
private static final int NOTIFY_ID = 0;
private int progress;
private NotificationManager mNotificationManager;
private boolean canceled;
// 返回的安裝包url
//http://softfile.3g.qq.com:8080/msoft/179/24659/43549/qq_hd_mini_1.4.apk
private String apkUrl = "應(yīng)用服務(wù)器地址";
/* 下載包安裝路徑 */
private static final String savePath = "/sdcard/updateApkDemo/";
private static final String saveFileName = savePath + "3GQQ_AppUpdate.apk";
private ICallbackResult callback;
private DownloadBinder binder;
private SczwApplication application;
private boolean serviceIsDestroy = false;
private Thread downLoadThread;
private Notification mNotification;
private int lastRate = 0;
private static final int MSG_OVER_CANCEL = 0;//下載完畢取消
private static final int MSG_UPDATE_PROGRESS = 1;//更新下載進(jìn)度
private static final int MSG_MANUAL_CANCEL = 2;//手動(dòng)取消
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case MSG_OVER_CANCEL:
application.setDownload(false);
// 下載完畢
// 取消通知
mNotificationManager.cancel(NOTIFY_ID);
installApk();
break;
case MSG_MANUAL_CANCEL:
application.setDownload(false);
// 這里是用戶界面手動(dòng)取消,所以會(huì)經(jīng)過(guò)activity的onDestroy();方法
// 取消通知
mNotificationManager.cancel(NOTIFY_ID);
break;
case MSG_UPDATE_PROGRESS:
int rate = msg.arg1;
application.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 {
// 下載完畢后變換通知形式
mNotification.flags = Notification.FLAG_AUTO_CANCEL;
mNotification.contentView = null;
Intent intent = new Intent(mContext, UpdateNotifiActivity.class);
// 告知已完成
intent.putExtra("completed", "yes");
// 更新參數(shù),注意flags要使用FLAG_UPDATE_CURRENT
PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
mNotification.setLatestEventInfo(mContext, "下載完成", "文件已下載完畢", contentIntent);
//
serviceIsDestroy = true;
stopSelf();// 停掉服務(wù)自身
}
mNotificationManager.notify(NOTIFY_ID, mNotification);
break;
}
}
};
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG,"是否執(zhí)行了 onBind");
return binder;
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i(TAG,"downloadservice ondestroy");
// 假如被銷毀了,無(wú)論如何都默認(rèn)取消了。
application.setDownload(false);
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG,"downloadservice onUnbind");
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
// TODO Auto-generated method stub
super.onRebind(intent);
Log.i(TAG,"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);// 這個(gè)不確定是否有作用
application = SczwApplication.getInstance();
}
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(MSG_MANUAL_CANCEL);
}
public void addCallback(ICallbackResult callback) {
DownloadService.this.callback = callback;
}
}
/**
* @Description 啟動(dòng)新版apk下載任務(wù)
* @param null
* @return void
* @throws
*/
private void startDownload() {
// TODO Auto-generated method stub
canceled = false;
downloadApk();
}
/**
* @Description 創(chuàng)建通知
* @param null
* @return void
* @throws
*/
private void setUpNotification() {
int icon = R.drawable.ic_launcher;
CharSequence tickerText = "開(kāi)始下載";
long when = System.currentTimeMillis();
mNotification = new Notification(icon, tickerText, when);
// 放置在"正在運(yùn)行"欄目中
mNotification.flags = Notification.FLAG_ONGOING_EVENT;
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.update_notif_ly);
contentView.setTextViewText(R.id.name, "騰訊QQ.apk 正在下載...");
// 指定個(gè)性化視圖
mNotification.contentView = contentView;
Intent intent = new Intent(this, UpdateNotifiActivity.class);
// 下面兩句是 在按home后,點(diǎn)擊通知欄,返回之前activity 狀態(tài);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
// 指定內(nèi)容意圖
mNotification.contentIntent = contentIntent;
mNotificationManager.notify(NOTIFY_ID, mNotification);
}
/**
* @Description 下載新版apk
* @param tags
* @return return_type
* @throws
*/
private void downloadApk() {
downLoadThread = new Thread(mdownApkRunnable);
downLoadThread.start();
}
/**
* @Description 安裝新版apk
* @param null
* @return void
* @throws
*/
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");
}
/**
* @Description 啟動(dòng)線程下載新版apk
* @param String
* @return null
* @throws
*/
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);
// 更新進(jìn)度
Message msg = mHandler.obtainMessage();
msg.what = MSG_UPDATE_PROGRESS;
msg.arg1 = progress;
if (progress >= lastRate + 1) {
mHandler.sendMessage(msg);
lastRate = progress;
if (callback != null)
callback.OnBackResult(progress);
}
if (numread <= 0) {
// 下載完成通知安裝
mHandler.sendEmptyMessage(MSG_OVER_CANCEL);
// 下載完了,cancelled也要設(shè)置
canceled = true;
break;
}
fos.write(buf, 0, numread);
} while (!canceled);// 點(diǎn)擊取消就停止下載.
fos.close();
is.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
應(yīng)用更新相關(guān)文章:
應(yīng)用更新之_UpdateNotifiActivity
應(yīng)用更新之_update_activity.xml
應(yīng)用更新之_update_notif_ly.xml
應(yīng)用更新之_permission