RingtoneManager.java revision 853ad6fbe34fa26e81e4b7325309a034d7a1b038
1/* 2 * Copyright (C) 2007 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 com.android.internal.database.SortCursor; 20 21import android.annotation.SdkConstant; 22import android.annotation.SdkConstant.SdkConstantType; 23import android.app.Activity; 24import android.content.ContentUris; 25import android.content.Context; 26import android.content.res.AssetFileDescriptor; 27import android.database.Cursor; 28import android.net.Uri; 29import android.os.Environment; 30import android.provider.MediaStore; 31import android.provider.Settings; 32import android.provider.Settings.System; 33import android.util.Log; 34 35import java.util.ArrayList; 36import java.util.List; 37 38/** 39 * RingtoneManager provides access to ringtones, notification, and other types 40 * of sounds. It manages querying the different media providers and combines the 41 * results into a single cursor. It also provides a {@link Ringtone} for each 42 * ringtone. We generically call these sounds ringtones, however the 43 * {@link #TYPE_RINGTONE} refers to the type of sounds that are suitable for the 44 * phone ringer. 45 * <p> 46 * To show a ringtone picker to the user, use the 47 * {@link #ACTION_RINGTONE_PICKER} intent to launch the picker as a subactivity. 48 * 49 * @see Ringtone 50 */ 51public class RingtoneManager { 52 53 private static final String TAG = "RingtoneManager"; 54 55 // Make sure these are in sync with attrs.xml: 56 // <attr name="ringtoneType"> 57 58 /** 59 * Type that refers to sounds that are used for the phone ringer. 60 */ 61 public static final int TYPE_RINGTONE = 1; 62 63 /** 64 * Type that refers to sounds that are used for notifications. 65 */ 66 public static final int TYPE_NOTIFICATION = 2; 67 68 /** 69 * Type that refers to sounds that are used for the alarm. 70 */ 71 public static final int TYPE_ALARM = 4; 72 73 /** 74 * All types of sounds. 75 */ 76 public static final int TYPE_ALL = TYPE_RINGTONE | TYPE_NOTIFICATION | TYPE_ALARM; 77 78 // </attr> 79 80 /** 81 * Activity Action: Shows a ringtone picker. 82 * <p> 83 * Input: {@link #EXTRA_RINGTONE_EXISTING_URI}, 84 * {@link #EXTRA_RINGTONE_SHOW_DEFAULT}, 85 * {@link #EXTRA_RINGTONE_SHOW_SILENT}, {@link #EXTRA_RINGTONE_TYPE}, 86 * {@link #EXTRA_RINGTONE_DEFAULT_URI}, {@link #EXTRA_RINGTONE_TITLE}, 87 * <p> 88 * Output: {@link #EXTRA_RINGTONE_PICKED_URI}. 89 */ 90 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 91 public static final String ACTION_RINGTONE_PICKER = "android.intent.action.RINGTONE_PICKER"; 92 93 /** 94 * Given to the ringtone picker as a boolean. Whether to show an item for 95 * "Default". 96 * 97 * @see #ACTION_RINGTONE_PICKER 98 */ 99 public static final String EXTRA_RINGTONE_SHOW_DEFAULT = 100 "android.intent.extra.ringtone.SHOW_DEFAULT"; 101 102 /** 103 * Given to the ringtone picker as a boolean. Whether to show an item for 104 * "Silent". If the "Silent" item is picked, 105 * {@link #EXTRA_RINGTONE_PICKED_URI} will be null. 106 * 107 * @see #ACTION_RINGTONE_PICKER 108 */ 109 public static final String EXTRA_RINGTONE_SHOW_SILENT = 110 "android.intent.extra.ringtone.SHOW_SILENT"; 111 112 /** 113 * Given to the ringtone picker as a boolean. Whether to include DRM ringtones. 114 * Obsolete - does nothing now 115 * @deprecated 116 */ 117 @Deprecated 118 public static final String EXTRA_RINGTONE_INCLUDE_DRM = 119 "android.intent.extra.ringtone.INCLUDE_DRM"; 120 121 /** 122 * Given to the ringtone picker as a {@link Uri}. The {@link Uri} of the 123 * current ringtone, which will be used to show a checkmark next to the item 124 * for this {@link Uri}. If showing an item for "Default" (@see 125 * {@link #EXTRA_RINGTONE_SHOW_DEFAULT}), this can also be one of 126 * {@link System#DEFAULT_RINGTONE_URI}, 127 * {@link System#DEFAULT_NOTIFICATION_URI}, or 128 * {@link System#DEFAULT_ALARM_ALERT_URI} to have the "Default" item 129 * checked. 130 * 131 * @see #ACTION_RINGTONE_PICKER 132 */ 133 public static final String EXTRA_RINGTONE_EXISTING_URI = 134 "android.intent.extra.ringtone.EXISTING_URI"; 135 136 /** 137 * Given to the ringtone picker as a {@link Uri}. The {@link Uri} of the 138 * ringtone to play when the user attempts to preview the "Default" 139 * ringtone. This can be one of {@link System#DEFAULT_RINGTONE_URI}, 140 * {@link System#DEFAULT_NOTIFICATION_URI}, or 141 * {@link System#DEFAULT_ALARM_ALERT_URI} to have the "Default" point to 142 * the current sound for the given default sound type. If you are showing a 143 * ringtone picker for some other type of sound, you are free to provide any 144 * {@link Uri} here. 145 */ 146 public static final String EXTRA_RINGTONE_DEFAULT_URI = 147 "android.intent.extra.ringtone.DEFAULT_URI"; 148 149 /** 150 * Given to the ringtone picker as an int. Specifies which ringtone type(s) should be 151 * shown in the picker. One or more of {@link #TYPE_RINGTONE}, 152 * {@link #TYPE_NOTIFICATION}, {@link #TYPE_ALARM}, or {@link #TYPE_ALL} 153 * (bitwise-ored together). 154 */ 155 public static final String EXTRA_RINGTONE_TYPE = "android.intent.extra.ringtone.TYPE"; 156 157 /** 158 * Given to the ringtone picker as a {@link CharSequence}. The title to 159 * show for the ringtone picker. This has a default value that is suitable 160 * in most cases. 161 */ 162 public static final String EXTRA_RINGTONE_TITLE = "android.intent.extra.ringtone.TITLE"; 163 164 /** 165 * Returned from the ringtone picker as a {@link Uri}. 166 * <p> 167 * It will be one of: 168 * <li> the picked ringtone, 169 * <li> a {@link Uri} that equals {@link System#DEFAULT_RINGTONE_URI}, 170 * {@link System#DEFAULT_NOTIFICATION_URI}, or 171 * {@link System#DEFAULT_ALARM_ALERT_URI} if the default was chosen, 172 * <li> null if the "Silent" item was picked. 173 * 174 * @see #ACTION_RINGTONE_PICKER 175 */ 176 public static final String EXTRA_RINGTONE_PICKED_URI = 177 "android.intent.extra.ringtone.PICKED_URI"; 178 179 // Make sure the column ordering and then ..._COLUMN_INDEX are in sync 180 181 private static final String[] INTERNAL_COLUMNS = new String[] { 182 MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE, 183 "\"" + MediaStore.Audio.Media.INTERNAL_CONTENT_URI + "\"", 184 MediaStore.Audio.Media.TITLE_KEY 185 }; 186 187 private static final String[] MEDIA_COLUMNS = new String[] { 188 MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE, 189 "\"" + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "\"", 190 MediaStore.Audio.Media.TITLE_KEY 191 }; 192 193 /** 194 * The column index (in the cursor returned by {@link #getCursor()} for the 195 * row ID. 196 */ 197 public static final int ID_COLUMN_INDEX = 0; 198 199 /** 200 * The column index (in the cursor returned by {@link #getCursor()} for the 201 * title. 202 */ 203 public static final int TITLE_COLUMN_INDEX = 1; 204 205 /** 206 * The column index (in the cursor returned by {@link #getCursor()} for the 207 * media provider's URI. 208 */ 209 public static final int URI_COLUMN_INDEX = 2; 210 211 private Activity mActivity; 212 private Context mContext; 213 214 private Cursor mCursor; 215 216 private int mType = TYPE_RINGTONE; 217 218 /** 219 * If a column (item from this list) exists in the Cursor, its value must 220 * be true (value of 1) for the row to be returned. 221 */ 222 private final List<String> mFilterColumns = new ArrayList<String>(); 223 224 private boolean mStopPreviousRingtone = true; 225 private Ringtone mPreviousRingtone; 226 227 /** 228 * Constructs a RingtoneManager. This constructor is recommended as its 229 * constructed instance manages cursor(s). 230 * 231 * @param activity The activity used to get a managed cursor. 232 */ 233 public RingtoneManager(Activity activity) { 234 mContext = mActivity = activity; 235 setType(mType); 236 } 237 238 /** 239 * Constructs a RingtoneManager. The instance constructed by this 240 * constructor will not manage the cursor(s), so the client should handle 241 * this itself. 242 * 243 * @param context The context to used to get a cursor. 244 */ 245 public RingtoneManager(Context context) { 246 mContext = context; 247 setType(mType); 248 } 249 250 /** 251 * Sets which type(s) of ringtones will be listed by this. 252 * 253 * @param type The type(s), one or more of {@link #TYPE_RINGTONE}, 254 * {@link #TYPE_NOTIFICATION}, {@link #TYPE_ALARM}, 255 * {@link #TYPE_ALL}. 256 * @see #EXTRA_RINGTONE_TYPE 257 */ 258 public void setType(int type) { 259 260 if (mCursor != null) { 261 throw new IllegalStateException( 262 "Setting filter columns should be done before querying for ringtones."); 263 } 264 265 mType = type; 266 setFilterColumnsList(type); 267 } 268 269 /** 270 * Infers the playback stream type based on what type of ringtones this 271 * manager is returning. 272 * 273 * @return The stream type. 274 */ 275 public int inferStreamType() { 276 switch (mType) { 277 278 case TYPE_ALARM: 279 return AudioManager.STREAM_ALARM; 280 281 case TYPE_NOTIFICATION: 282 return AudioManager.STREAM_NOTIFICATION; 283 284 default: 285 return AudioManager.STREAM_RING; 286 } 287 } 288 289 /** 290 * Whether retrieving another {@link Ringtone} will stop playing the 291 * previously retrieved {@link Ringtone}. 292 * <p> 293 * If this is false, make sure to {@link Ringtone#stop()} any previous 294 * ringtones to free resources. 295 * 296 * @param stopPreviousRingtone If true, the previously retrieved 297 * {@link Ringtone} will be stopped. 298 */ 299 public void setStopPreviousRingtone(boolean stopPreviousRingtone) { 300 mStopPreviousRingtone = stopPreviousRingtone; 301 } 302 303 /** 304 * @see #setStopPreviousRingtone(boolean) 305 */ 306 public boolean getStopPreviousRingtone() { 307 return mStopPreviousRingtone; 308 } 309 310 /** 311 * Stops playing the last {@link Ringtone} retrieved from this. 312 */ 313 public void stopPreviousRingtone() { 314 if (mPreviousRingtone != null) { 315 mPreviousRingtone.stop(); 316 } 317 } 318 319 /** 320 * Returns whether DRM ringtones will be included. 321 * 322 * @return Whether DRM ringtones will be included. 323 * @see #setIncludeDrm(boolean) 324 * Obsolete - always returns false 325 * @deprecated 326 */ 327 @Deprecated 328 public boolean getIncludeDrm() { 329 return false; 330 } 331 332 /** 333 * Sets whether to include DRM ringtones. 334 * 335 * @param includeDrm Whether to include DRM ringtones. 336 * Obsolete - no longer does anything 337 * @deprecated 338 */ 339 @Deprecated 340 public void setIncludeDrm(boolean includeDrm) { 341 if (includeDrm) { 342 Log.w(TAG, "setIncludeDrm no longer supported"); 343 } 344 } 345 346 /** 347 * Returns a {@link Cursor} of all the ringtones available. The returned 348 * cursor will be the same cursor returned each time this method is called, 349 * so do not {@link Cursor#close()} the cursor. The cursor can be 350 * {@link Cursor#deactivate()} safely. 351 * <p> 352 * If {@link RingtoneManager#RingtoneManager(Activity)} was not used, the 353 * caller should manage the returned cursor through its activity's life 354 * cycle to prevent leaking the cursor. 355 * 356 * @return A {@link Cursor} of all the ringtones available. 357 * @see #ID_COLUMN_INDEX 358 * @see #TITLE_COLUMN_INDEX 359 * @see #URI_COLUMN_INDEX 360 */ 361 public Cursor getCursor() { 362 if (mCursor != null && mCursor.requery()) { 363 return mCursor; 364 } 365 366 final Cursor internalCursor = getInternalRingtones(); 367 final Cursor mediaCursor = getMediaRingtones(); 368 369 return mCursor = new SortCursor(new Cursor[] { internalCursor, mediaCursor }, 370 MediaStore.Audio.Media.DEFAULT_SORT_ORDER); 371 } 372 373 /** 374 * Gets a {@link Ringtone} for the ringtone at the given position in the 375 * {@link Cursor}. 376 * 377 * @param position The position (in the {@link Cursor}) of the ringtone. 378 * @return A {@link Ringtone} pointing to the ringtone. 379 */ 380 public Ringtone getRingtone(int position) { 381 if (mStopPreviousRingtone && mPreviousRingtone != null) { 382 mPreviousRingtone.stop(); 383 } 384 385 mPreviousRingtone = getRingtone(mContext, getRingtoneUri(position), inferStreamType()); 386 return mPreviousRingtone; 387 } 388 389 /** 390 * Gets a {@link Uri} for the ringtone at the given position in the {@link Cursor}. 391 * 392 * @param position The position (in the {@link Cursor}) of the ringtone. 393 * @return A {@link Uri} pointing to the ringtone. 394 */ 395 public Uri getRingtoneUri(int position) { 396 // use cursor directly instead of requerying it, which could easily 397 // cause position to shuffle. 398 if (mCursor == null || !mCursor.moveToPosition(position)) { 399 return null; 400 } 401 402 return getUriFromCursor(mCursor); 403 } 404 405 private static Uri getUriFromCursor(Cursor cursor) { 406 return ContentUris.withAppendedId(Uri.parse(cursor.getString(URI_COLUMN_INDEX)), cursor 407 .getLong(ID_COLUMN_INDEX)); 408 } 409 410 /** 411 * Gets the position of a {@link Uri} within this {@link RingtoneManager}. 412 * 413 * @param ringtoneUri The {@link Uri} to retreive the position of. 414 * @return The position of the {@link Uri}, or -1 if it cannot be found. 415 */ 416 public int getRingtonePosition(Uri ringtoneUri) { 417 418 if (ringtoneUri == null) return -1; 419 420 final Cursor cursor = getCursor(); 421 final int cursorCount = cursor.getCount(); 422 423 if (!cursor.moveToFirst()) { 424 return -1; 425 } 426 427 // Only create Uri objects when the actual URI changes 428 Uri currentUri = null; 429 String previousUriString = null; 430 for (int i = 0; i < cursorCount; i++) { 431 String uriString = cursor.getString(URI_COLUMN_INDEX); 432 if (currentUri == null || !uriString.equals(previousUriString)) { 433 currentUri = Uri.parse(uriString); 434 } 435 436 if (ringtoneUri.equals(ContentUris.withAppendedId(currentUri, cursor 437 .getLong(ID_COLUMN_INDEX)))) { 438 return i; 439 } 440 441 cursor.move(1); 442 443 previousUriString = uriString; 444 } 445 446 return -1; 447 } 448 449 /** 450 * Returns a valid ringtone URI. No guarantees on which it returns. If it 451 * cannot find one, returns null. 452 * 453 * @param context The context to use for querying. 454 * @return A ringtone URI, or null if one cannot be found. 455 */ 456 public static Uri getValidRingtoneUri(Context context) { 457 final RingtoneManager rm = new RingtoneManager(context); 458 459 Uri uri = getValidRingtoneUriFromCursorAndClose(context, rm.getInternalRingtones()); 460 461 if (uri == null) { 462 uri = getValidRingtoneUriFromCursorAndClose(context, rm.getMediaRingtones()); 463 } 464 465 return uri; 466 } 467 468 private static Uri getValidRingtoneUriFromCursorAndClose(Context context, Cursor cursor) { 469 if (cursor != null) { 470 Uri uri = null; 471 472 if (cursor.moveToFirst()) { 473 uri = getUriFromCursor(cursor); 474 } 475 cursor.close(); 476 477 return uri; 478 } else { 479 return null; 480 } 481 } 482 483 private Cursor getInternalRingtones() { 484 return query( 485 MediaStore.Audio.Media.INTERNAL_CONTENT_URI, INTERNAL_COLUMNS, 486 constructBooleanTrueWhereClause(mFilterColumns), 487 null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER); 488 } 489 490 private Cursor getMediaRingtones() { 491 // Get the external media cursor. First check to see if it is mounted. 492 final String status = Environment.getExternalStorageState(); 493 494 return (status.equals(Environment.MEDIA_MOUNTED) || 495 status.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) 496 ? query( 497 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MEDIA_COLUMNS, 498 constructBooleanTrueWhereClause(mFilterColumns), null, 499 MediaStore.Audio.Media.DEFAULT_SORT_ORDER) 500 : null; 501 } 502 503 private void setFilterColumnsList(int type) { 504 List<String> columns = mFilterColumns; 505 columns.clear(); 506 507 if ((type & TYPE_RINGTONE) != 0) { 508 columns.add(MediaStore.Audio.AudioColumns.IS_RINGTONE); 509 } 510 511 if ((type & TYPE_NOTIFICATION) != 0) { 512 columns.add(MediaStore.Audio.AudioColumns.IS_NOTIFICATION); 513 } 514 515 if ((type & TYPE_ALARM) != 0) { 516 columns.add(MediaStore.Audio.AudioColumns.IS_ALARM); 517 } 518 } 519 520 /** 521 * Constructs a where clause that consists of at least one column being 1 522 * (true). This is used to find all matching sounds for the given sound 523 * types (ringtone, notifications, etc.) 524 * 525 * @param columns The columns that must be true. 526 * @return The where clause. 527 */ 528 private static String constructBooleanTrueWhereClause(List<String> columns) { 529 530 if (columns == null) return null; 531 532 StringBuilder sb = new StringBuilder(); 533 sb.append("("); 534 535 for (int i = columns.size() - 1; i >= 0; i--) { 536 sb.append(columns.get(i)).append("=1 or "); 537 } 538 539 if (columns.size() > 0) { 540 // Remove last ' or ' 541 sb.setLength(sb.length() - 4); 542 } 543 544 sb.append(")"); 545 546 return sb.toString(); 547 } 548 549 private Cursor query(Uri uri, 550 String[] projection, 551 String selection, 552 String[] selectionArgs, 553 String sortOrder) { 554 if (mActivity != null) { 555 return mActivity.managedQuery(uri, projection, selection, selectionArgs, sortOrder); 556 } else { 557 return mContext.getContentResolver().query(uri, projection, selection, selectionArgs, 558 sortOrder); 559 } 560 } 561 562 /** 563 * Returns a {@link Ringtone} for a given sound URI. 564 * <p> 565 * If the given URI cannot be opened for any reason, this method will 566 * attempt to fallback on another sound. If it cannot find any, it will 567 * return null. 568 * 569 * @param context A context used to query. 570 * @param ringtoneUri The {@link Uri} of a sound or ringtone. 571 * @return A {@link Ringtone} for the given URI, or null. 572 */ 573 public static Ringtone getRingtone(final Context context, Uri ringtoneUri) { 574 // Don't set the stream type 575 return getRingtone(context, ringtoneUri, -1); 576 } 577 578 /** 579 * Returns a {@link Ringtone} for a given sound URI on the given stream 580 * type. Normally, if you change the stream type on the returned 581 * {@link Ringtone}, it will re-create the {@link MediaPlayer}. This is just 582 * an optimized route to avoid that. 583 * 584 * @param streamType The stream type for the ringtone, or -1 if it should 585 * not be set (and the default used instead). 586 * @see #getRingtone(Context, Uri) 587 */ 588 private static Ringtone getRingtone(final Context context, Uri ringtoneUri, int streamType) { 589 try { 590 final Ringtone r = new Ringtone(context, true); 591 if (streamType >= 0) { 592 r.setStreamType(streamType); 593 } 594 r.setUri(ringtoneUri); 595 return r; 596 } catch (Exception ex) { 597 Log.e(TAG, "Failed to open ringtone " + ringtoneUri + ": " + ex); 598 } 599 600 return null; 601 } 602 603 /** 604 * Gets the current default sound's {@link Uri}. This will give the actual 605 * sound {@link Uri}, instead of using this, most clients can use 606 * {@link System#DEFAULT_RINGTONE_URI}. 607 * 608 * @param context A context used for querying. 609 * @param type The type whose default sound should be returned. One of 610 * {@link #TYPE_RINGTONE}, {@link #TYPE_NOTIFICATION}, or 611 * {@link #TYPE_ALARM}. 612 * @return A {@link Uri} pointing to the default sound for the sound type. 613 * @see #setActualDefaultRingtoneUri(Context, int, Uri) 614 */ 615 public static Uri getActualDefaultRingtoneUri(Context context, int type) { 616 String setting = getSettingForType(type); 617 if (setting == null) return null; 618 final String uriString = Settings.System.getString(context.getContentResolver(), setting); 619 return uriString != null ? Uri.parse(uriString) : null; 620 } 621 622 /** 623 * Sets the {@link Uri} of the default sound for a given sound type. 624 * 625 * @param context A context used for querying. 626 * @param type The type whose default sound should be set. One of 627 * {@link #TYPE_RINGTONE}, {@link #TYPE_NOTIFICATION}, or 628 * {@link #TYPE_ALARM}. 629 * @param ringtoneUri A {@link Uri} pointing to the default sound to set. 630 * @see #getActualDefaultRingtoneUri(Context, int) 631 */ 632 public static void setActualDefaultRingtoneUri(Context context, int type, Uri ringtoneUri) { 633 String setting = getSettingForType(type); 634 if (setting == null) return; 635 Settings.System.putString(context.getContentResolver(), setting, 636 ringtoneUri != null ? ringtoneUri.toString() : null); 637 } 638 639 private static String getSettingForType(int type) { 640 if ((type & TYPE_RINGTONE) != 0) { 641 return Settings.System.RINGTONE; 642 } else if ((type & TYPE_NOTIFICATION) != 0) { 643 return Settings.System.NOTIFICATION_SOUND; 644 } else if ((type & TYPE_ALARM) != 0) { 645 return Settings.System.ALARM_ALERT; 646 } else { 647 return null; 648 } 649 } 650 651 /** 652 * Returns whether the given {@link Uri} is one of the default ringtones. 653 * 654 * @param ringtoneUri The ringtone {@link Uri} to be checked. 655 * @return Whether the {@link Uri} is a default. 656 */ 657 public static boolean isDefault(Uri ringtoneUri) { 658 return getDefaultType(ringtoneUri) != -1; 659 } 660 661 /** 662 * Returns the type of a default {@link Uri}. 663 * 664 * @param defaultRingtoneUri The default {@link Uri}. For example, 665 * {@link System#DEFAULT_RINGTONE_URI}, 666 * {@link System#DEFAULT_NOTIFICATION_URI}, or 667 * {@link System#DEFAULT_ALARM_ALERT_URI}. 668 * @return The type of the defaultRingtoneUri, or -1. 669 */ 670 public static int getDefaultType(Uri defaultRingtoneUri) { 671 if (defaultRingtoneUri == null) { 672 return -1; 673 } else if (defaultRingtoneUri.equals(Settings.System.DEFAULT_RINGTONE_URI)) { 674 return TYPE_RINGTONE; 675 } else if (defaultRingtoneUri.equals(Settings.System.DEFAULT_NOTIFICATION_URI)) { 676 return TYPE_NOTIFICATION; 677 } else if (defaultRingtoneUri.equals(Settings.System.DEFAULT_ALARM_ALERT_URI)) { 678 return TYPE_ALARM; 679 } else { 680 return -1; 681 } 682 } 683 684 /** 685 * Returns the {@link Uri} for the default ringtone of a particular type. 686 * Rather than returning the actual ringtone's sound {@link Uri}, this will 687 * return the symbolic {@link Uri} which will resolved to the actual sound 688 * when played. 689 * 690 * @param type The ringtone type whose default should be returned. 691 * @return The {@link Uri} of the default ringtone for the given type. 692 */ 693 public static Uri getDefaultUri(int type) { 694 if ((type & TYPE_RINGTONE) != 0) { 695 return Settings.System.DEFAULT_RINGTONE_URI; 696 } else if ((type & TYPE_NOTIFICATION) != 0) { 697 return Settings.System.DEFAULT_NOTIFICATION_URI; 698 } else if ((type & TYPE_ALARM) != 0) { 699 return Settings.System.DEFAULT_ALARM_ALERT_URI; 700 } else { 701 return null; 702 } 703 } 704 705} 706