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

来源:互联网 发布:淘宝礼服店推荐知乎 编辑:程序博客网 时间:2024/05/21 14:58

先看一下效果,有点问题是进度更新不够连续,通过query得到到的进度就这个屎样,几乎是按一秒一秒变的,我设置轮询的时间间隔是500毫秒,但是不顶用,跟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<Long, Boolean>() {                    @Override                    public Boolean call(Long aLong) {                        return isCompleted;                    }                })                .subscribeOn(AndroidSchedulers.mainThread())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Action1<Long>() {                    @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

0 0
原创粉丝点击