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