1. Android SD存储相关
1) 检查SD状态
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(MainActivity.this, "无法操作SD卡", Toast.LENGTH_LONG).show(); return true; }
2) 获取SD下载目录
String downloadDirPath = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
2. DownloadManager
1) 配置权限
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2) 获取实例
DownloadManager downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
3) 通过DownloadManager.Request设置下载请求信息
//downloadUrl为下载地址 DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadUrl)); //设置文件下载目录和文件名 request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "test.apk"); //设置下载中通知栏提示的标题 request.setTitle("test apk"); //设置下载中通知栏提示的介绍 request.setDescription("测试下载中"); /* 表示下载进行中和下载完成的通知栏是否显示,默认只显示下载中通知, VISIBILITY_HIDDEN表示不显示任何通知栏提示, 这个需要在AndroidMainfest中添加权限android.permission.DOWNLOAD_WITHOUT_NOTIFICATION */ //request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); /* 表示下载允许的网络类型,默认在任何网络下都允许下载, 有NETWORK_MOBILE、NETWORK_WIFI、NETWORK_BLUETOOTH三种及其组合可供选择; 如果只允许wifi下载,而当前网络为3g,则下载会等待 */ //request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); //移动网络情况下是否允许漫游 //request.setAllowedOverRoaming(true); //表示允许MediaScanner扫描到这个文件,默认不允许 //request.allowScanningByMediaScanner(); /* 设置下载文件的mineType, 因为下载管理Ui中点击某个已下载完成文件及下载完成点击通知栏提示都会根据mimeType去打开文件, 所以我们可以利用这个属性。比如上面设置了mimeType为application/package.name, 我们可以同时设置某个Activity的intent-filter为application/package.name,用于响应点击的打开文件 */ //request.setMimeType("application/package.name"); //添加请求下载的网络链接的http头,比如User-Agent,gzip压缩等 //request.addRequestHeader(String header, String value);
4) 发起下载请求
/* 调用downloadManager的enqueue接口进行下载, 返回唯一的downloadId用于下载状态查询和下载完成监听 */ long downloadId = downloadManager.enqueue(request);
3. 查询下载状态
DownloadManager.Query用来查询下载信息
//setFilterById根据下载id进行过滤 DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId); Cursor cursor = null; try { cursor = downloadManager.query(query); if (cursor != null && cursor.moveToFirst()) { downloadedBytes = cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); totalBytes = cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); status = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); } } finally { if (cursor != null) { cursor.close(); } }
4. 连续性地更新下载进度
1) 方法一:注册ContentObserver,监听下载状态,每次变化都会触发onChange
private ContentObserver downloadObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); //TODO //此处可以通知handle去查询下载状态 } }; @Override protected void onResume() { super.onResume(); //注册ContentObserver getContentResolver().registerContentObserver( Uri.parse("content://downloads/my_downloads"), true, downloadObserver); } @Override protected void onPause() { super.onPause(); getContentResolver().unregisterContentObserver(downloadObserver); }
2) 方法二:通过ScheduledExecutorService轮询
a) ScheduledExecutorService相关
① 接口scheduleAtFixedRate原型定义及参数说明
/* command:执行线程 initialDelay:初始化延时 period:两次开始执行最小间隔时间 unit:计时单位 */ public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
注:If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor. If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
即当执行任务的时间大于我们指定的间隔时间时,它并不会在指定间隔时开辟一个新的线程并发执行这个任务,而是等待该线程执行完毕。
②关于任务的取消和重用
//get reference to the future Future<?> future = service.scheduleAtFixedRate(runnable, INITIAL_DELAY, INTERVAL, TimeUnit.SECONDS) //cancel instead of shutdown future.cancel(true); //schedule again (reuse) future = service.scheduleAtFixedRate(runnable, INITIAL_DELAY, INTERVAL, TimeUnit.SECONDS) //shutdown when you don't need to reuse the service anymore service.shutdown()
b) 具体实现
ScheduledExecutorService scheduledExecutorService; Future<?> future; //下载的文件存储名 String downloadFilePath = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/test.apk"; File downFile = new File(downloadFilePath); long fileTotalSize; //每过100ms通知handler去查询下载状态 future = scheduledExecutorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { Message msg = mHandler.obtainMessage(); msg.what = QUERY; mHandler.sendMessage(msg); } }, 0, 100, TimeUnit.MILLISECONDS); private Handler mHandler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { switch (msg.what) { case QUERY: Cursor cursor = downloadManager.query(query); if (cursor != null && cursor.moveToFirst()) { //此处直接查询文件大小 long downSize = downFile.length(); //获取文件下载总大小 fileTotalSize = cursor.getLong(cursor.getColumnIndex( DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); cursor.close(); Log.w(TAG, "downloaded size: " + downSize); Log.w(TAG, "total size: " + fileTotalSize); if (fileTotalSize != 0) { int percentage = (int) (downSize * 100 / fileTotalSize); statusBar.setProgress(percentage); statusText.setText(percentage + "%"); } //终止轮询task if (fileTotalSize == downSize) future.cancel(true); } } return true; } }); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); scheduledExecutorService = Executors.newScheduledThreadPool(1); } @Override protected void onDestroy() { super.onDestroy(); if (future != null && !future.isCancelled()) future.cancel(true); if (scheduledExecutorService != null && !scheduledExecutorService.isShutdown()) scheduledExecutorService.shutdown(); }
5. 获取DownloadManager下载完成的推送信息
下载完成后,DownloadManager会发出DownloadManager.ACTION_DOWNLOAD_COMPLETE这个广播,并传递downloadId作为参数。通过接受广播我们可以打开对下载完成的内容进行操作。
BroadcastReceiver downloadCompleteReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { long completeDownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); if (completeDownloadId == downloadId) { Log.w(TAG, "download complete"); statusBar.setProgress(100); statusText.setText("100%"); } } }; @Override protected void onResume() { super.onResume(); /** 注册下载完成接收广播 **/ registerReceiver(downloadCompleteReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); } @Override protected void onPause() { super.onPause(); unregisterReceiver(downloadCompleteReceiver); }
6. Refer:
Android系统下载管理DownloadManager功能介绍及使用示例
ScheduledExecutorService start stop several times
相关推荐
通过使用DownloadManager,开发者可以实现应用的自动更新功能,并通过监听下载进度,向用户展示当前下载状态。下面详细介绍一下DownloadManager的使用方法以及如何监听下载进度。 首先,DownloadManager是自Android...
这个"DownloadManager使用的Demo"是帮助开发者理解并熟练运用DownloadManager的一个详细实例。下面将详细介绍DownloadManager的相关知识点。 **1. DownloadManager简介** DownloadManager是Android 2.3(API Level ...
以上就是使用Android自带的`DownloadManager`实现应用更新的基本步骤。通过这个方法,开发者可以实现一个简单、兼容性强的后台下载和更新机制,让用户在不离开应用或关闭设备的情况下也能顺利完成更新。当然,实际...
要使用`DownloadManager`,我们需要在AndroidManifest.xml中添加对互联网访问的权限: ```xml ``` 接下来,我们需要在代码中获取`DownloadManager`的实例: ```java DownloadManager downloadManager = ...
接下来,使用`DownloadManager`的`enqueue()`方法提交请求,开始下载: ```java long downloadId = downloadManager.enqueue(request); ``` `enqueue()`方法返回一个唯一的下载ID,可以用于后续查询下载状态: ``...
通过以上步骤,我们就可以使用Android的`DownloadManager`实现自动下载并安装APK更新了。这种方式既简单又高效,能确保用户在不打开应用的情况下也能接收到新版本的更新。在实际开发中,还可以根据需求增加一些额外...
通过以上步骤,我们就使用`DownloadManager`成功地创建了一个文件下载任务,并在通知栏显示了下载进度。在实际应用中,还可以根据需要设置更多的参数,如限制下载速度、设置优先级等。同时,注意处理可能的异常情况...
使用`DownloadManager.enqueue(Request request)`方法将请求加入到下载队列,返回一个long类型的id,这是下载任务的唯一标识符,用于后续查询和取消操作。 4. **查询下载状态** 可以通过`DownloadManager.query...
`Android-Updater`是一个基于`DownloadManager`服务的封装库,旨在简化应用程序的更新流程,为开发者提供一个高效且用户友好的解决方案。本篇文章将深入探讨`Android-Updater`的工作原理、主要功能及其在实际开发中...
4. **下载进度更新**:为了提供良好的用户体验,DownloadManager 可以定期更新下载进度,这些更新可以通过BroadcastReceiver传递给应用程序,进而显示在UI上,让用户了解下载的实时情况。 5. **错误处理**:当下载...
本示例将详细介绍如何使用DownloadManager进行文件下载,并提供一个简单的Demo来帮助理解其工作原理。 首先,我们需要在AndroidManifest.xml文件中添加必要的权限,因为下载文件通常涉及网络访问和写入外部存储: ...
首先,我们需要了解DownloadManager的基本使用。在AndroidManifest.xml文件中,你需要添加对INTERNET权限的请求,因为下载文件需要网络权限: ```xml ``` 然后,在代码中获取DownloadManager的实例,通常在应用...
- 在SAP ONE Support Launchpad上,找到需要下载的软件或更新,选择“使用SAP Download Manager下载”选项。 - 在Download Manager中,添加选定的文件到下载列表,然后点击开始下载。 - 监控下载进度,根据需要...
在使用DownloadManager之前,需要在AndroidManifest.xml中添加以下权限: ```xml ``` 3. **请求下载** 要发起下载,首先需要获取DownloadManager实例: ```java DownloadManager downloadManager = ...
在安卓应用开发中,为了实现应用的自动更新,开发者经常使用Android系统的DownloadManager服务来下载新的apk文件。这个服务是系统级别的,具有可靠性和后台运行的能力,即使应用被关闭,下载也会继续。以下是对这个...
1. 保存进度信息:`DownloadManager`会在数据库中记录每个下载任务的状态,包括已下载的字节数和文件的总大小。当网络恢复或设备重启时,它会读取这些信息来判断是否需要从断点处继续下载。 2. 请求范围:`...
本示例旨在展示如何使用`DownloadManager`来实现下载功能,包括监听下载开始和结束的事件。 首先,我们需要在AndroidManifest.xml文件中添加对`Internet`权限的声明,因为下载文件需要网络访问权限: ```xml ``` ...