zoukankan      html  css  js  c++  java
  • DownloadManager 的使用

    一、基本概念
        1、DownloadManager是Android 2.3A (API level 9) 引入的,基于http协议,用于处理长时间下载。

        2、DownloadManager对于断点续传功能支持很好 。

    二、权限设置(由于下载会需要SD卡存储,所以需要SD卡文件读写权限)

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

    三、request.setNotificationVisibility 可以用来控制什么时候显示Notification,甚至是隐藏该request的Notification 。

       1)Request.VISIBILITY_VISIBLE

              在下载进行的过程中,通知栏中会一直显示该下载的Notification,当下载完成时,该Notification会被移除,这是默认的参数值。

       (2)Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED

              在下载过程中通知栏会一直显示该下载的Notification,在下载完成后该Notification会继续显示,直到用户点击该Notification或者消除该Notification。

       (3)Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION

             只有在下载完成后该Notification才会被显示。

        (4)Request.VISIBILITY_HIDDEN

              不显示该下载请求的Notification。如果要使用这个参数,需要在应用的清单文件中加上DOWNLOAD_WITHOUT_NOTIFICATION权限。

     相对应的代码

       //设置状态栏中显示Notification

         //设置Notification的标题

        request.setTitle( "微信下载" ) ;

        request.setDescription( "5.3.6" ) ;


        request.setNotificationVisibility( Request.VISIBILITY_VISIBLE ) ;

        request.setNotificationVisibility( Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED ) ;

        request.setNotificationVisibility( Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION ) ;

        request.setNotificationVisibility( Request.VISIBILITY_HIDDEN ) ;

     四:下载的文件,存放路径

    /**
         * 设置下载文件存储目录
         */
        void setDownloadFilePath( Request request ){
            /**
             * 方法1: 
             * 目录: Android -> data -> com.app -> files -> Download -> 微信.apk
             * 这个文件是你的应用所专用的,软件卸载后,下载的文件将随着卸载全部被删除
             */
    
            //request.setDestinationInExternalFilesDir( this , Environment.DIRECTORY_DOWNLOADS ,  "微信.apk" );  
    
            /**
             * 方法2:
             * 下载的文件存放地址  SD卡 download文件夹,pp.jpg
             * 软件卸载后,下载的文件会保留
             */
            //在SD卡上创建一个文件夹
            //request.setDestinationInExternalPublicDir(  "/mydownfile/"  , "weixin.apk" ) ;  
    
    
            /**
             * 方法3:
             * 如果下载的文件希望被其他的应用共享
             * 特别是那些你下载下来希望被Media Scanner扫描到的文件(比如音乐文件)
             */
            //request.setDestinationInExternalPublicDir( Environment.DIRECTORY_MUSIC,  "笨小孩.mp3" );  
    
            /**
             * 方法4
             * 文件将存放在外部存储的确实download文件内,如果无此文件夹,创建之,如果有,下面将返回false。
             * 系统有个下载文件夹,比如小米手机系统下载文件夹  SD卡--> Download文件夹
             */
            //创建目录
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).mkdir() ; 
    
            //设置文件存放路径
            request.setDestinationInExternalPublicDir(  Environment.DIRECTORY_DOWNLOADS  , "weixin.apk" ) ;
        }

    五、应用实例

    package com.app;
    import android.app.Activity;
    import android.app.DownloadManager;
    import android.app.DownloadManager.Query;
    import android.app.DownloadManager.Request;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Environment;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.webkit.MimeTypeMap;
    import android.widget.Toast;
    
    public class MainActivity extends Activity implements OnClickListener {
    
        String url = "http://shouji.360tpcdn.com/150527/c90d7a6a8cded5b5da95ae1ee6382875/com.tencent.mm_561.apk" ;
        private long  mReference = 0 ;  
        private DownloadManager downloadManager ;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView( R.layout.activity_main ) ; 
    
            //取消下载
            findViewById( R.id.cancle_bt ).setOnClickListener( this );
    
            //查看下载状态
            findViewById( R.id.look_bt ).setOnClickListener( this );
    
            //注册广播接收器
            IntentFilter filter = new IntentFilter( DownloadManager.ACTION_DOWNLOAD_COMPLETE ) ;   
            registerReceiver( receiver , filter ) ;   
    
            Request request = new Request( Uri.parse( url ) );
    
            //下载网络需求  手机数据流量、wifi
            request.setAllowedNetworkTypes( Request.NETWORK_MOBILE | Request.NETWORK_WIFI ) ;
    
            //设置是否允许漫游网络 建立请求 默认true
            request.setAllowedOverRoaming( true ) ;
    
            //设置通知类型
            setNotification( request ) ;
    
            //设置下载路径
            setDownloadFilePath( request ) ;
    
            /*在默认的情况下,通过Download Manager下载的文件是不能被Media Scanner扫描到的 。
            进而这些下载的文件(音乐、视频等)就不会在Gallery 和  Music Player这样的应用中看到。
            为了让下载的音乐文件可以被其他应用扫描到,我们需要调用Request对象的
             */
            request.allowScanningByMediaScanner() ; 
    
            /*如果我们希望下载的文件可以被系统的Downloads应用扫描到并管理,
            我们需要调用Request对象的setVisibleInDownloadsUi方法,传递参数true。*/
            request.setVisibleInDownloadsUi( true ) ;
    
            //设置请求的Mime
            MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
            request.setMimeType(mimeTypeMap.getMimeTypeFromExtension(url));
    
            //开始下载
            downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE) ;
            mReference = downloadManager.enqueue( request ) ;
    
            /*
            下载管理器中有很多下载项,怎么知道一个资源已经下载过,避免重复下载呢?
            我的项目中的需求就是apk更新下载,用户点击更新确定按钮,第一次是直接下载,
            后面如果用户连续点击更新确定按钮,就不要重复下载了。
            可以看出来查询和操作数据库查询一样的
             */
            Query query = new Query() ;
            query.setFilterById( mReference );
            Cursor cursor = downloadManager.query( query ) ;  
            if ( !cursor.moveToFirst() ) {// 没有记录     
    
            } else {
                //有记录
            }
    
        }
    
        /**
         * 设置状态栏中显示Notification
         */
        void setNotification(Request request ) {
            //设置Notification的标题
            request.setTitle( "微信下载" ) ;
    
            //设置描述
            request.setDescription( "5.3.6" ) ;
    
            //request.setNotificationVisibility( Request.VISIBILITY_VISIBLE ) ;
    
            request.setNotificationVisibility( Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED ) ;
    
            //request.setNotificationVisibility( Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION ) ;
    
            //request.setNotificationVisibility( Request.VISIBILITY_HIDDEN ) ; 
        }
    
        /**
         * 设置下载文件存储目录
         */
        void setDownloadFilePath( Request request ){
            /**
             * 方法1: 
             * 目录: Android -> data -> com.app -> files -> Download -> 微信.apk
             * 这个文件是你的应用所专用的,软件卸载后,下载的文件将随着卸载全部被删除
             */
    
            //request.setDestinationInExternalFilesDir( this , Environment.DIRECTORY_DOWNLOADS ,  "微信.apk" );  
    
            /**
             * 方法2:
             * 下载的文件存放地址  SD卡 download文件夹,pp.jpg
             * 软件卸载后,下载的文件会保留
             */
            //在SD卡上创建一个文件夹
            //request.setDestinationInExternalPublicDir(  "/mydownfile/"  , "weixin.apk" ) ;  
    
    
            /**
             * 方法3:
             * 如果下载的文件希望被其他的应用共享
             * 特别是那些你下载下来希望被Media Scanner扫描到的文件(比如音乐文件)
             */
            //request.setDestinationInExternalPublicDir( Environment.DIRECTORY_MUSIC,  "笨小孩.mp3" );  
    
            /**
             * 方法4
             * 文件将存放在外部存储的确实download文件内,如果无此文件夹,创建之,如果有,下面将返回false。
             * 系统有个下载文件夹,比如小米手机系统下载文件夹  SD卡--> Download文件夹
             */
            //创建目录
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).mkdir() ; 
    
            //设置文件存放路径
            request.setDestinationInExternalPublicDir(  Environment.DIRECTORY_DOWNLOADS  , "weixin.apk" ) ;
        }
    
        /**
         * 广播接受器, 下载完成监听器
         */
        BroadcastReceiver receiver = new BroadcastReceiver() {    
            @Override     
            public void onReceive(Context context, Intent intent) { 
                String action = intent.getAction() ;
                if( action.equals( DownloadManager.ACTION_DOWNLOAD_COMPLETE  )){
                    //下载完成了
                    //获取当前完成任务的ID
                    long  reference = intent.getLongExtra( DownloadManager.EXTRA_DOWNLOAD_ID , -1 );
    
                    Toast.makeText( MainActivity.this , "下载完成了" ,  Toast.LENGTH_SHORT ).show() ;
                    
                    //自动安装应用
                    Util util = new Util() ;
                    util.openFile(context );
                    
                }
    
                if( action.equals( DownloadManager.ACTION_NOTIFICATION_CLICKED )){
                    //广播被点击了
                    Toast.makeText( MainActivity.this , "广播被点击了" ,  Toast.LENGTH_SHORT ).show() ;
                }
            }   
        };
    
        @Override
        public void onClick(View v) {
            switch ( v.getId() ) {
            case R.id.cancle_bt :
                //取消下载, 如果一个下载被取消了,所有相关联的文件,部分下载的文件和完全下载的文件都会被删除。
                downloadManager.remove( mReference ) ;
                break ;
    
            case R.id.look_bt :
                Query query = new Query() ;
                query.setFilterById( mReference );
                Cursor cursor = downloadManager.query( query ) ;  
    
                if( cursor == null ){ 
                    Toast.makeText( MainActivity.this , "Download not found!", Toast.LENGTH_LONG ).show(); 
                }else{  //以下是从游标中进行信息提取 
                    cursor.moveToFirst(); 
                    String msg = statusMessage( cursor ) ;
                    Toast.makeText( MainActivity.this , msg  ,  Toast.LENGTH_SHORT ).show() ;
                }
                break;
            }
        }   
    
        /**
         * 查询状态
         * @param c
         * @return
         */
        private String statusMessage(Cursor c){  
            switch(c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS ))){ 
            case DownloadManager.STATUS_FAILED:  
                return "Download failed";  
            case DownloadManager.STATUS_PAUSED:  
                return "Download paused";  
            case DownloadManager.STATUS_PENDING:  
                return "Download pending";  
            case DownloadManager.STATUS_RUNNING: 
                return "Download in progress!";  
            case DownloadManager.STATUS_SUCCESSFUL:  
                return "Download finished";  
            default: 
                return "Unknown Information";  
            } 
        }
    }


    六:项目下载地址

    http://download.csdn.net/detail/yanzi2015/8839023

     

  • 相关阅读:
    一个链表,奇数位升序偶数位降序,让链表变成升序的
    LeetCode 046 Permutations 全排列
    LeetCode 128 Longest Consecutive Sequence 一个无序整数数组中找到最长连续序列
    LeetCode 024 Swap Nodes in Pairs 交换链表中相邻的两个节点
    模板实现一个栈(内部使用动态申请的数组作为存储结构)
    004 Median of Two Sorted Arrays 两个有序数组的中位数
    静态链接与动态链接
    sizeof和strlen的区别
    const和define的区别
    lodash
  • 原文地址:https://www.cnblogs.com/zhaoyanjun/p/4591960.html
Copyright © 2011-2022 走看看