package com.app.retrofit;
import android.app.ActivityManager;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;
import com.app.retrofit.api.Network;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;
/**
* author: Yangbin
* time : 2016/11/10 18:02
* desc : 下载app
*/
public class DownLoadAppService extends IntentService {
private static String TAG = "UpdataAppThread";
// NotificationManager : 是状态栏通知的管理类,负责发通知、清楚通知等。
private NotificationManager manager;
private int notifiId = 789;
private int progress = 0;
private String apkName;
// 定义Map来保存Notification对象
private Map<Integer, Notification> map = null;
public DownLoadAppService() {
super("DownLoadAppService");
}
public static void startDownLoadAppService(Context cxt, String apkName, String url) {
ActivityManager manager = (ActivityManager) cxt.getSystemService(ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (DownLoadAppService.class.getName().equals(service.service.getClassName())) {
Log.d(TAG, "-->不再启动服务,已经在下载更新了");
return;//退出不再继续执行
}
}
Intent startServiceIntent = new Intent(cxt, DownLoadAppService.class);
Bundle bundle2 = new Bundle();
bundle2.putString("apkName", apkName);
bundle2.putString("url", url);
startServiceIntent.putExtras(bundle2);
Log.d(TAG, "-->启动了下载服务");
cxt.startService(startServiceIntent);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
protected void onHandleIntent(Intent intent) {
//NotificationManager 是一个系统Service,必须通过 getSystemService()方法来获取。
manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
map = new HashMap<>();
this.apkName = intent.getExtras().getString("apkName");
String url = intent.getExtras().getString("url");
showNotification(notifiId);
Log.d(TAG, "-->同步下载开始");
// 启动后台服务下载apk
Call<ResponseBody> call = Network.getInstance().getApi().downloadFileWithDynamicUrlSync(url);
try {
Response<ResponseBody> response = call.execute();
if (response.isSuccessful()) {
Log.d(TAG, "server contacted and has file");
boolean writtenToDisk = writeResponseBodyToDisk(response.body());
Log.d(TAG, "file download was a success? " + writtenToDisk);
cancel(notifiId);
if (writtenToDisk) {
installApk();
} else {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast.makeText(DownLoadAppService.this, "更新失败", Toast.LENGTH_LONG).show();
}
});
}
} else {
Log.d(TAG, "server contact failed");
cancel(notifiId);
Toast.makeText(DownLoadAppService.this, "更新失败", Toast.LENGTH_LONG).show();
}
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, "-->同步下载结束");
}
/**
* 写入
*
* @param body
* @return
*/
private boolean writeResponseBodyToDisk(ResponseBody body) {
try {
// todo change the file location/name according to your needs
File futureStudioIconFile = new File(getExternalFilesDir(null) + File.separator + apkName);
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
inputStream = body.byteStream();
outputStream = new FileOutputStream(futureStudioIconFile);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
int pro = (int) (fileSizeDownloaded * 100 / fileSize);
if (pro > progress) {
progress = pro;
updateProgress(notifiId, pro);
Log.d(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
}
}
outputStream.flush();
return true;
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
/**
* 安装APK文件
*/
private void installApk() {
File apkfile = new File(getExternalFilesDir(null) + File.separator, apkName);
if (!apkfile.exists()) {
return;
}
// 通过Intent安装APK文件
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
startActivity(intent);
}
/**
* 显示通知
*/
public void showNotification(int notificationId) {
if (!map.containsKey(notificationId)) {
Notification notification = new Notification();
notification.tickerText = "正在开始下载文件...";
notification.when = System.currentTimeMillis();
notification.icon = R.mipmap.ic_launcher;
// 设置通知的特性: 通知被点击后,自动消失
notification.flags = Notification.FLAG_AUTO_CANCEL;
// 设置通知的显示视图
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_contentview);
notification.contentView = remoteViews;
// 发出通知
manager.notify(notificationId, notification);
map.put(notificationId, notification);// 存入Map中
}
}
/**
* 取消通知操作
*
* @param notificationId
*/
public void cancel(int notificationId) {
manager.cancel(notificationId);
map.remove(notificationId);
}
/**
* 显示进度
*
* @param notificationId
* @param progress
*/
public void updateProgress(int notificationId, int progress) {
this.progress = progress;
Notification notify = map.get(notificationId);
if (null != notify) {