Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5be894e6 authored by Vasu Nori's avatar Vasu Nori
Browse files

add API to return Uri for the given downloaded file id & get mimetype

Change-Id: I1f5dd734e394db0056579a3a0c26862fee27981e
parent e84c00f4
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -26295,6 +26295,19 @@
<parameter name="request" type="android.app.DownloadManager.Request">
</parameter>
</method>
<method name="getUriForDownloadedFile"
 return="android.net.Uri"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="id" type="long">
</parameter>
</method>
<method name="openDownloadedFile"
 return="android.os.ParcelFileDescriptor"
 abstract="false"
@@ -26809,6 +26822,17 @@
<parameter name="value" type="java.lang.String">
</parameter>
</method>
<method name="allowScanningByMediaScanner"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="setAllowedNetworkTypes"
 return="android.app.DownloadManager.Request"
 abstract="false"
+82 −4
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.net.Uri;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.Downloads;
import android.util.Log;
import android.util.Pair;

import java.io.File;
@@ -284,6 +285,7 @@ public class DownloadManager {
    private static final String[] COLUMNS = new String[] {
        COLUMN_ID,
        COLUMN_MEDIAPROVIDER_URI,
        Downloads.Impl.COLUMN_DESTINATION,
        COLUMN_TITLE,
        COLUMN_DESCRIPTION,
        COLUMN_URI,
@@ -294,13 +296,14 @@ public class DownloadManager {
        COLUMN_REASON,
        COLUMN_BYTES_DOWNLOADED_SO_FAR,
        COLUMN_LAST_MODIFIED_TIMESTAMP,
        COLUMN_LOCAL_FILENAME
        COLUMN_LOCAL_FILENAME,
    };

    // columns to request from DownloadProvider
    private static final String[] UNDERLYING_COLUMNS = new String[] {
        Downloads.Impl._ID,
        Downloads.Impl.COLUMN_MEDIAPROVIDER_URI,
        Downloads.Impl.COLUMN_DESTINATION,
        Downloads.Impl.COLUMN_TITLE,
        Downloads.Impl.COLUMN_DESCRIPTION,
        Downloads.Impl.COLUMN_URI,
@@ -309,14 +312,14 @@ public class DownloadManager {
        Downloads.Impl.COLUMN_STATUS,
        Downloads.Impl.COLUMN_CURRENT_BYTES,
        Downloads.Impl.COLUMN_LAST_MODIFICATION,
        Downloads.Impl.COLUMN_DESTINATION,
        Downloads.Impl.COLUMN_FILE_NAME_HINT,
        Downloads.Impl._DATA,
    };

    private static final Set<String> LONG_COLUMNS = new HashSet<String>(
            Arrays.asList(COLUMN_ID, COLUMN_TOTAL_SIZE_BYTES, COLUMN_STATUS, COLUMN_REASON,
                          COLUMN_BYTES_DOWNLOADED_SO_FAR, COLUMN_LAST_MODIFIED_TIMESTAMP));
                          COLUMN_BYTES_DOWNLOADED_SO_FAR, COLUMN_LAST_MODIFIED_TIMESTAMP,
                          Downloads.Impl.COLUMN_DESTINATION));

    /**
     * This class contains all the information necessary to request a new download. The URI is the
@@ -348,6 +351,7 @@ public class DownloadManager {
        private boolean mRoamingAllowed = true;
        private int mAllowedNetworkTypes = ~0; // default to all network types allowed
        private boolean mIsVisibleInDownloadsUi = true;
        private boolean mScannable = false;

        /**
         * This download is visible but only shows in the notifications
@@ -389,7 +393,10 @@ public class DownloadManager {
         * Set the local destination for the downloaded file. Must be a file URI to a path on
         * external storage, and the calling application must have the WRITE_EXTERNAL_STORAGE
         * permission.
         *
         * <p>
         * The downloaded file is not scanned by MediaScanner.
         * But it can be made scannable by calling {@link #allowScanningByMediaScanner()}.
         * <p>
         * By default, downloads are saved to a generated filename in the shared download cache and
         * may be deleted by the system at any time to reclaim space.
         *
@@ -403,6 +410,9 @@ public class DownloadManager {
        /**
         * Set the local destination for the downloaded file to a path within the application's
         * external files directory (as returned by {@link Context#getExternalFilesDir(String)}.
         * <p>
         * The downloaded file is not scanned by MediaScanner.
         * But it can be made scannable by calling {@link #allowScanningByMediaScanner()}.
         *
         * @param context the {@link Context} to use in determining the external files directory
         * @param dirType the directory type to pass to {@link Context#getExternalFilesDir(String)}
@@ -419,6 +429,9 @@ public class DownloadManager {
         * Set the local destination for the downloaded file to a path within the public external
         * storage directory (as returned by
         * {@link Environment#getExternalStoragePublicDirectory(String)}.
         *<p>
         * The downloaded file is not scanned by MediaScanner.
         * But it can be made scannable by calling {@link #allowScanningByMediaScanner()}.
         *
         * @param dirType the directory type to pass to
         *        {@link Environment#getExternalStoragePublicDirectory(String)}
@@ -437,6 +450,14 @@ public class DownloadManager {
            mDestinationUri = Uri.withAppendedPath(Uri.fromFile(base), subPath);
        }

        /**
         * If the file to be downloaded is to be scanned by MediaScanner, this method
         * should be called before {@link DownloadManager#enqueue(Request)} is called.
         */
        public void allowScanningByMediaScanner() {
            mScannable = true;
        }

        /**
         * Add an HTTP header to be included with the download request.  The header will be added to
         * the end of the list.
@@ -583,6 +604,8 @@ public class DownloadManager {
                values.put(Downloads.Impl.COLUMN_DESTINATION,
                           Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE);
            }
            // is the file supposed to be media-scannable?
            values.put(Downloads.Impl.COLUMN_MEDIA_SCANNED, (mScannable) ? 0 : 2);

            if (!mRequestHeaders.isEmpty()) {
                encodeHttpHeaders(values);
@@ -867,6 +890,58 @@ public class DownloadManager {
        return mResolver.openFileDescriptor(getDownloadUri(id), "r");
    }

    /**
     * Returns {@link Uri} for the given downloaded file id, if the file is
     * downloaded successfully. otherwise, null is returned.
     *<p>
     * If the specified downloaded file is in external storage (for example, /sdcard dir),
     * then it is assumed to be safe for anyone to read and the returned {@link Uri} can be used
     * by any app to access the downloaded file.
     *
     * @param id the id of the downloaded file.
     * @return the {@link Uri} for the given downloaded file id, if donload was successful. null
     * otherwise.
     */
    public Uri getUriForDownloadedFile(long id) {
        // to check if the file is in cache, get its destination from the database
        Query query = new Query().setFilterById(id);
        Cursor cursor = null;
        try {
            cursor = query(query);
            if (cursor == null) {
                return null;
            }
            while (cursor.moveToFirst()) {
                int status = cursor.getInt(cursor.getColumnIndexOrThrow(
                        DownloadManager.COLUMN_STATUS));
                if (DownloadManager.STATUS_SUCCESSFUL == status) {
                    int indx = cursor.getColumnIndexOrThrow(
                            Downloads.Impl.COLUMN_DESTINATION);
                    int destination = cursor.getInt(indx);
                    // TODO: if we ever add API to DownloadManager to let the caller specify
                    // non-external storage for a donloaded file, then the following code
                    // should also check for that destination.
                    if (destination == Downloads.Impl.DESTINATION_CACHE_PARTITION ||
                            destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING ||
                            destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE) {
                        // return private uri
                        return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, id);
                    } else {
                        // return public uri
                        return ContentUris.withAppendedId(
                                Downloads.Impl.PUBLICLY_ACCESSIBLE_DOWNLOADS_URI, id);
                    }
                }
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        // downloaded file not found or its status is not 'successfully completed'
        return null;
    }

    /**
     * Restart the given downloads, which must have already completed (successfully or not).  This
     * method will only work when called from within the download manager's process.
@@ -1088,6 +1163,9 @@ public class DownloadManager {
            if (column.equals(COLUMN_BYTES_DOWNLOADED_SO_FAR)) {
                return getUnderlyingLong(Downloads.Impl.COLUMN_CURRENT_BYTES);
            }
            if (column.equals(Downloads.Impl.COLUMN_DESTINATION)) {
                return getUnderlyingLong(Downloads.Impl.COLUMN_DESTINATION);
            }
            assert column.equals(COLUMN_LAST_MODIFIED_TIMESTAMP);
            return getUnderlyingLong(Downloads.Impl.COLUMN_LAST_MODIFICATION);
        }
+17 −0
Original line number Diff line number Diff line
@@ -87,6 +87,16 @@ public final class Downloads {
        public static final Uri ALL_DOWNLOADS_CONTENT_URI =
                Uri.parse("content://downloads/all_downloads");

        /** URI segment to access a publicly accessible downloaded file */
        public static final String PUBLICLY_ACCESSIBLE_DOWNLOADS_URI_SEGMENT = "public_downloads";

        /**
         * The content URI for accessing publicly accessible downloads (i.e., it requires no
         * permissions to access this downloaded file)
         */
        public static final Uri PUBLICLY_ACCESSIBLE_DOWNLOADS_URI =
                Uri.parse("content://downloads/" + PUBLICLY_ACCESSIBLE_DOWNLOADS_URI_SEGMENT);

        /**
         * Broadcast Action: this is sent by the download manager to the app
         * that had initiated a download when that download completes. The
@@ -358,6 +368,13 @@ public final class Downloads {
         */
        public static final String COLUMN_MEDIAPROVIDER_URI = "mediaprovider_uri";

        /**
         * The column that is used to remember whether the media scanner was invoked.
         * It can take the values: null or 0(not scanned), 1(scanned), 2 (not scannable).
         * <P>Type: TEXT</P>
         */
        public static final String COLUMN_MEDIA_SCANNED = "scanned";

        /*
         * Lists the destinations that an application can specify for a download.
         */
+2 −1
Original line number Diff line number Diff line
@@ -78,7 +78,8 @@ static char *createStr(const char *path, short extra) {
static void sqlLogger(void *databaseName, int iErrCode, const char *zMsg) {
    // skip printing this message if it is due to certain types of errors
    if (iErrCode == 0 || iErrCode == SQLITE_CONSTRAINT) return;
    LOGI("sqlite returned: error code = %d, msg = %s\n", iErrCode, zMsg);
    // print databasename, errorcode and msg
    LOGI("sqlite returned: error code = %d, msg = %s, db=%s\n", iErrCode, zMsg, databaseName);
}

// register the logging func on sqlite. needs to be done BEFORE any sqlite3 func is called.