DownloadManger is the android 2.3 (api level 9) provided to optimize the processing of long downloads. DownloadManager handles Http/Https connections and monitors state changes and system reboots in the connection to ensure that each download task completes successfully. Most of the downloads are used in the case of DownloadManager, which is a good choice, especially in the background to continue downloading, download status callbacks, resume downloads, download environment settings, download file operations, etc., support is very good.
DownloadManager is a class that is open to third-party applications and contains two static internal classes, DownloadManager.Query and DownloadManager.Request. DownloadManager.Request is used to request a download, DownloadManager.Query is used to query the download information, the specific interface information can be found in the final api description.
DownloadManager mainly provides the following interfaces:
The public long enqueue (Request request) performs the download and returns the downloadId. The downloadId can be used to query the download information later. If the network does not meet the conditions, the Sdcard is mounted, and the maximum number of concurrent times exceeds the maximum number of concurrent outputs, the device will wait for the download. If it is normal, it will be downloaded directly.
Int remove(long... ids) Delete the download, if the download is canceled. The downloaded files and records will also be deleted.
Cursor query(Query query) Query the download information.
getMaxBytesOverMobile(Context context) Returns the maximum value of the mobile network download
Rename(Context context, long id, String displayName) Rename the name of the downloaded item
getRecommendedMaxBytesOverMobile(Context context) Get the recommended size of the mobile web download
Other: By looking at the code we can see that there is also a private static inner class of CursorTranslator. This class mainly makes a layer of proxy for Query. Make a mapping between DownloadProvider and DownloadManager. The ten states in the DownloadProvider are mapped to the five states in the DownloadManager, and the failure in the DownloadProvider and the reason for the suspension are converted to the DownloadManager.
1. Download the required permissions
<uses-permission android:name="android.permission.INTERNET" />;
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>;
2. Call DownloadManager.Request to start downloading
DownloadManager downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
String apkUrl = "https://qd.myapp.com/myapp/qqteam/AndroidQQ/mobileqq_android.apk";
DownloadManager.Request request = new
DownloadManager.Request(Uri.parse(apkUrl));
request.setDestinationInExternalPublicDir("dirType", "/mydownload/QQ.apk");
// request.setTitle("TX QQ");
// request.setDescription("This is TX QQ");
// request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
//request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
//
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
//request.setMimeType("application/cn.trinea.download.file");
long downloadId = downloadManager.enqueue(request);
The above code is to add a download url to the system download queue. When the condition is met, it will automatically start downloading. Calling enqueue() returns a long id value, which is the unique id of the download item.
You can set the property of the Request (download item), except that the URI of the construct parameter is required. Other conditions are optional, such as the downloaded local path, the rename after download, the display of the download notification and the display or not. , download the allowed network type, download the MimeType, etc.
request.setMimeType(“application/cn.trinea.download.file”);
Set the mineType of the downloaded file. Because the download management Ui clicks on a downloaded completed file and the download completes the click notification bar prompt will open the file according to mimeType, so we can use this property. For example, if the mimeType is set to application/cn.trinea.download.file above, we can also set the intent-filter of an Activity to application/cn.trinea.download.file, which is used to respond to the clicked open file.
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/cn.trinea.download.file" />
</intent-filter>
Add the http header of the network link requesting to download, such as User-Agent, gzip compression, etc.:
request.addRequestHeader(String header, String value);
3. Download progress status monitoring and query
The DownloadManager download tool does not provide a corresponding callback interface for returning the real-time download progress status, but through one of the four components of Android, ContentProvider, we can monitor the progress status of the current download.
downloadManager.getUriForDownloadedFile(id);
This method will return a Uri of the download item, such as:content://downloads/my_downloads/125
ContentObserver - Content observer, which can listen to changes in the database items pointed to by a particular Uri, and then handle the corresponding processing, where we will listen to Uri.parse ("content://downloads/my_downloads"). Then query the download status and progress, and proceed to the next step, such as sending a handler to update the UI.
The following method can query the download progress status of the download item according to the id of the download item and return "current downloaded byte", "total bytes", "current download status":
public int[] getBytesAndStatus(long downloadId) {
int[] bytesAndStatus = new int[] { -1, -1, 0 };
DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
Cursor c = null;
try {
c = downloadManager.query(query);
if (c != null && c.moveToFirst()) {
bytesAndStatus[0] = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
bytesAndStatus[1] = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
bytesAndStatus[2] = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
}
} finally {
if (c != null) {
c.close();
}
}
return bytesAndStatus;
}
As you can see from the above code, we mainly call DownloadManager.Query() to query. DownloadManager.Query is an information query class that is open to the public for download management. It mainly includes the following interfaces:
To observe the content provided by ContentProvider, you need to restart the onChange(boolean selfChange) method in ContentObserver and register/unregister Observer in the corresponding lifecycle method of activity/fragment:
class DownloadStatusObserver extends ContentObserver {
public DownloadStatusObserver() {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
int[] bytesAndStatus = getBytesAndStatus(downloadId);
Int currentSize = bytesAndStatus[0];//current size
Int totalSize = bytesAndStatus[1];//total size
Int status = bytesAndStatus[2];//Download status
}
}
@Override
protected void onResume() {
super.onResume();
getContentResolver().registerContentObserver(CONTENT_URI, true, observer);
}
@Override
protected void onDestroy() {
super.onDestroy();
getContentResolver().unregisterContentObserver(observer);
}
If too many elements on the interface need to be updated, and the network speed is faster, continuous execution of onChange will have a certain impact on page performance. The ScheduledExecutorService is recommended to be queried regularly, as follows:
//Three seconds to refresh once
public static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
Runnable command = new Runnable() {
@Override
public void run() {
updateView();
}
};
scheduledExecutorService.scheduleAtFixedRate(command, 0, 3, TimeUnit.SECONDS);
4. Download successfully monitored
After the download is complete, the download manager issues a DownloadManager.ACTION_DOWNLOAD_COMPLETE broadcast and passes the downloadId as a parameter. By accepting the broadcast we can open the operation of the downloaded content. code show as below:
class CompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// get complete download id
long completeDownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
// to do here
}
};
private CompleteReceiver completeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.download_manager_demo);
…
completeReceiver = new CompleteReceiver();
/** register download success broadcast **/
registerReceiver(completeReceiver,
new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(completeReceiver);
}
5, click on the response notification bar
Click the notification in the notification bar in the download, the system will send the Action to DownloadManager.ACTION_NOTIFICATION_CLICKED broadcast separately for the downloaded application.
intent.getData iscontent://downloads/all_downloads/29669The last bit is downloadId.
If multiple applications are downloaded at the same time, the intent will contain the DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS key, indicating the downloaded downloadId array.
After downloading, the following code will be called for processing. From this we can find that the system will call the View action to query according to mimeType. So you can take advantage of the setMimeType function of the DownloadManager.Request we introduced.
private void openDownload(Context context, Cursor cursor) {
String filename = cursor.getString(cursor.getColumnIndexOrThrow(Downloads.Impl._DATA));
String mimetype = cursor.getString(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_MIME_TYPE));
Uri path = Uri.parse(filename);
// If there is no scheme, then it must be a file
if (path.getScheme() == null) {
path = Uri.fromFile(new File(filename));
}
Intent activityIntent = new Intent(Intent.ACTION_VIEW);
mimetype = DownloadDrmHelper.getOriginalMimeType(context, filename, mimetype);
activityIntent.setDataAndType(path, mimetype);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(activityIntent);
} catch (ActivityNotFoundException ex) {
Log.d(Constants.TAG, "no activity for " + mimetype, ex);
}
}
6, open the system download interface through implicit intent
Intent intent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
startActivity(intent);
long enqueue(Request request)
Add a new download to the queue, the download will automatically start the download when the downloadmanager is ready to execute the download/connection, returning the unique id of the download
int remove(long... ids)
Remove one or more downloads and return the number of changes
Cursor query(Query query)
Executing a query Qurey class is described below
openDownloadedFile(long id)
Open a file (this file must have been downloaded)
getUriForDownloadedFile(long id)
Returns a Uri of a downloaded item, such as:content://downloads/my_downloads/103
getMimeTypeForDownloadedFile(long id)
Returns a downloaded item mimetype
restartDownload(long... ids)
Re-completed downloads (download successful, download failed) to start downloading;
getMaxBytesOverMobile(Context context)
Return the maximum value of the mobile network download
rename(Context context, long id, String displayName)
Rename the name of the downloaded item
getRecommendedMaxBytesOverMobile(Context context)
Get the recommended size of the mobile web download
addCompletedDownload(String title, String description,boolean isMediaScannerScannable, String mimeType, String path, long length,boolean showNotification)
Add a file to the system's download file database, and the download entry for the file can be displayed in the system download app;
According to the instructions on the api, this method is useful for making a file a file that can be scanned by MediaScanner. Call this method to turn the specified file into scannable by MediaScanner by setting the param isMediaScannerScannable to true. Useful for album gallary applications
setDestinationUri(Uri uri) :
Customize the download local path, passing in a Uri type;
setDestinationInExternalFilesDir(Context context, String dirType,String subPath) :
The custom download local path is the Android/data/package-name/ parent directory of the built-in sd card. The content under this directory will be deleted and cleared with the uninstallation of the application. dirType: the type of the file (Environment.DIRECTORY_DOWNLOADS, Environment. DIRECTORY_DCIM,......);
subPath: subdirectory path under the parent directory (/apk/myPath/myapk.apk)
setDestinationInExternalPublicDir(String dirType, String subPath) :
Same as above, download to the subPath subdirectory under the shared public parent directory on the sd card.
allowScanningByMediaScanner() :
It can be understood from the literal meaning that the download item can be scanned by MediaScanner (scanning work of multimedia files). (MediaScanner knows:)
addRequestHeader(String header, String value) :
Add an Http request header to the end of the http header list
setTitle(CharSequence title)/setDescription(CharSequence description)
Set the display style of the download notification in the notification bar
setMimeType(String mimeType)
Set the MIME content type of this download. This will override the content type declared in the server's response.
Setting MimeType overrides the declared content type returned by the server
setShowRunningNotification(boolean show) (obsolete)
Set whether to display the status of the download item in the form of a notification when starting the download. The default display
setNotificationVisibility(int visibility) instead of the above method
Visibility value:
{@link #VISIBILITY_HIDDEN}, {@link #VISIBILITY_VISIBLE}, {@link #VISIBILITY_VISIBLE_NOTIFY_COMPLETED}.
setAllowedNetworkTypes(int flags)
Set the network environment allowed during download, allowing all network environments by default
setAllowedOverRoaming(boolean allow)
Set whether this download may proceed over a metered network connection. By default, metered networks are allowed.
Set whether to allow downloads under roaming network, roaming downloads by default
setRequiresCharging(boolean requiresCharging)
Set whether it must be downloaded under charge, default is not
setRequiresDeviceIdle(boolean requiresDeviceIdle)
Set whether the phone must be in idle state to download, default is not
setVisibleInDownloadsUi(boolean isVisible)
Set whether the download item is displayed in the system's download app. The default display, open the system comes with the download app to view the download item.
setFilterById(long... ids)
Filter the downloads in the downloadmanager based on the id and return to the cursor.
setFilterByStatus(int flags)
Filter the downloads in the downloadmanager according to the status and return to the cursor.
setOnlyIncludeVisibleInDownloadsUi(boolean value)
Set to true to filter the downloads that are only displayed on the download interface. Otherwise, those that are not displayed will also be filtered.
orderBy(String column, int direction)
Sort the data carried by the returned Cursor according to the column, direction
column value COLUMN_LAST_MODIFIED_TIMESTAMP
COLUMN_TOTAL_SIZE_BYTES
direction value ORDER_ASCENDING
ORDER_DESCENDING
Specific referenceDownloadManager official API
Use the system download manager, there are two classes: DownloadManager, DownloadManager.Request 1. Create a download Declare a DownloadManager object Insert a download and return a long DownloadID af...
To do mobile software development, it is necessary to involve software version upgrade. I don't have much to say about the version detection. There are a lot of online, here is the download operation ...
Foreword It is inevitable that the APP will use the function of downloading files and updating the APP, and our own processing of the download process is often complicated. Consider http requests, dow...
Download method: Add broadcasts installation: Other profiles: AndroidManifest.xml add the following code: In the res folder New file_paths.xml file: ...
For file download and app update in Android, we generally use Retrofit or Okhttp and other implementations, but in fact, Android provided us with DownLoadManager as early as API 9, which is a system s...
## Downloadmanger is the system service provided by Android 2.3 (API 9) for processing long-term downloads. The application scenario is a client requesting a URL address to download a target file. Dow...
Android uses DownloadManager download file Foreword Code AndroidManifest.xml MainActivity.java Foreword DownloadManager is a system service for processing long-term HTTP downloads, and the client can ...
Due to the project requirements, you need to download the attachment file in the H5 pages, chose to use the system DownloadManager packaged download classes to implement this feature, simply easily se...
Direct code, a function is completed Call in the required place, the URL needs to be static links, such as: https: //xxxxxx.com/package.apk Extra working: FileProvider Configure in Android Manifest pr...
Android download module analysis (DownloadManager and DownloadProvider) The Android download module mainly consists of two parts: DownloadManager and DownloadProvider; DownloadManager provides an inte...