DownloadManager+Rxjava实现显示进度的文件下载

先看一下效果,有点问题是进度更新不够连续,通过query得到到的进度就这个屎样,几乎是按一秒一秒变的,我设置轮询的时间间隔是500毫秒,但是不顶用,跟1秒的效果一样:
DownloadManager+Rxjava实现显示进度的文件下载_第1张图片
说多了都是泪,话都在代码里。

public class DownloadActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "DownloadActivity";
    private static final String PACKAGE_URL = "http://gdown.baidu.com/data/wisegame/8d5889f722f640c8/weixin_800.apk";
    private long mDownloadId;
    private DownloadManager manager;
    private DownloadManager.Request request;
    private boolean isCompleted;
    private ProgressDialog mProgressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_download);
        initView();
    }

    private void initView() {
        // 下载请求对象
        request = new DownloadManager.Request(Uri.parse(PACKAGE_URL))
                .setAllowedOverRoaming(false)//漫游网络是否可以下载
                .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI)//仅在wifi下执行下载
                .setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN)//通知栏隐藏(默认可见)
                .setVisibleInDownloadsUi(true)//下载时可见(默认可见)
                .setDestinationInExternalPublicDir("/download/", "WeChart.apk");//设置下载路径,在Download文件夹下
        manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

        mProgressDialog = getProgressDialog();
        Button downloadButton = (Button) findViewById(R.id.download_button);
        downloadButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        //执行下载任务,反馈downloadId
        mDownloadId = manager.enqueue(request);

        //使用RxJava对下载信息进行轮询,500毫秒一次
        Observable.interval(300, 500, TimeUnit.MILLISECONDS)
                .takeUntil(new Func1() {
                    @Override
                    public Boolean call(Long aLong) {
                        return isCompleted;
                    }
                })
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1() {
                    @Override
                    public void call(Long aLong) {
                        checkDownloadStatus();
                    }
                });
    }

    private void checkDownloadStatus() {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(mDownloadId);//筛选下载任务,传入任务ID,可变参数
        Cursor cursor = manager.query(query);
        if (cursor.moveToFirst()) {
            long downloadedBytes = cursor.getLong(
                    cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
            long totalBytes = cursor.getLong(
                    cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
            mProgressDialog.setMax(((int) (totalBytes / 1024)));
            int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
            switch (status) {
                case DownloadManager.STATUS_RUNNING:
                    mProgressDialog.setProgress(((int) (downloadedBytes / 1024)));
                    if(!mProgressDialog.isShowing()){
                        mProgressDialog.show();
                    }
                    break;
                case DownloadManager.STATUS_SUCCESSFUL:
                    isCompleted = true;
                    if(mProgressDialog.isShowing()){
                        mProgressDialog.dismiss();
                    }
                    break;
            }
        }
        cursor.close();
    }

    private ProgressDialog getProgressDialog() {
        ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setProgressNumberFormat("%1d KB/%2d KB");
        progressDialog.setMessage("正在更新...");
        progressDialog.setIndeterminate(false);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setCancelable(true);
        return progressDialog;
    }
}

记得在清单文件声明权限,最后一条在通知栏不显示进度要用到:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />

Rxjava真是好东西,如此轻易就实现了轮询,在这里替代了ContentObserver或ScheduledExecutorService,省去了Handler直接实现了对下载进度的监听和ProgressDialog的更新。

参考链接:http://xuanzhui.iteye.com/blog/2258923

你可能感兴趣的:(功能库,Rxjava)