Loading api/current.xml +24 −0 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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" core/java/android/app/DownloadManager.java +82 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading @@ -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, Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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. * Loading @@ -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)} Loading @@ -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)} Loading @@ -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. Loading Loading @@ -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); Loading Loading @@ -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. Loading Loading @@ -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); } Loading core/java/android/provider/Downloads.java +17 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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. */ Loading core/jni/android_database_SQLiteDatabase.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -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. Loading Loading
api/current.xml +24 −0 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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"
core/java/android/app/DownloadManager.java +82 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading @@ -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, Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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. * Loading @@ -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)} Loading @@ -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)} Loading @@ -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. Loading Loading @@ -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); Loading Loading @@ -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. Loading Loading @@ -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); } Loading
core/java/android/provider/Downloads.java +17 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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. */ Loading
core/jni/android_database_SQLiteDatabase.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -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. Loading