Android--retrofitを使用してダウンロード(ブレークポイントの継続、開始、停止)を実現
10624 ワード
Retrofitに詳しくないお客様に便利な通路を提供し、私たちの共同進歩を支援します.
InentServiceを起動してダウンロードすると、ダウンロードが完了すると自動的にサービスが停止します.
retrofit要求方法:
apiは次のように構成されています.
サービスを開始
一時停止してもいい
InentServiceを起動してダウンロードすると、ダウンロードが完了すると自動的にサービスが停止します.
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);
}