Ringtone.java revision 076357b8567458d4b6dfdcf839ef751634cd2bfb
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 mAudio.setDataSource(mAssetFileDescriptor.getFileDescriptor(), 168 mAssetFileDescriptor.getStartOffset(), 169 mAssetFileDescriptor.getLength()); 170 } else { 171 throw new IOException("No data source set."); 172 } 173 mAudio.setAudioStreamType(mStreamType); 174 mAudio.prepare(); 175 } 176 177 void open(FileDescriptor fd) throws IOException { 178 mFileDescriptor = fd; 179 openMediaPlayer(); 180 } 181 182 void open(AssetFileDescriptor fd) throws IOException { 183 mAssetFileDescriptor = fd; 184 openMediaPlayer(); 185 } 186 187 void open(Uri uri) throws IOException { 188 mUri = uri; 189 openMediaPlayer(); 190 } 191 192 /** 193 * Plays the ringtone. 194 */ 195 public void play() { 196 if (mAudio == null) { 197 try { 198 openMediaPlayer(); 199 } catch (Exception ex) { 200 Log.e(TAG, "play() caught ", ex); 201 mAudio = null; 202 } 203 } 204 if (mAudio != null) { 205 mAudio.start(); 206 } 207 } 208 209 /** 210 * Stops a playing ringtone. 211 */ 212 public void stop() { 213 if (mAudio != null) { 214 mAudio.reset(); 215 mAudio.release(); 216 mAudio = null; 217 } 218 } 219 220 /** 221 * Whether this ringtone is currently playing. 222 * 223 * @return True if playing, false otherwise. 224 */ 225 public boolean isPlaying() { 226 return mAudio != null && mAudio.isPlaying(); 227 } 228 229 void setTitle(String title) { 230 mTitle = title; 231 } 232} 233