• 【转】 Pro Android学习笔记(七五):HTTP服务(9):DownloadManager


    目录(?)[-]

    1. 小例子
    2. 保存在哪里下载文件信息设置和读取
    3. 查看下载状态和取消下载

    文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件,转载须注明出处:http://blog.csdn.net/flowingflying/

    应用有时需要从web中下载一个大文件,并保存在本地,这个操作过程是标准的,因此在Android2.3引入了DownloadManager类。相关的学习也可以参考Android学习笔记(四六):互联网通信-文件下载

    小例子

    先看一个小例子,如下图所示。layout由一个button和一个textview组成,textview用于显示信息。用户按Start按键后,通过Download在后台下载文件,在通知栏中有提示,可以查看下载进度。当下载结束,通知栏的相关信息也将被清除。Android系统有一个下载管理器Downloads,可以查看通过DownloadManager下载的文件情况。

    源程序如下:

    public class DownloadMrgActivity extends Activity{ 
        private TextView tv = null; 
        private DownloadManager manager = null; 
        private long downloadId = -1;  
         
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.download_mrg); 
            tv = (TextView)findViewById(R.id.tv); 
        } 

        //【1】通过获取Download_Service的reference来获得DownloadManager实例 
        protected void onResume() {  
            super.onResume(); 
            manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
            showInfo("get DownloadManager instance : " + manager);

        } 
        //【2】向DownloadManager请求下载某图片 
        public void doDownload(View v){  //按Button触发 android:onClick="doDoownload"
            showInfo("doDownload() is called"); 
           /*【2.1】设置请求 */ 
           DownloadManager.Request dmReq = new DownloadManager.Request

                    Uri.parse("http://ww1.sinaimg.cn/large/5cf79a90jw1ecy18vfwlrj20xc18gtgd.jpg")); 
            dmReq.setTitle(getResources().getString(R.string.download_manager));//下来通知栏,显示信息的title
            dmReq.setDescription("食指大动");  //下来通知栏,显示信息的描述 
            dmReq.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);//缺省不作限制,本例在此设置只允许WIFI连接时下载,也可以设置为NETWORK_MOBILE
            /* 【2.2】DownloadManager在后台下载完成后,会进行广播通知,设置通知接收器:先设置过滤条件,再register接收器*/
            IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
            registerReceiver(myReceiver, filter); 
            /* 【2.3】 向DownloadManager提交请求,并获得id,该id用于对应该请求的处理 */
            downloadId = manager.enqueue(dmReq);
     
            showInfo("downloadId = " + downloadId);
        } 
        /*【2.2.1】设置DownloadManager的广播接收器*/ 
        public BroadcastReceiver myReceiver = new BroadcastReceiver(){ 
            // 获取id号,可据此判断是哪个请求的完成。intent在之前已经学习过,可以用来唤起component,并传递信息,component包括activity、service、broadcast receiver以及content provider。此处正式broadcast receiver。
            public void onReceive(Context context, Intent intent) { 
                Bundle extras = intent.getExtras(); 
                long doneDownloadId = extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
               
                if(doneDownloadId != downloadId) 
                    return; 
                showInfo("Download with id " + doneDownloadId + " is finished.");
                showInfo("Download file uri is " + manager.getUriForDownloadedFile(doneDownloadId));
            } 
            
        };  
         
        //【3】与onResume()对应,进行一些清空处理,如unregister接收器,不再监听DownloadManager的广播
        protected void onPause() {  
            super.onPause(); 
            unregisterReceiver(myReceiver); 
            manager = null;
     
            downloadId = -1;
        } 

        private void showInfo(String s){
            Log.d("PRO-wei",s); 
            tv.setText(s + " " + tv.getText()); 
        } 
    }

    保存在哪里?(下载文件信息设置和读取)

    在Android 4.2开始,manager.getUriForDownloadedFile(id)将返回的scheme是content,小例子返回uri是content://downloads/my_downloads/<id>,没有给出路径,我找了很久都没有找到缺省存放在哪里。当然,有了uri,就可以进行读取,例如:

    InputStream input = getContentResolver().openInputStream(uri);

    但是,我们还是想知道具体存放在那里,可以通过下面的方式查看下载文件信息,还可以查询很多信息,具体可翻阅API的reference。

    Cursor c = manager.query(new DownloadManager.Query().setFilterById(doneDownloadId));
    if(c != null){ 
        c.moveToFirst(); 
        showInfo(c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME)));
        c.close(); 

    应该查询,文件放在一个隐秘的地方,难怪没能翻出来,LogCat截图如下:

    如果希望文件能否放在一个用户容易查找的地方,可以在请求中指定路径,如下:

    dmReq.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "fish.jpg");

    在指定路径后,uri给出的是文件的路径file:///mnt/sdcard/Download/fish.jpg。当然要正确运行,我们必须申请WRITE_EXTERNAL_STORAGE权限。

    实际上,我们并不需要知道文件路径或者content uri,也可读取文件,我们在layout中增加一个imageview控件,用于显示下载的图片,相关代码如下:

    try{  
        ParcelFileDescriptor pfd = manager.openDownloadedFile(doneDownloadId); 
        FileDescriptor fileDescriptor = pfd.getFileDescriptor();  
        Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);  
        pfd.close();  
        ImageView image = (ImageView)findViewById(R.id.download_image);  
        image.setImageBitmap(bitmap);  
    }catch(Exception e){  
        e.printStackTrace();  

    查看下载状态和取消下载

    在layout中增加一个Cancel按钮,触发cancelDownload()函数,用于取消下载。我们首先查询下载的状态,如果已经完成,不作处理,否则取消下载。

    public void cancelDownload(View v){ 
        if(downloadId > 0){ 
            Cursor c = manager.query(new DownloadManager.Query().setFilterById(downloadId));
            if(c == null) 
                return; 
            c.moveToFirst(); 
            int state = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
            if(state != DownloadManager.STATUS_FAILED && state != DownloadManager.STATUS_SUCCESSFUL){ 
                showInfo("Download is not finished, CANCEL it.");
                manager.remove(downloadId);  //如果文件已经下载完成,remove命令并不会删除文件 
                downloadId = -1; 
            }            
            c.close();            
        } 

    本博文涉及的例子代码,可以在Pro Android学习:Http service小例子中下载。

    相关链接: 我的Android开发相关文章

  • 相关阅读:
    [数据结构与算法 01] 什么是数据结构?什么是算法?联系是什么?常用的数据结构/算法有?
    程序员面试金典-面试题 16.05. 阶乘尾数
    程序员面试金典-面试题 16.04. 井字游戏
    程序员面试金典-面试题 16.02. 单词频率
    程序员面试金典-面试题 16.01. 交换数字
    程序员面试金典-面试题 10.11. 峰与谷
    程序员面试金典-面试题 10.10. 数字流的秩
    程序员面试金典-面试题 10.09. 排序矩阵查找
    程序员面试金典-面试题 10.05. 稀疏数组搜索
    程序员面试金典-面试题 10.03. 搜索旋转数组
  • 原文地址:https://www.cnblogs.com/blongfree/p/5048056.html
Copyright © 2020-2023  润新知