为 Retrofit 不太熟悉的小伙伴提供便捷通道助力我们共同进步
开启IntentService进行下载,在下载完毕,它会自动关闭服务
public class DownloadIntentService extends IntentService {
private static final String TAG = "DownloadIntentService";
private NotificationManager mNotifyManager;
private String mDownloadFileName;
private Notification mNotification;
private int progress;
private int downcode;
private RemoteViews remoteViews;
private int downloadId;
//retrofit订阅事件的监听
public static CompositeDisposable compositeDisposable = new CompositeDisposable();
public DownloadIntentService() {
super("InitializeService");
}
@Override
public int onStartCommand(@android.support.annotation.Nullable Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean stopService(Intent name) {
return super.stopService(name);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
String downloadUrl = intent.getExtras().getString("download_url");
downloadId = intent.getExtras().getInt("download_id");
mDownloadFileName = intent.getExtras().getString("download_file");
downcode = intent.getExtras().getInt("downcode");
Log.d(TAG, "download_url --" + downloadUrl);
Log.d(TAG, "download_file --" + mDownloadFileName);
//文件存储地址
final File file = new File(ConstantCode.APP_ROOT_PATH + ConstantCode.DOWNLOAD_DIR + mDownloadFileName);
long range = 0;
progress = 0;
if (file.exists()) {
range = SPDownloadUtil.getInstance().get(downloadUrl, 0);
progress = (int) (range * 100 / file.length());
if (range == file.length()) {
installApp(file);
return;
}
}
Log.d(TAG, "range = " + range);
//下载文件
remoteViews = new RemoteViews(getPackageName(), R.layout.notify_download);
remoteViews.setProgressBar(R.id.pb_progress, 100, progress, false);
remoteViews.setTextViewText(R.id.tv_progress, "已下载" + progress + "%");
final NotificationCompat.Builder builder =
new NotificationCompat.Builder(this)
.setContent(remoteViews)
.setTicker("正在下载")
.setSmallIcon(R.drawable.logo);
mNotification = builder.build();
mNotifyManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
mNotifyManager.notify(downloadId, mNotification);
HttpManager.getInstance().downloadFile(getApplication(), range, downloadUrl, mDownloadFileName, new DownloadCallBack() {
@Override
public void onProgress(int progress) {
DialogActivity.appHandler.sendEmptyMessage(progress);
SPUtils.put(getApplication(), "downProgressRange", progress);
remoteViews.setProgressBar(R.id.pb_progress, 100, progress, false);
remoteViews.setTextViewText(R.id.tv_progress, "已下载" + progress + "%");
mNotifyManager.notify(downloadId, mNotification);
}
@Override
public void onFileLength (String fileLength){
Log.d(TAG, "文件大小为:" + fileLength);
}
@Override
public void onCompleted () {
Log.d(TAG, "下载完成");
SPUtils.put(getApplication(), "downOnce", false);
SPUtils.put(getApplication(), "downFenish", true);
SPUtils.put(getApplication(), "downProgressRange", 9999);
mNotifyManager.cancel(downloadId);
installApp(file);
}
@Override
public void onError (String msg){
mNotifyManager.cancel(downloadId);
Log.d(TAG, "下载发生错误--" + msg);
}
});
}
//安装apk
private void installApp(File file) {
DialogActivity.appHandler.sendEmptyMessage(100);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(intent);
}
public void setCompositeDisposable() {
//暂停下载
if (!compositeDisposable.isDisposed()) {
if (compositeDisposable.size() != 0) {
compositeDisposable.clear();
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
retrofit请求方法:
/*
* 下载app
* */
public void downloadFile(Context context, final long range, final String url, final String fileName, final DownloadCallBack downloadCallback) {
//断点续传时请求的总长度
File file = new File(ConstantCode.APP_ROOT_PATH + ConstantCode.DOWNLOAD_DIR, fileName);
String totalLength = "-";
if (file.exists()) {
totalLength += file.length();
}
changeApiBaseUrl().executeDownload("bytes=" + Long.toString(range) + totalLength, url)
.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
DownloadIntentService.compositeDisposable.add(d);
}
@Override
public void onNext(ResponseBody responseBody) {
RandomAccessFile randomAccessFile = null;
InputStream inputStream = null;
long total = range;
long responseLength = 0;
try {
byte[] buf = new byte[2048];
int len = 0;
//剩余下载的长度
responseLength = responseBody.contentLength();
inputStream = responseBody.byteStream();
String filePath = ConstantCode.APP_ROOT_PATH + ConstantCode.DOWNLOAD_DIR;
File file = new File(filePath, fileName);
File dir = new File(filePath);
if (!dir.exists()) {
dir.mkdirs();
}
randomAccessFile = new RandomAccessFile(file, "rwd");
if (range == 0) {
randomAccessFile.setLength(responseLength);
}
randomAccessFile.seek(range);
int progress = 0;
int lastProgress = 0;
while ((len = inputStream.read(buf)) != -1) {
randomAccessFile.write(buf, 0, len);
total += len;
//cun
SPDownloadUtil.getInstance().save(url, total);
lastProgress = progress;
progress = (int) (total * 100 / randomAccessFile.length());
if (progress > 0 && progress != lastProgress && progress >= lastProgress) {
downloadCallback.onProgress(progress);
}
}
downloadCallback.onCompleted();
} catch (Exception e) {
Log.d("DownloadIntentService", e.getMessage());
downloadCallback.onError(e.getMessage());
e.printStackTrace();
} finally {
try {
if (randomAccessFile != null) {
randomAccessFile.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onError(Throwable e) {
downloadCallback.onError(e.toString());
}
@Override
public void onComplete() {
}
});
}
api配置如下内容
@Streaming
@GET
Observable executeDownload(@Header("Range") String range, @Url() String url);
开启服务
//开启服务
public void goDownLoad(int code) {
if (isServiceRunning(DownloadIntentService.class.getName())) {
Toast.makeText(DialogActivity.this, "正在下载", Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent(getApplicationContext(), DownloadIntentService.class);
Bundle bundle = new Bundle();
bundle.putString("download_url", '/' + download_url.substring(download_url.lastIndexOf('/') + 1));
bundle.putInt("download_id", DOWNLOADAPK_ID);
bundle.putInt("downcode", code);
bundle.putString("download_file", download_url.substring(download_url.lastIndexOf('/') + 1));
intent.putExtras(bundle);
startService(intent);
}
/**
* 用来判断服务是否运行.
*
* @param className 判断的服务名字
* @return true 在运行 false 不在运行
*/
private boolean isServiceRunning(String className) {
boolean isRunning = false;
ActivityManager activityManager = (ActivityManager) this
.getSystemService(Context.ACTIVITY_SERVICE);
List serviceList = activityManager
.getRunningServices(Integer.MAX_VALUE);
if (!(serviceList.size() > 0)) {
return false;
}
for (int i = 0; i < serviceList.size(); i++) {
if (serviceList.get(i).service.getClassName().equals(className) == true) {
isRunning = true;
break;
}
}
return isRunning;
}
暂停停止皆可以如此
//关闭服务 停止下载
public void stopFinishSer(){
//也就是取消订阅
if (!DownloadIntentService.compositeDisposable.isDisposed()) {
if (DownloadIntentService.compositeDisposable.size() != 0) {
DownloadIntentService.compositeDisposable.clear();
}
}
stopService(intent);
}