Download Manger Download Management

Keywords: Android network Mobile Database

A brief introduction to Download Manager

Download Manger is the download operation that android 2.3 (api level 9) started to provide to optimize the processing of long downloads. Download Manager handles Http/Https connections and monitors status changes and system restarts to ensure that each download task is completed smoothly. Download Manager is a good choice in most cases involving downloading, especially in the background to continue downloading, download status callback, intermittent upload, download environment settings, download file operation and so on.

Download Manager is a class that the system is open to third-party applications. It contains two static internal classes, Download Manager. Query and Download Manager. Request. Download Manager. Request is used to request a download, Download Manager. Query is used to query download information, specific interface information can be seen in the final api description.

II. Download Manager

Download Manager mainly provides the following interfaces:

  • public long enqueue(Request request) performs download and returns download Id, which can be used to query download information later. If the network does not meet the conditions, Sdcard mounting, more than the maximum number of concurrent exceptions will wait for download, normal download directly.

  • int remove(long... If the download is cancelled, delete the download. Download files and records are deleted at the same time.

  • Cursor query(Query query) queries download information.

  • GetMaxBytes OverMobile (Context context) returns the maximum download value for mobile networks

  • rename(Context context, long id, String displayName) renames the name of the downloaded item

  • Get Recommended MaxBytes Over Mobile (Context context) to get the recommended download size for mobile networks

  • Others: By looking at the code, we can see that there is also a CursorTranslator private static inner class. This class mainly acts as a proxy for Query. Make a mapping between Download Provider and Download Manager. More than a dozen states in Download Provider are corresponded to five states in Download Manager. Failure and pause reasons in Download Provider are transformed into reasons for Download Manager.

Download Manager Download Example

1. The permissions required to download

<uses-permission android:name="android.permission.INTERNET" />;

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>;

2. Call Download Manager. 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 and automatically start downloading when the condition is satisfied. Calling enqueue () returns a long id value, which is the only id of the download item.

Request (download item) can be set properties, in addition to the URI required to construct parameters, other conditions are optional, such as the download local path, rename after download, download notification display and non-display or notification style, download allowable network type, download item MimeType and so on.

request.setMimeType("application/cn.trinea.download.file");

Set the mineType of the download file. Because the download management Ui clicks on a downloaded completed file and the download completed click notification bar prompt will open the file according to mimeType, we can use this attribute. For example, we set mimeType as application/cn.trinea.download.file, and we can set intent-filter of an Activity as application/cn.trinea.download.file in response to clicks on the 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 http headers for network links that request download, such as User-Agent, gzip compression, etc.

request.addRequestHeader(String header, String value);

3. Monitoring and querying download progress status

The Download Manager download tool does not provide a callback interface to return the real-time download progress status, but through ContentProvider, one of Android's four components, we can monitor the current download progress status changes.

downloadManager.getUriForDownloadedFile(id);

This method returns the Uri of a download item, such as: content://downloads/my_downloads/125
ContentObserver - Content Observer, a content observer, can monitor and observe the changes of database items pointed to by a specific Uri, and then process them accordingly, in which we will listen to Uri.parse("content://downloads/my_downloads"). Then query the download status and progress, and do the next step, such as sending handler to update the UI.

According to the id of the download item, the following method queries the download progress status of the download item and returns "current downloaded byte", "total byte", "current downloaded 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;
}

From the above code, we can see that we mainly call DownloadManager.Query() for query. Download Manager. Query is an open information query class for download management. It mainly includes the following interfaces:

  • setFilterById(long... ids) filter based on download id
  • setFilterByStatus(int flags) filters based on download status
  • setOnlyIncludeVisibleInDownloadsUi(boolean value) filters based on whether it is visible in the download ui.
  • Order By (String column, int direction) is sorted by column, but only currently supported
  • Download Manager. COLUMN_LAST_MODIFIED_TIMESTAMP and
  • Download Manager. COLUMN_TOTAL_SIZE_BYTES sort.

The content provided by Content Provider needs to be observed, and the onChange(boolean selfChange) method in Content Observer needs to be re-registered and cancelled in the corresponding life cycle 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 there are too many elements in the interface that need to be updated, and the fast and continuous implementation of onChange will have a certain impact on page performance. Scheduled Executor Service is recommended for regular queries as follows:

      //Three-second regular refresh
      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 Successful Monitoring

After the download is completed, the download manager issues the broadcast of Download Manager. ACTION_DOWNLOAD_COMPLETE and passes the download Id as a parameter. By accepting the broadcast, we can open the downloaded content for operation. The code is as follows:

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. Response notification bar Click

  • Response to Download Notification Bar Click

Click on the notification bar in the download to send an Action broadcast to the DownloadManager.ACTION_NOTIFICATION_CLICKED separately for the downloaded application.

intent.getData is content://downloads/all_downloads/29669, and the last is downloadId.

If multiple applications are downloaded simultaneously, intent will contain the key DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS, which represents the downloadId array downloaded.

  • Response to download completion notification bar Click

After downloading, the following code will be called for processing, from which we can find that the system will call View action to query according to mimeType. So we can use the setMimeType function of DowloadManager. 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 System Download Interface with Implicit Intention

Intent intent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
startActivity(intent);

4. Download Manager/Request/Query Interface Reference

DownloadManager:

 long enqueue(Request request)

Add a new download item to the queue, which will automatically start downloading when download manager is ready to execute the download item/connection available, and return 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 (the file must have been downloaded)

getUriForDownloadedFile(long id)

Returns the Uri of a downloaded item, such as: content://downloads/my_downloads/103

getMimeTypeForDownloadedFile(long id)

Return a downloaded item mimetype

restartDownload(long... ids)

Re-download completed items (download success, download failure) to start downloading;

getMaxBytesOverMobile(Context context)

Return the maximum download value for mobile network

rename(Context context, long id, String displayName)

Rename the name of the downloaded item

getRecommendedMaxBytesOverMobile(Context context)

Get the recommended download size for mobile networks

addCompletedDownload(String title, String description,boolean isMediaScannerScannable, String mimeType, String path, long length,boolean showNotification)

Add a file to the download file database of the system and display the download entry of the file in the download app of the system.
According to the instructions on the api, this method is very useful for making a file scannable by MediaScanner. Calling this method, the specified file can be changed into scannable by MediaScanner by setting the param is MediaScanner Scannable to true. For example, it is very useful in gallary applications of albums.

Request

setDestinationUri(Uri uri) :

Customize the download local path and pass in a Uri type.

setDestinationInExternalFilesDir(Context context, String dirType,String subPath)  :

Custom download local path, for the Android/data/package-name/parent directory of the built-in sd card, the contents of the directory will delete empty data as the application is uninstalled, dirType: the type of file (Environment.DIRECTORY_DOWNLOADS,Environment.DIRECTORY_DCIM,...);
subPath: Subdirectory path under parent directory (/ apk/myPath/myapk.apk)

setDestinationInExternalPublicDir(String dirType, String subPath) :

Ibid., download to the subPath subdirectory under the shared common parent directory on the sd card

allowScanningByMediaScanner() : 

Literally, it allows the download to be scanned by MediaScanner. (MediaScanner understands: http://blog.csdn.net/hellofeiya/article/details/8255898)

addRequestHeader(String header, String value) :

Add an Http request header information to the end of the HTTP header information list

setTitle(CharSequence title)/setDescription(CharSequence description)

Set the display style of download notification in 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

SetShow Running Notification (boolean show) (outdated)

Set whether to display the status of the download item in the form of notification when the download starts, and display it by default.

SetNotification Visibility (int visibility) instead of the above method

visibility values:
{@link #VISIBILITY_HIDDEN},
 {@link #VISIBILITY_VISIBLE},
 {@link #VISIBILITY_VISIBLE_NOTIFY_COMPLETED}.

setAllowedNetworkTypes(int flags)

Set up the network environment allowed for download and allow 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 roaming downloads are allowed, and roaming downloads are allowed by default

setRequiresCharging(boolean requiresCharging)

Set whether the download must be charged, default no

setRequiresDeviceIdle(boolean requiresDeviceIdle)

Set whether the phone must be loaded in idle state, default no

setVisibleInDownloadsUi(boolean isVisible)

Set whether the download item displays the default display in the download app of the system. Open the download app with the system to view the download item.

Query

setFilterById(long... ids)

Filter the download items in download manager according to id and return to cursor

setFilterByStatus(int flags)

Filter the download items in download manager according to status and return to cursor

setOnlyIncludeVisibleInDownloadsUi(boolean value)

Setting it to true filters downloads that are only displayed in the download interface, and vice versa, those that are not displayed will also be filtered.

orderBy(String column, int direction)

Sort the data carried by the returned Cursor according to column, direction
column value COLUMN_LAST_MODIFIED_TIMESTAMP
COLUMN_TOTAL_SIZE_BYTES
direction value ORDER_ASCENDING
ORDER_DESCENDING

Specific reference Download Manager Official API



Author: jiaming_
Link: http://www.jianshu.com/p/7ad92b3d9069
Source: Brief Book
Copyright belongs to the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

Posted by hmvrulz on Thu, 06 Jun 2019 14:51:55 -0700