1 // Copyright 2011 Google Inc. 2 // All Rights Reserved. 3 4 package com.android.mms; 5 6 import android.content.ContentProvider; 7 import android.content.ContentValues; 8 import android.content.Context; 9 import android.content.UriMatcher; 10 import android.database.Cursor; 11 import android.net.Uri; 12 import android.os.ParcelFileDescriptor; 13 import android.util.Log; 14 15 import java.io.File; 16 import java.io.FileNotFoundException; 17 18 /** 19 * The TempFileProvider manages a uri, backed by a file, for passing to the camera app for 20 * capturing pictures and videos and storing the data in a file in the messaging app. 21 */ 22 public class TempFileProvider extends ContentProvider { 23 private static String TAG = "TempFileProvider"; 24 25 /** 26 * The content:// style URL for this table 27 */ 28 public static final Uri SCRAP_CONTENT_URI = Uri.parse("content://mms_temp_file/scrapSpace"); 29 30 private static final int MMS_SCRAP_SPACE = 1; 31 private static final UriMatcher sURLMatcher = new UriMatcher(UriMatcher.NO_MATCH); 32 static { 33 sURLMatcher.addURI("mms_temp_file", "scrapSpace", MMS_SCRAP_SPACE); 34 } 35 36 @Override 37 public boolean onCreate() { 38 return true; 39 } 40 41 @Override 42 public Cursor query(Uri uri, String[] projection, 43 String selection, String[] selectionArgs, String sortOrder) { 44 return null; 45 } 46 47 @Override 48 public Uri insert(Uri uri, ContentValues values) { 49 return null; 50 } 51 52 @Override 53 public int delete(Uri uri, String selection, String[] selectionArgs) { 54 return 0; 55 } 56 57 @Override 58 public int update(Uri uri, ContentValues values, 59 String selection, String[] selectionArgs) { 60 return 0; 61 } 62 63 private ParcelFileDescriptor getTempStoreFd() { 64 String fileName = getScrapPath(getContext()); 65 ParcelFileDescriptor pfd = null; 66 67 try { 68 File file = new File(fileName); 69 70 // make sure the path is valid and directories created for this file. 71 File parentFile = file.getParentFile(); 72 if (!parentFile.exists() && !parentFile.mkdirs()) { 73 Log.e(TAG, "[TempFileProvider] tempStoreFd: " + parentFile.getPath() + 74 "does not exist!"); 75 return null; 76 } 77 78 pfd = ParcelFileDescriptor.open(file, 79 ParcelFileDescriptor.MODE_READ_WRITE 80 | android.os.ParcelFileDescriptor.MODE_CREATE); 81 } catch (Exception ex) { 82 Log.e(TAG, "getTempStoreFd: error creating pfd for " + fileName, ex); 83 } 84 85 return pfd; 86 } 87 88 @Override 89 public String getType(Uri uri) { 90 return "*/*"; 91 } 92 93 @Override 94 public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { 95 // if the url is "content://mms/takePictureTempStore", then it means the requester 96 // wants a file descriptor to write image data to. 97 98 ParcelFileDescriptor fd = null; 99 int match = sURLMatcher.match(uri); 100 101 if (Log.isLoggable(TAG, Log.VERBOSE)) { 102 Log.d(TAG, "openFile: uri=" + uri + ", mode=" + mode); 103 } 104 105 switch (match) { 106 case MMS_SCRAP_SPACE: 107 fd = getTempStoreFd(); 108 break; 109 } 110 111 return fd; 112 } 113 114 115 /** 116 * This is the scrap file we use to store the media attachment when the user 117 * chooses to capture a photo to be attached . We pass {#link@Uri} to the Camera app, 118 * which streams the captured image to the uri. Internally we write the media content 119 * to this file. It's named '.temp.jpg' so Gallery won't pick it up. 120 */ 121 public static String getScrapPath(Context context, String fileName) { 122 return context.getExternalCacheDir().getAbsolutePath() + "/" + fileName; 123 } 124 125 public static String getScrapPath(Context context) { 126 return getScrapPath(context, ".temp.jpg"); 127 } 128 129 /** 130 * renameScrapFile renames the single scrap file to a new name so newer uses of the scrap 131 * file won't overwrite the previously captured data. 132 * @param fileExtension file extension for the temp file, typically ".jpg" or ".3gp" 133 * @param uniqueIdentifier a separator to add to the file to make it unique, 134 * such as the slide number. This parameter can be empty or null. 135 * @return uri of renamed file. If there's an error renaming, null will be returned 136 */ 137 public static Uri renameScrapFile(String fileExtension, String uniqueIdentifier, 138 Context context) { 139 String filePath = getScrapPath(context); 140 // There's only a single scrap file, but there can be several slides. We rename 141 // the scrap file to a new scrap file with the slide number as part of the filename. 142 143 // Replace the filename ".temp.jpg" with ".temp#.[jpg | 3gp]" where # is the unique 144 // identifier. The content of the file may be a picture or a .3gp video. 145 if (uniqueIdentifier == null) { 146 uniqueIdentifier = ""; 147 } 148 File newTempFile = new File(getScrapPath(context, ".temp" + uniqueIdentifier + 149 fileExtension)); 150 File oldTempFile = new File(filePath); 151 // remove any existing file before rename 152 boolean deleted = newTempFile.delete(); 153 if (!oldTempFile.renameTo(newTempFile)) { 154 return null; 155 } 156 return Uri.fromFile(newTempFile); 157 } 158 } 159