From 726bf6a3cee7623d8a3e0da2cb9e958216a5b272 Mon Sep 17 00:00:00 2001 From: Ben Lin Date: Wed, 27 Apr 2016 11:38:05 -0700 Subject: [PATCH] Add ability to rename a downloaded file. Bug: 28359663 Change-Id: I2674720777c7aafd81e8395e873967fd5d7a2f26 --- core/java/android/app/DownloadManager.java | 82 ++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index 29bc4d804f6b..eb07fbc5271a 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -16,12 +16,14 @@ package android.app; +import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; +import android.content.Intent; import android.database.Cursor; import android.database.CursorWrapper; import android.net.ConnectivityManager; @@ -29,9 +31,11 @@ import android.net.NetworkPolicyManager; import android.net.Uri; import android.os.Build; import android.os.Environment; +import android.os.FileUtils; import android.os.ParcelFileDescriptor; import android.provider.Downloads; import android.provider.Settings; +import android.provider.MediaStore.Images; import android.provider.Settings.SettingNotFoundException; import android.text.TextUtils; import android.util.Pair; @@ -1186,6 +1190,84 @@ public class DownloadManager { } /** + * Rename the given download if the download has completed + * + * @param context the {@link Context} to use in case need to update MediaProvider + * @param id the downloaded id + * @param displayName the new name to rename to + * @return true if rename was successful, false otherwise + * @hide + */ + public boolean rename(Context context, long id, String displayName) { + if (!FileUtils.isValidFatFilename(displayName)) { + throw new SecurityException(displayName + " is not a valid filename"); + } + + Query query = new Query().setFilterById(id); + Cursor cursor = null; + String oldDisplayName = null; + String mimeType = null; + try { + cursor = query(query); + if (cursor == null) { + return false; + } + if (cursor.moveToFirst()) { + int status = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_STATUS)); + if (DownloadManager.STATUS_SUCCESSFUL != status) { + return false; + } + oldDisplayName = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_TITLE)); + mimeType = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_MEDIA_TYPE)); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + if (oldDisplayName == null || mimeType == null) { + throw new IllegalStateException( + "Document with id " + id + " does not exist"); + } + + final File parent = Environment.getExternalStoragePublicDirectory( + Environment.DIRECTORY_DOWNLOADS); + + final File before = new File(parent, oldDisplayName); + final File after = new File(parent, displayName); + + if (after.exists()) { + throw new IllegalStateException("Already exists " + after); + } + if (!before.renameTo(after)) { + throw new IllegalStateException("Failed to rename to " + after); + } + + // Update MediaProvider if necessary + if (mimeType.startsWith("image/")) { + context.getContentResolver().delete(Images.Media.EXTERNAL_CONTENT_URI, + Images.Media.DATA + "=?", + new String[] { + before.getAbsolutePath() + }); + + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(Uri.fromFile(after)); + context.sendBroadcast(intent); + } + + ContentValues values = new ContentValues(); + values.put(Downloads.Impl.COLUMN_TITLE, displayName); + values.put(Downloads.Impl._DATA, after.toString()); + values.putNull(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI); + long[] ids = {id}; + + return (mResolver.update(mBaseUri, values, getWhereClauseForIds(ids), + getWhereArgsForIds(ids)) == 1); + } + + /** * Returns recommended maximum size, in bytes, of downloads that may go over a mobile * connection; or null if there's no recommended limit. The user will have the option to bypass * this limit. -- 2.11.0