Android uses the DownloadManager Management System to download tasks. android Management System
Starting from Android 2.3 (API level 9), Android provides Download Manager in the form of system services to optimize and process long-time Download operations. Download Manager processes the HTTP connection and monitors the status changes in the connection and restarts the system to ensure the smooth completion of each Download task.
The use of Download Manager is a good choice in most cases involving downloads. Especially when users switch between different applications, the Download needs to continue in the background, and when the download task is completed successfully (DownloadManager supports resumable upload very well ).
To use Download Manager, use the getSystemService method to request the system's DOWNLOAD_SERVICE service. The code snippet is as follows:
String serviceString =Context.DOWNLOAD_SERVICE; DownloadManager downloadManager; downloadManager = (DownloadManager)getSystemService(serviceString);
Download files
To Request a download operation, you must create a DownloadManager. Request object and pass the Uri of the file to be downloaded to the enqueue method of DownloadManager. The code snippet is as follows:
String serviceString =Context.DOWNLOAD_SERVICE; DownloadManager downloadManager; downloadManager =(DownloadManager)getSystemService(serviceString); Uri uri =Uri.parse("http://developer.android.com/shareables/icon_templates-v4.0.zip"); DownloadManager.Request request = newRequest(uri); long reference =downloadManager.enqueue(request);
The returned reference variable is a unique ID allocated by the system for the current download request. We can use this ID to obtain the download task again, you can perform operations or query the download status and cancel the download.
You can use the addRequestHeader method to add an HTTP header to the DownloadManager. Request object request, or use the setMimeType method to override the mimetype returned from the server.
We can also specify the connection status for the download operation. The setAllowedNetworkTypes method can be used to restrict download on WiFi or mobile phone networks. The setAllowedOverRoaming method can be used to prevent mobile phone downloads from roaming.
The following code snippet specifies that a large file can only be downloaded under WiFi:
request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
Android API level 11 introduces the getRecommendedMaxBytesOverMobile class method (static method). It returns the maximum number of recommended bytes for the current mobile phone network connection to determine whether the download should be limited to WiFi. After the enqueue method is called, the Download starts as long as the data connection is available and the Download Manager is available. You need to get a system notification when the download is complete. Register a broadcast receiver to receive ACTION_DOWNLOAD_COMPLETE broadcast, the broadcast contains an EXTRA_DOWNLOAD_ID information. The intent contains the downloaded ID. The code snippet is as follows:
IntentFilter filter = newIntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); BroadcastReceiver receiver = newBroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { long reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,-1); if (myDownloadReference == reference) { } } }; registerReceiver(receiver, filter);
Use the openDownloadedFile method of Download Manager to open a downloaded file and return a ParcelFileDescriptor object. We can use Download Manager to query the address for saving the downloaded file. If the path and file name are specified during the Download, we can directly operate the file. You can register a broadcast receiver for action_icationication_clicked action. When you click a download project from the notification bar or click a download project from the Downloads app, the system sends a broadcast of click Download items.
The code snippet is as follows:
IntentFilter filter = newIntentFilter(DownloadManager.ACTION_NOTIFICATION_CLICKED); BroadcastReceiver receiver = newBroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String extraID =DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS; long[] references = intent.getLongArrayExtra(extraID); for (long reference : references) if (reference == myDownloadReference) { // Do something with downloading file. } } }; registerReceiver(receiver, filter);
Customize Download Manager specifications
By default, the Notification bar displays the current Download progress and file name for each download Notification managed by Download Manager.
You can use Download Manager to customize Notification styles for each download request, including completely hiding the Notification. The following code snippet shows the custom text displayed in the File Download Notification by using the setTitle and setDescription methods.
request.setTitle(“Earthquakes”); request.setDescription(“EarthquakeXML”);
The setNotificationVisibility method can be used to control when the Notification is displayed, or even hide the Notification of the request. The following parameters are available:
Request. VISIBILITY_VISIBLE: The downloaded Notification is always displayed in the Notification bar during the download process. When the download is complete, the Notification is removed. This is the default parameter value.
Request. visibility_visible_policy_completed.
Request. visibility_visible_policy_only_completion: the Notification is displayed only after the download is complete.
Request. VISIBILITY_HIDDEN: the Notification of the download Request is not displayed. To use this parameter, add the DOWNLOAD_WITHOUT_NOTIFICATION permission to the application configuration file.
Download and save address
By default, all files downloaded through Download Manager are saved in a shared Download cache. You can create a Download object using the file name generated by the system.
Save address. Generally, all downloaded files should be stored in external storage. Therefore, we need to add the WRITE_EXTERNAL_STORAGE permission to the Application List file:
<uses-permissionandroid:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>
The following code snippet specifies an arbitrary storage location in an external store:
request.setDestinationUri(Uri.fromFile(f));
F is a File object.
If the downloaded file is dedicated to your application, you may want to put the file in a private folder in the external storage of your application. Note that this folder does not provide access control, so other applications can also access this folder. In this case, if your application is uninstalled, the folder will also be deleted.
The following code snippet specifies the path of the storage file as a private folder of the application in External Storage:
request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, “Bugdroid.png”);
If the downloaded file is to be shared by other applications, especially those files (such as music files) that you download and want to be scanned by Media transcoding ), you can specify the download path under the public folder of external storage. The following code snippet stores the file in the public music folder of External Storage:
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_MUSIC, "Android_Rock.mp3");
By default, files downloaded through the Download Manager cannot be scanned by the Media repository, And the downloaded files (such as music and video) will not be in the Gallery and
Music Player.
To enable the downloaded music file to be scanned by other applications, we need to call the allowScaningByMediaScanner method of the Request object.
If the file we want to download can be scanned and managed by the system's Downloads application, we need to call the setVisibleInDownloadsUi method of the Request object and pass the parameter true.
Cancel and delete downloads
The remove Method of Download Manager can be used to cancel a preparation Download, abort an ongoing Download, or delete a completed Download.
The remove Method accepts several download IDS as parameters. You can set one or more download IDs you want to cancel, as shown in the following code snippet:
downloadManager.remove(REFERENCE_1,REFERENCE_2, REFERENCE_3);
This method returns the number of successfully canceled downloads. If a download is canceled, all associated files, some downloaded files, and all downloaded files will be deleted.
Query Download Manager
You can query the Download Manager to obtain the Download task status, progress, and details. You can use the query method to return a Cursor containing the Download task details. The query method transmits a DownloadManager. Query object as the parameter. You can use the setFilterById method of the DownloadManager. Query object to filter the download task ID that we want to query. You can also use the setFilterByStatus method to filter download tasks in a certain state that you want to query. The parameter passed is the constant DownloadManager. STATUS _ *, which can be specified
Status: in progress, paused, failed, and completed.
Download Manager contains a series of COLUMN _ * Static String constants that can be used to query the results COLUMN indexes in Cursor. We can query various details of the download task, including status, file size, number of downloaded bytes, title, description, URI, local file name and URI, media type and Media Provider download URI.
The following code snippet describes how to query the local file name and URI of the downloaded file by registering the broadcast receiver of the listener download completion event:
@Override public void onReceive(Context context,Intent intent) { long reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,-1); if(myDownloadReference == reference) { Query myDownloadQuery = new Query(); myDownloadQuery.setFilterById(reference); Cursor myDownload = downloadManager.query(myDownloadQuery); if (myDownload.moveToFirst()) { int fileNameIdx = myDownload.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME); int fileUriIdx = myDownload.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI); String fileName = myDownload.getString(fileNameIdx); String fileUri = myDownload.getString(fileUriIdx); // TODO Do something with the file. Log.d(TAG, fileName + " : " + fileUri); } myDownload.close(); } }
For paused and failed downloads, We can query the full number of causes in the COLUMN_REASON column.
For DownloadManager. PAUSED _ * Static constants, you can use DownloadManager. PAUSED _ * to translate the full number of the reason, and then determine that the download is waiting for a network connection.
Wait until the Wi-Fi connection is established or you are about to download it again.
For DownloadManager. ERROR _ * to download STATUS_FAILED status, we can use DownloadManager. ERROR _ * to determine the cause of the failure, which may be the ERROR code (cause of failure), including no storage device,
Insufficient storage space, duplicate file names, or HTTP errors.
The following code queries all the currently paused download tasks, extracts the reason for the pause, the file name, the download title, and the implementation method of the current progress:
// Obtain the Download ManagerService. String serviceString =Context.DOWNLOAD_SERVICE; DownloadManager downloadManager; downloadManager =(DownloadManager)getSystemService(serviceString); // Create a query for pauseddownloads. Query pausedDownloadQuery = newQuery(); pausedDownloadQuery.setFilterByStatus(DownloadManager.STATUS_PAUSED); // Query the Download Manager for pauseddownloads. Cursor pausedDownloads =downloadManager.query(pausedDownloadQuery); // Find the column indexes for the data werequire. int reasonIdx =pausedDownloads.getColumnIndex(DownloadManager.COLUMN_REASON); int titleIdx =pausedDownloads.getColumnIndex(DownloadManager.COLUMN_TITLE); int fileSizeIdx = pausedDownloads.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES); int bytesDLIdx = pausedDownloads.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR); // Iterate over the result Cursor. while (pausedDownloads.moveToNext()) { //Extract the data we require from the Cursor. String title = pausedDownloads.getString(titleIdx); intfileSize = pausedDownloads.getInt(fileSizeIdx); intbytesDL = pausedDownloads.getInt(bytesDLIdx); //Translate the pause reason to friendly text. intreason = pausedDownloads.getInt(reasonIdx); String reasonString = "Unknown"; switch (reason) { case DownloadManager.PAUSED_QUEUED_FOR_WIFI : reasonString = "Waiting for WiFi"; break; case DownloadManager.PAUSED_WAITING_FOR_NETWORK : reasonString = "Waiting for connectivity"; break; case DownloadManager.PAUSED_WAITING_TO_RETRY : reasonString = "Waiting to retry"; break; default : break; } //Construct a status summary StringBuilder sb = new StringBuilder(); sb.append(title).append("\n"); sb.append(reasonString).append("\n"); sb.append("Downloaded ").append(bytesDL).append(" /" ).append(fileSize); //Display the status Log.d("DOWNLOAD", sb.toString()); } // Close the result Cursor. pausedDownloads.close();
How does DownloadManager set the download path?
First, you must go to AndroidManifest. apply for DownloadManager permission in xml to add a download task: ContentValues values = new ContentValues (); values. put (Downloads. URI, url); // specify values. put (Downloads. COOKIE_DATA, cookie); // If cookie is required for downloading the Server, set cookie values. put (Downloads. VISIBILITY, Downloads. VISIBILITY_HIDDEN); // sets whether to display values at the top of the screen when the download prompt is displayed. put (Downloads. icationication_package, getPackageName (); // sets the package name values for callback after the download is complete. put (Downloads. NOTIFICATION_CLASS, DownloadCompleteReceiver. class. getName (); // set the Receiver to be received after the download is complete. This class inherits BroadcastReceiver values. put (Downloads. DESTINATION, save_path); // sets the download path, which must be processed by values in the consumer. put (Downloads. TITLE, title); // set the download Task Name this. getContentResolver (). insert (Downloads. CONTENT_URI, values); // insert it into the DownloadManager database. The database triggers a modification event and starts the download task to the eoeAndroid website to view the answer details>
Why does android downloadmanager return-1 when obtaining the total size of the downloaded file?
HttpURLConnection conn = (HttpURLConnection) url. openConnection ();
Conn. setRequestProperty ("Accept-Encoding", "identity ");
Conn. connect ();
Add the middle line. (Gzip compression is used by default, so the total size of the downloaded file cannot be obtained in advance, so you cannot compress the downloaded file)