Android--retrofitを使用してダウンロード(ブレークポイントの継続、開始、停止)を実現

10624 ワード

Retrofitに詳しくないお客様に便利な通路を提供し、私たちの共同進歩を支援します.
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);
}