Downloadmanager in android

本文介绍如何使用Android中的DownloadManager进行文件下载,包括创建下载任务、设置下载参数、查询下载进度及状态等操作,并提供了监听下载进度和下载完成的方法。

Downloadmanager使用

DownloadManager是android提供的一个下载管理器

缺点:不支持断点续传

使用方法:

  1. 创建实例:

    DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
  2. 创建下载任务:

    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(URL));
    //指定保存地址
    request.setDestinationInExternalPublicDir("chuyi", "meizhi.apk");
    //设置允许下载的网络状况
    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
    //设置通知栏的行为
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    //通过id唯一标识此下载任务
    long id = manager.enqueue(request);
  3. 删除下载任务:

    manager.remove(id);
  4. 查询下载任务:

    DownloadManager.Query query = new DownloadManager.Query();
    query.setFilterById(id);
    Cursor cursor = manager.query(query);
    
    if(cursor.moveToFirst()){
        String filename = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
        String fileUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
        Toast.makeText(context,"下载完成...name:"+filename+",uri:"+fileUri,Toast.LENGTH_SHORT).show();
    }else {
      //TODO
    }
    cursor.close();
  5. 查询下载进度:

    DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
    Cursor c = null;
    try {
        c = downloadManager.query(query);
        if (c != null && c.moveToFirst()) {
            int downloadedBytes = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
            int totalBytes = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
            int state = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
        }
    } finally {
        if (c != null) {
            c.close();
        }
    }
    
  6. 监听下载结束通知:

    可以通过接收DownloadManager.ACTION_DOWNLOAD_COMPLETE广播来监听下载结束的通知

    IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        mReceiver = new BroadcastReceiver(){
          public void onReceive(Context c,Intent i){
              long downId = i.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,-1);
          }
        }
        context.registerReceiver(mReceiver,filter);
  7. 监听下载进度:

    主要有三种方案:1.FileReceiver 2.ContentObserver 3.定时任务

    class DownloadChangeObserver extends ContentObserver {
    
    public DownloadChangeObserver(){
        super(handler);
    }
    
    @Override
    public void onChange(boolean selfChange) {
        //查询进度
    }
    
    }
    //in activity
    private DownloadChangeObserver downloadObserver;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.download_manager_demo);
    ……
    downloadObserver = new DownloadChangeObserver();
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        /** observer download change **/
        getContentResolver().registerContentObserver(DownloadManagerPro.CONTENT_URI, true,
                                                     downloadObserver);
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        getContentResolver().unregisterContentObserver(downloadObserver);
    }

    上面这种做法可能对性能有些损耗,因为会不断触发onChange

    推荐使用ScheduledExecutorService

    public static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
    Runnable command = new Runnable() {
    
        @Override
        public void run() {
            updateView();
        }
    };
    scheduledExecutorService.scheduleAtFixedRate(command, 0, 3, TimeUnit.SECONDS);

    参考资料:

    1. http://www.trinea.cn/android/android-downloadmanager/
    2. http://www.trinea.cn/android/android-downloadmanager/
    3. https://github.com/Trinea/android-common/blob/master/src/cn/trinea/android/common/util/DownloadManagerPro.java
Android 中实现下载功能,通常涉及使用系统提供的 API 或第三方库来管理文件的下载、存储和访问。以下是一些常见的实现方式及指南。 ### 下载管理器(DownloadManagerAndroid 提供了 `DownloadManager` 类,这是一个系统服务,用于处理长时间运行的 HTTP 下载任务。它适用于不需要与用户交互的后台下载操作,并且可以自动处理网络中断和重试。 要使用 `DownloadManager`,首先需要获取其实例: ```java DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); ``` 然后创建一个 `DownloadManager.Request` 对象,指定要下载的 URI 和其他选项: ```java Uri uri = Uri.parse("https://example.com/file_to_download"); DownloadManager.Request request = new DownloadManager.Request(uri); // 设置通知栏标题 request.setTitle("File Download"); // 设置允许使用的网络类型 request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE); // 设置是否允许漫游 request.setAllowedOverRoaming(false); // 设置下载文件的 MIME 类型 request.setMimeType("application/pdf"); // 设置下载文件保存的位置 request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "file_to_download"); // 将请求加入队列 long downloadId = downloadManager.enqueue(request); ``` 可以通过 `DownloadManager.Query` 来查询下载状态: ```java DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(downloadId); Cursor cursor = downloadManager.query(query); if (cursor.moveToFirst()) { int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); switch (status) { case DownloadManager.STATUS_SUCCESSFUL: // 下载成功 break; case DownloadManager.STATUS_FAILED: // 下载失败 break; } } cursor.close(); ``` ### 使用 HttpURLConnection 实现自定义下载 如果需要更精细的控制下载过程,例如显示进度条或暂停/恢复功能,则可以使用 `HttpURLConnection` 杜绝系统级的服务直接进行网络通信。 以下是一个简单的示例: ```java URL url = new URL("https://example.com/file_to_download"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); try { InputStream input = new BufferedInputStream(connection.getInputStream()); OutputStream output = new FileOutputStream("/path/to/local/file"); byte[] data = new byte[1024]; int count; while ((count = input.read(data)) != -1) { output.write(data, 0, count); } output.flush(); output.close(); input.close(); } finally { connection.disconnect(); } ``` ### 文件提供者(FileProvider) 当应用需要分享下载的文件时,尤其是通过 Intent 向其他应用共享本地文件时,应使用 `FileProvider` 来生成安全的内容 URI。这在 Android 7.0(API 级别 24)及以上版本中是必需的,因为直接暴露文件路径会导致 `FileUriExposedException`。 在 `AndroidManifest.xml` 中声明 `FileProvider`: ```xml <provider android:name="androidx.core.content.FileProvider" android:authorities="com.example.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> ``` 其中 `@xml/file_paths` 是一个 XML 资源文件,定义了哪些目录可以被访问: ```xml <?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="external_files" path="." /> </paths> ``` 然后可以通过以下方式获取内容 URI 并启动其他应用打开文件: ```java File file = new File(context.getExternalFilesDir(null), "file_to_share.pdf"); Uri contentUri = FileProvider.getUriForFile(context, "com.example.fileprovider", file); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(contentUri, "application/pdf"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent); ``` ### 总结 - **DownloadManager**:适合于后台静默下载,无需复杂逻辑。 - **HttpURLConnection**:适合需要完全控制下载流程的情况,如进度监控、断点续传等。 - **FileProvider**:用于安全地与其他应用共享文件,特别是在 Android 7.0 及以上版本中。 这些方法结合使用,可以帮助开发者构建完整的下载管理解决方案 [^1]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值