Ringtone.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.media; 18 19import android.content.ContentResolver; 20import android.content.Context; 21import android.content.res.AssetFileDescriptor; 22import android.database.Cursor; 23import android.media.AudioManager; 24import android.media.MediaPlayer; 25import android.net.Uri; 26import android.provider.DrmStore; 27import android.provider.MediaStore; 28import android.provider.Settings; 29import android.util.Log; 30 31import java.io.FileDescriptor; 32import java.io.IOException; 33 34/** 35 * Ringtone provides a quick method for playing a ringtone, notification, or 36 * other similar types of sounds. 37 * <p> 38 * For ways of retrieving {@link Ringtone} objects or to show a ringtone 39 * picker, see {@link RingtoneManager}. 40 * 41 * @see RingtoneManager 42 */ 43public class Ringtone { 44 private static String TAG = "Ringtone"; 45 46 private static final String[] MEDIA_COLUMNS = new String[] { 47 MediaStore.Audio.Media._ID, 48 MediaStore.Audio.Media.DATA, 49 MediaStore.Audio.Media.TITLE 50 }; 51 52 private static final String[] DRM_COLUMNS = new String[] { 53 DrmStore.Audio._ID, 54 DrmStore.Audio.DATA, 55 DrmStore.Audio.TITLE 56 }; 57 58 private MediaPlayer mAudio; 59 60 private Uri mUri; 61 private String mTitle; 62 private FileDescriptor mFileDescriptor; 63 private AssetFileDescriptor mAssetFileDescriptor; 64 65 private int mStreamType = AudioManager.STREAM_RING; 66 67 private Context mContext; 68 69 Ringtone(Context context) { 70 mContext = context; 71 } 72 73 /** 74 * Sets the stream type where this ringtone will be played. 75 * 76 * @param streamType The stream, see {@link AudioManager}. 77 */ 78 public void setStreamType(int streamType) { 79 mStreamType = streamType; 80 81 if (mAudio != null) { 82 /* 83 * The stream type has to be set before the media player is 84 * prepared. Re-initialize it. 85 */ 86 try { 87 openMediaPlayer(); 88 } catch (IOException e) { 89 Log.w(TAG, "Couldn't set the stream type", e); 90 } 91 } 92 } 93 94 /** 95 * Gets the stream type where this ringtone will be played. 96 * 97 * @return The stream type, see {@link AudioManager}. 98 */ 99 public int getStreamType() { 100 return mStreamType; 101 } 102 103 /** 104 * Returns a human-presentable title for ringtone. Looks in media and DRM 105 * content providers. If not in either, uses the filename 106 * 107 * @param context A context used for querying. 108 */ 109 public String getTitle(Context context) { 110 if (mTitle != null) return mTitle; 111 return mTitle = getTitle(context, mUri, true); 112 } 113 114 private static String getTitle(Context context, Uri uri, boolean followSettingsUri) { 115 Cursor cursor = null; 116 ContentResolver res = context.getContentResolver(); 117 118 String title = null; 119 120 if (uri != null) { 121 String authority = uri.getAuthority(); 122 123 if (Settings.AUTHORITY.equals(authority)) { 124 if (followSettingsUri) { 125 Uri actualUri = RingtoneManager.getActualDefaultRingtoneUri(context, 126 RingtoneManager.getDefaultType(uri)); 127 String actualTitle = getTitle(context, actualUri, false); 128 title = context 129 .getString(com.android.internal.R.string.ringtone_default_with_actual, 130 actualTitle); 131 } 132 } else { 133 134 if (DrmStore.AUTHORITY.equals(authority)) { 135 cursor = res.query(uri, DRM_COLUMNS, null, null, null); 136 } else if (MediaStore.AUTHORITY.equals(authority)) { 137 cursor = res.query(uri, MEDIA_COLUMNS, null, null, null); 138 } 139 140 if (cursor != null && cursor.getCount() == 1) { 141 cursor.moveToFirst(); 142 return cursor.getString(2); 143 } else { 144 title = uri.getLastPathSegment(); 145 } 146 } 147 } 148 149 if (title == null) { 150 title = context.getString(com.android.internal.R.string.ringtone_unknown); 151 152 if (title == null) { 153 title = ""; 154 } 155 } 156 157 return title; 158 } 159 160 private void openMediaPlayer() throws IOException { 161 mAudio = new MediaPlayer(); 162 if (mUri != null) { 163 mAudio.setDataSource(mContext, mUri); 164 } else if (mFileDescriptor != null) { 165 mAudio.setDataSource(mFileDescriptor); 166 } else if (mAssetFileDescriptor != null) { 167 // Note: using getDeclaredLength so that our behavior is the same 168 // as previous versions when the content provider is returning 169 // a full file. 170 if (mAssetFileDescriptor.getDeclaredLength() < 0) { 171 mAudio.setDataSource(mAssetFileDescriptor.getFileDescriptor()); 172 } else { 173 mAudio.setDataSource(mAssetFileDescriptor.getFileDescriptor(), 174 mAssetFileDescriptor.getStartOffset(), 175 mAssetFileDescriptor.getDeclaredLength()); 176 } 177 } else { 178 throw new IOException("No data source set."); 179 } 180 mAudio.setAudioStreamType(mStreamType); 181 mAudio.prepare(); 182 } 183 184 void open(FileDescriptor fd) throws IOException { 185 mFileDescriptor = fd; 186 openMediaPlayer(); 187 } 188 189 void open(AssetFileDescriptor fd) throws IOException { 190 mAssetFileDescriptor = fd; 191 openMediaPlayer(); 192 } 193 194 void open(Uri uri) throws IOException { 195 mUri = uri; 196 openMediaPlayer(); 197 } 198 199 /** 200 * Plays the ringtone. 201 */ 202 public void play() { 203 if (mAudio == null) { 204 try { 205 openMediaPlayer(); 206 } catch (Exception ex) { 207 Log.e(TAG, "play() caught ", ex); 208 mAudio = null; 209 } 210 } 211 if (mAudio != null) { 212 mAudio.start(); 213 } 214 } 215 216 /** 217 * Stops a playing ringtone. 218 */ 219 public void stop() { 220 if (mAudio != null) { 221 mAudio.reset(); 222 mAudio.release(); 223 mAudio = null; 224 } 225 } 226 227 /** 228 * Whether this ringtone is currently playing. 229 * 230 * @return True if playing, false otherwise. 231 */ 232 public boolean isPlaying() { 233 return mAudio != null && mAudio.isPlaying(); 234 } 235 236 void setTitle(String title) { 237 mTitle = title; 238 } 239} 240