MediaMetadataCompat.java revision d3c5347b3ec0025ec906e2053eaa9b97287c46a5
1/* 2 * Copyright (C) 2014 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 */ 16package android.support.v4.media; 17 18import android.graphics.Bitmap; 19import android.net.Uri; 20import android.os.Build; 21import android.os.Bundle; 22import android.os.Parcel; 23import android.os.Parcelable; 24import android.support.annotation.StringDef; 25import android.support.v4.util.ArrayMap; 26import android.text.TextUtils; 27import android.util.Log; 28 29import java.lang.annotation.Retention; 30import java.lang.annotation.RetentionPolicy; 31import java.util.Set; 32 33/** 34 * Contains metadata about an item, such as the title, artist, etc. 35 */ 36public final class MediaMetadataCompat implements Parcelable { 37 private static final String TAG = "MediaMetadata"; 38 39 /** 40 * The title of the media. 41 */ 42 public static final String METADATA_KEY_TITLE = "android.media.metadata.TITLE"; 43 44 /** 45 * The artist of the media. 46 */ 47 public static final String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST"; 48 49 /** 50 * The duration of the media in ms. A negative duration indicates that the 51 * duration is unknown (or infinite). 52 */ 53 public static final String METADATA_KEY_DURATION = "android.media.metadata.DURATION"; 54 55 /** 56 * The album title for the media. 57 */ 58 public static final String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM"; 59 60 /** 61 * The author of the media. 62 */ 63 public static final String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR"; 64 65 /** 66 * The writer of the media. 67 */ 68 public static final String METADATA_KEY_WRITER = "android.media.metadata.WRITER"; 69 70 /** 71 * The composer of the media. 72 */ 73 public static final String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER"; 74 75 /** 76 * The compilation status of the media. 77 */ 78 public static final String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION"; 79 80 /** 81 * The date the media was created or published. The format is unspecified 82 * but RFC 3339 is recommended. 83 */ 84 public static final String METADATA_KEY_DATE = "android.media.metadata.DATE"; 85 86 /** 87 * The year the media was created or published as a long. 88 */ 89 public static final String METADATA_KEY_YEAR = "android.media.metadata.YEAR"; 90 91 /** 92 * The genre of the media. 93 */ 94 public static final String METADATA_KEY_GENRE = "android.media.metadata.GENRE"; 95 96 /** 97 * The track number for the media. 98 */ 99 public static final String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER"; 100 101 /** 102 * The number of tracks in the media's original source. 103 */ 104 public static final String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS"; 105 106 /** 107 * The disc number for the media's original source. 108 */ 109 public static final String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER"; 110 111 /** 112 * The artist for the album of the media's original source. 113 */ 114 public static final String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST"; 115 116 /** 117 * The artwork for the media as a {@link Bitmap}. 118 */ 119 public static final String METADATA_KEY_ART = "android.media.metadata.ART"; 120 121 /** 122 * The artwork for the media as a Uri style String. 123 */ 124 public static final String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI"; 125 126 /** 127 * The artwork for the album of the media's original source as a 128 * {@link Bitmap}. 129 */ 130 public static final String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART"; 131 132 /** 133 * The artwork for the album of the media's original source as a Uri style 134 * String. 135 */ 136 public static final String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI"; 137 138 /** 139 * The user's rating for the media. 140 * 141 * @see RatingCompat 142 */ 143 public static final String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING"; 144 145 /** 146 * The overall rating for the media. 147 * 148 * @see RatingCompat 149 */ 150 public static final String METADATA_KEY_RATING = "android.media.metadata.RATING"; 151 152 /** 153 * A title that is suitable for display to the user. This will generally be 154 * the same as {@link #METADATA_KEY_TITLE} but may differ for some formats. 155 * When displaying media described by this metadata this should be preferred 156 * if present. 157 */ 158 public static final String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE"; 159 160 /** 161 * A subtitle that is suitable for display to the user. When displaying a 162 * second line for media described by this metadata this should be preferred 163 * to other fields if present. 164 */ 165 public static final String METADATA_KEY_DISPLAY_SUBTITLE 166 = "android.media.metadata.DISPLAY_SUBTITLE"; 167 168 /** 169 * A description that is suitable for display to the user. When displaying 170 * more information for media described by this metadata this should be 171 * preferred to other fields if present. 172 */ 173 public static final String METADATA_KEY_DISPLAY_DESCRIPTION 174 = "android.media.metadata.DISPLAY_DESCRIPTION"; 175 176 /** 177 * An icon or thumbnail that is suitable for display to the user. When 178 * displaying an icon for media described by this metadata this should be 179 * preferred to other fields if present. This must be a {@link Bitmap}. 180 */ 181 public static final String METADATA_KEY_DISPLAY_ICON 182 = "android.media.metadata.DISPLAY_ICON"; 183 184 /** 185 * An icon or thumbnail that is suitable for display to the user. When 186 * displaying more information for media described by this metadata the 187 * display description should be preferred to other fields when present. 188 * This must be a Uri style String. 189 */ 190 public static final String METADATA_KEY_DISPLAY_ICON_URI 191 = "android.media.metadata.DISPLAY_ICON_URI"; 192 193 /** 194 * A String key for identifying the content. This value is specific to the 195 * service providing the content. If used, this should be a persistent 196 * unique key for the underlying content. 197 */ 198 public static final String METADATA_KEY_MEDIA_ID = "android.media.metadata.MEDIA_ID"; 199 200 /** 201 * @hide 202 */ 203 @StringDef({METADATA_KEY_TITLE, METADATA_KEY_ARTIST, METADATA_KEY_ALBUM, METADATA_KEY_AUTHOR, 204 METADATA_KEY_WRITER, METADATA_KEY_COMPOSER, METADATA_KEY_COMPILATION, 205 METADATA_KEY_DATE, METADATA_KEY_GENRE, METADATA_KEY_ALBUM_ARTIST, METADATA_KEY_ART_URI, 206 METADATA_KEY_ALBUM_ART_URI, METADATA_KEY_DISPLAY_TITLE, METADATA_KEY_DISPLAY_SUBTITLE, 207 METADATA_KEY_DISPLAY_DESCRIPTION, METADATA_KEY_DISPLAY_ICON_URI, 208 METADATA_KEY_MEDIA_ID}) 209 @Retention(RetentionPolicy.SOURCE) 210 public @interface TextKey {} 211 212 /** 213 * @hide 214 */ 215 @StringDef({METADATA_KEY_DURATION, METADATA_KEY_YEAR, METADATA_KEY_TRACK_NUMBER, 216 METADATA_KEY_NUM_TRACKS, METADATA_KEY_DISC_NUMBER}) 217 @Retention(RetentionPolicy.SOURCE) 218 public @interface LongKey {} 219 220 /** 221 * @hide 222 */ 223 @StringDef({METADATA_KEY_ART, METADATA_KEY_ALBUM_ART, METADATA_KEY_DISPLAY_ICON}) 224 @Retention(RetentionPolicy.SOURCE) 225 public @interface BitmapKey {} 226 227 /** 228 * @hide 229 */ 230 @StringDef({METADATA_KEY_USER_RATING, METADATA_KEY_RATING}) 231 @Retention(RetentionPolicy.SOURCE) 232 public @interface RatingKey {} 233 234 private static final int METADATA_TYPE_LONG = 0; 235 private static final int METADATA_TYPE_TEXT = 1; 236 private static final int METADATA_TYPE_BITMAP = 2; 237 private static final int METADATA_TYPE_RATING = 3; 238 private static final ArrayMap<String, Integer> METADATA_KEYS_TYPE; 239 240 static { 241 METADATA_KEYS_TYPE = new ArrayMap<String, Integer>(); 242 METADATA_KEYS_TYPE.put(METADATA_KEY_TITLE, METADATA_TYPE_TEXT); 243 METADATA_KEYS_TYPE.put(METADATA_KEY_ARTIST, METADATA_TYPE_TEXT); 244 METADATA_KEYS_TYPE.put(METADATA_KEY_DURATION, METADATA_TYPE_LONG); 245 METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM, METADATA_TYPE_TEXT); 246 METADATA_KEYS_TYPE.put(METADATA_KEY_AUTHOR, METADATA_TYPE_TEXT); 247 METADATA_KEYS_TYPE.put(METADATA_KEY_WRITER, METADATA_TYPE_TEXT); 248 METADATA_KEYS_TYPE.put(METADATA_KEY_COMPOSER, METADATA_TYPE_TEXT); 249 METADATA_KEYS_TYPE.put(METADATA_KEY_COMPILATION, METADATA_TYPE_TEXT); 250 METADATA_KEYS_TYPE.put(METADATA_KEY_DATE, METADATA_TYPE_TEXT); 251 METADATA_KEYS_TYPE.put(METADATA_KEY_YEAR, METADATA_TYPE_LONG); 252 METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_TEXT); 253 METADATA_KEYS_TYPE.put(METADATA_KEY_TRACK_NUMBER, METADATA_TYPE_LONG); 254 METADATA_KEYS_TYPE.put(METADATA_KEY_NUM_TRACKS, METADATA_TYPE_LONG); 255 METADATA_KEYS_TYPE.put(METADATA_KEY_DISC_NUMBER, METADATA_TYPE_LONG); 256 METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ARTIST, METADATA_TYPE_TEXT); 257 METADATA_KEYS_TYPE.put(METADATA_KEY_ART, METADATA_TYPE_BITMAP); 258 METADATA_KEYS_TYPE.put(METADATA_KEY_ART_URI, METADATA_TYPE_TEXT); 259 METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART, METADATA_TYPE_BITMAP); 260 METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART_URI, METADATA_TYPE_TEXT); 261 METADATA_KEYS_TYPE.put(METADATA_KEY_USER_RATING, METADATA_TYPE_RATING); 262 METADATA_KEYS_TYPE.put(METADATA_KEY_RATING, METADATA_TYPE_RATING); 263 METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_TITLE, METADATA_TYPE_TEXT); 264 METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_SUBTITLE, METADATA_TYPE_TEXT); 265 METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_DESCRIPTION, METADATA_TYPE_TEXT); 266 METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_ICON, METADATA_TYPE_BITMAP); 267 METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_ICON_URI, METADATA_TYPE_TEXT); 268 METADATA_KEYS_TYPE.put(METADATA_KEY_MEDIA_ID, METADATA_TYPE_TEXT); 269 } 270 271 private static final @TextKey String[] PREFERRED_DESCRIPTION_ORDER = { 272 METADATA_KEY_TITLE, 273 METADATA_KEY_ARTIST, 274 METADATA_KEY_ALBUM, 275 METADATA_KEY_ALBUM_ARTIST, 276 METADATA_KEY_WRITER, 277 METADATA_KEY_AUTHOR, 278 METADATA_KEY_COMPOSER 279 }; 280 281 private static final @BitmapKey String[] PREFERRED_BITMAP_ORDER = { 282 METADATA_KEY_DISPLAY_ICON, 283 METADATA_KEY_ART, 284 METADATA_KEY_ALBUM_ART 285 }; 286 287 private static final @TextKey String[] PREFERRED_URI_ORDER = { 288 METADATA_KEY_DISPLAY_ICON_URI, 289 METADATA_KEY_ART_URI, 290 METADATA_KEY_ALBUM_ART_URI 291 }; 292 293 private final Bundle mBundle; 294 private Object mMetadataObj; 295 private MediaDescriptionCompat mDescription; 296 297 private MediaMetadataCompat(Bundle bundle) { 298 mBundle = new Bundle(bundle); 299 } 300 301 private MediaMetadataCompat(Parcel in) { 302 mBundle = in.readBundle(); 303 } 304 305 /** 306 * Returns true if the given key is contained in the metadata 307 * 308 * @param key a String key 309 * @return true if the key exists in this metadata, false otherwise 310 */ 311 public boolean containsKey(String key) { 312 return mBundle.containsKey(key); 313 } 314 315 /** 316 * Returns the value associated with the given key, or null if no mapping of 317 * the desired type exists for the given key or a null value is explicitly 318 * associated with the key. 319 * 320 * @param key The key the value is stored under 321 * @return a CharSequence value, or null 322 */ 323 public CharSequence getText(@TextKey String key) { 324 return mBundle.getCharSequence(key); 325 } 326 327 /** 328 * Returns the value associated with the given key, or null if no mapping of 329 * the desired type exists for the given key or a null value is explicitly 330 * associated with the key. 331 * 332 * @param key The key the value is stored under 333 * @return a String value, or null 334 */ 335 public String getString(@TextKey String key) { 336 CharSequence text = mBundle.getCharSequence(key); 337 if (text != null) { 338 return text.toString(); 339 } 340 return null; 341 } 342 343 /** 344 * Returns the value associated with the given key, or 0L if no long exists 345 * for the given key. 346 * 347 * @param key The key the value is stored under 348 * @return a long value 349 */ 350 public long getLong(@LongKey String key) { 351 return mBundle.getLong(key, 0); 352 } 353 354 /** 355 * Return a {@link RatingCompat} for the given key or null if no rating exists for 356 * the given key. 357 * 358 * @param key The key the value is stored under 359 * @return A {@link RatingCompat} or null 360 */ 361 public RatingCompat getRating(@RatingKey String key) { 362 RatingCompat rating = null; 363 try { 364 if (Build.VERSION.SDK_INT >= 21) { 365 // On platform version 21 or higher, mBundle stores a Rating object. Convert it to 366 // RatingCompat. 367 rating = RatingCompat.fromRating(mBundle.getParcelable(key)); 368 } else { 369 rating = mBundle.getParcelable(key); 370 } 371 } catch (Exception e) { 372 // ignore, value was not a bitmap 373 Log.w(TAG, "Failed to retrieve a key as Rating.", e); 374 } 375 return rating; 376 } 377 378 /** 379 * Return a {@link Bitmap} for the given key or null if no bitmap exists for 380 * the given key. 381 * 382 * @param key The key the value is stored under 383 * @return A {@link Bitmap} or null 384 */ 385 public Bitmap getBitmap(@BitmapKey String key) { 386 Bitmap bmp = null; 387 try { 388 bmp = mBundle.getParcelable(key); 389 } catch (Exception e) { 390 // ignore, value was not a bitmap 391 Log.w(TAG, "Failed to retrieve a key as Bitmap.", e); 392 } 393 return bmp; 394 } 395 396 /** 397 * Returns a simple description of this metadata for display purposes. 398 * 399 * @return A simple description of this metadata. 400 */ 401 public MediaDescriptionCompat getDescription() { 402 if (mDescription != null) { 403 return mDescription; 404 } 405 406 String mediaId = getString(METADATA_KEY_MEDIA_ID); 407 408 CharSequence[] text = new CharSequence[3]; 409 Bitmap icon = null; 410 Uri iconUri = null; 411 412 // First handle the case where display data is set already 413 CharSequence displayText = getText(METADATA_KEY_DISPLAY_TITLE); 414 if (!TextUtils.isEmpty(displayText)) { 415 // If they have a display title use only display data, otherwise use 416 // our best bets 417 text[0] = displayText; 418 text[1] = getText(METADATA_KEY_DISPLAY_SUBTITLE); 419 text[2] = getText(METADATA_KEY_DISPLAY_DESCRIPTION); 420 } else { 421 // Use whatever fields we can 422 int textIndex = 0; 423 int keyIndex = 0; 424 while (textIndex < text.length && keyIndex < PREFERRED_DESCRIPTION_ORDER.length) { 425 CharSequence next = getText(PREFERRED_DESCRIPTION_ORDER[keyIndex++]); 426 if (!TextUtils.isEmpty(next)) { 427 // Fill in the next empty bit of text 428 text[textIndex++] = next; 429 } 430 } 431 } 432 433 // Get the best art bitmap we can find 434 for (int i = 0; i < PREFERRED_BITMAP_ORDER.length; i++) { 435 Bitmap next = getBitmap(PREFERRED_BITMAP_ORDER[i]); 436 if (next != null) { 437 icon = next; 438 break; 439 } 440 } 441 442 // Get the best Uri we can find 443 for (int i = 0; i < PREFERRED_URI_ORDER.length; i++) { 444 String next = getString(PREFERRED_URI_ORDER[i]); 445 if (!TextUtils.isEmpty(next)) { 446 iconUri = Uri.parse(next); 447 break; 448 } 449 } 450 451 MediaDescriptionCompat.Builder bob = new MediaDescriptionCompat.Builder(); 452 bob.setMediaId(mediaId); 453 bob.setTitle(text[0]); 454 bob.setSubtitle(text[1]); 455 bob.setDescription(text[2]); 456 bob.setIconBitmap(icon); 457 bob.setIconUri(iconUri); 458 mDescription = bob.build(); 459 460 return mDescription; 461 } 462 463 @Override 464 public int describeContents() { 465 return 0; 466 } 467 468 @Override 469 public void writeToParcel(Parcel dest, int flags) { 470 dest.writeBundle(mBundle); 471 } 472 473 /** 474 * Get the number of fields in this metadata. 475 * 476 * @return The number of fields in the metadata. 477 */ 478 public int size() { 479 return mBundle.size(); 480 } 481 482 /** 483 * Returns a Set containing the Strings used as keys in this metadata. 484 * 485 * @return a Set of String keys 486 */ 487 public Set<String> keySet() { 488 return mBundle.keySet(); 489 } 490 491 /** 492 * Gets the bundle backing the metadata object. This is available to support 493 * backwards compatibility. Apps should not modify the bundle directly. 494 * 495 * @return The Bundle backing this metadata. 496 */ 497 public Bundle getBundle() { 498 return mBundle; 499 } 500 501 /** 502 * Creates an instance from a framework {@link android.media.MediaMetadata} 503 * object. 504 * <p> 505 * This method is only supported on 506 * {@link android.os.Build.VERSION_CODES#LOLLIPOP} and later. 507 * </p> 508 * 509 * @param metadataObj A {@link android.media.MediaMetadata} object, or null 510 * if none. 511 * @return An equivalent {@link MediaMetadataCompat} object, or null if 512 * none. 513 */ 514 public static MediaMetadataCompat fromMediaMetadata(Object metadataObj) { 515 if (metadataObj == null || Build.VERSION.SDK_INT < 21) { 516 return null; 517 } 518 519 Parcel p = Parcel.obtain(); 520 MediaMetadataCompatApi21.writeToParcel(metadataObj, p, 0); 521 p.setDataPosition(0); 522 MediaMetadataCompat metadata = MediaMetadataCompat.CREATOR.createFromParcel(p); 523 p.recycle(); 524 metadata.mMetadataObj = metadataObj; 525 return metadata; 526 } 527 528 /** 529 * Gets the underlying framework {@link android.media.MediaMetadata} object. 530 * <p> 531 * This method is only supported on 532 * {@link android.os.Build.VERSION_CODES#LOLLIPOP} and later. 533 * </p> 534 * 535 * @return An equivalent {@link android.media.MediaMetadata} object, or null 536 * if none. 537 */ 538 public Object getMediaMetadata() { 539 if (mMetadataObj != null || Build.VERSION.SDK_INT < 21) { 540 return mMetadataObj; 541 } 542 543 Parcel p = Parcel.obtain(); 544 writeToParcel(p, 0); 545 p.setDataPosition(0); 546 mMetadataObj = MediaMetadataCompatApi21.createFromParcel(p); 547 p.recycle(); 548 return mMetadataObj; 549 } 550 551 public static final Parcelable.Creator<MediaMetadataCompat> CREATOR = 552 new Parcelable.Creator<MediaMetadataCompat>() { 553 @Override 554 public MediaMetadataCompat createFromParcel(Parcel in) { 555 return new MediaMetadataCompat(in); 556 } 557 558 @Override 559 public MediaMetadataCompat[] newArray(int size) { 560 return new MediaMetadataCompat[size]; 561 } 562 }; 563 564 /** 565 * Use to build MediaMetadata objects. The system defined metadata keys must 566 * use the appropriate data type. 567 */ 568 public static final class Builder { 569 private final Bundle mBundle; 570 571 /** 572 * Create an empty Builder. Any field that should be included in the 573 * {@link MediaMetadataCompat} must be added. 574 */ 575 public Builder() { 576 mBundle = new Bundle(); 577 } 578 579 /** 580 * Create a Builder using a {@link MediaMetadataCompat} instance to set the 581 * initial values. All fields in the source metadata will be included in 582 * the new metadata. Fields can be overwritten by adding the same key. 583 * 584 * @param source 585 */ 586 public Builder(MediaMetadataCompat source) { 587 mBundle = new Bundle(source.mBundle); 588 } 589 590 /** 591 * Put a CharSequence value into the metadata. Custom keys may be used, 592 * but if the METADATA_KEYs defined in this class are used they may only 593 * be one of the following: 594 * <ul> 595 * <li>{@link #METADATA_KEY_TITLE}</li> 596 * <li>{@link #METADATA_KEY_ARTIST}</li> 597 * <li>{@link #METADATA_KEY_ALBUM}</li> 598 * <li>{@link #METADATA_KEY_AUTHOR}</li> 599 * <li>{@link #METADATA_KEY_WRITER}</li> 600 * <li>{@link #METADATA_KEY_COMPOSER}</li> 601 * <li>{@link #METADATA_KEY_DATE}</li> 602 * <li>{@link #METADATA_KEY_GENRE}</li> 603 * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li> 604 * <li>{@link #METADATA_KEY_ART_URI}</li> 605 * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li> 606 * <li>{@link #METADATA_KEY_DISPLAY_TITLE}</li> 607 * <li>{@link #METADATA_KEY_DISPLAY_SUBTITLE}</li> 608 * <li>{@link #METADATA_KEY_DISPLAY_DESCRIPTION}</li> 609 * <li>{@link #METADATA_KEY_DISPLAY_ICON_URI}</li> 610 * </ul> 611 * 612 * @param key The key for referencing this value 613 * @param value The CharSequence value to store 614 * @return The Builder to allow chaining 615 */ 616 public Builder putText(@TextKey String key, CharSequence value) { 617 if (METADATA_KEYS_TYPE.containsKey(key)) { 618 if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) { 619 throw new IllegalArgumentException("The " + key 620 + " key cannot be used to put a CharSequence"); 621 } 622 } 623 mBundle.putCharSequence(key, value); 624 return this; 625 } 626 627 /** 628 * Put a String value into the metadata. Custom keys may be used, but if 629 * the METADATA_KEYs defined in this class are used they may only be one 630 * of the following: 631 * <ul> 632 * <li>{@link #METADATA_KEY_TITLE}</li> 633 * <li>{@link #METADATA_KEY_ARTIST}</li> 634 * <li>{@link #METADATA_KEY_ALBUM}</li> 635 * <li>{@link #METADATA_KEY_AUTHOR}</li> 636 * <li>{@link #METADATA_KEY_WRITER}</li> 637 * <li>{@link #METADATA_KEY_COMPOSER}</li> 638 * <li>{@link #METADATA_KEY_DATE}</li> 639 * <li>{@link #METADATA_KEY_GENRE}</li> 640 * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li> 641 * <li>{@link #METADATA_KEY_ART_URI}</li> 642 * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li> 643 * <li>{@link #METADATA_KEY_DISPLAY_TITLE}</li> 644 * <li>{@link #METADATA_KEY_DISPLAY_SUBTITLE}</li> 645 * <li>{@link #METADATA_KEY_DISPLAY_DESCRIPTION}</li> 646 * <li>{@link #METADATA_KEY_DISPLAY_ICON_URI}</li> 647 * </ul> 648 * 649 * @param key The key for referencing this value 650 * @param value The String value to store 651 * @return The Builder to allow chaining 652 */ 653 public Builder putString(@TextKey String key, String value) { 654 if (METADATA_KEYS_TYPE.containsKey(key)) { 655 if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) { 656 throw new IllegalArgumentException("The " + key 657 + " key cannot be used to put a String"); 658 } 659 } 660 mBundle.putCharSequence(key, value); 661 return this; 662 } 663 664 /** 665 * Put a long value into the metadata. Custom keys may be used, but if 666 * the METADATA_KEYs defined in this class are used they may only be one 667 * of the following: 668 * <ul> 669 * <li>{@link #METADATA_KEY_DURATION}</li> 670 * <li>{@link #METADATA_KEY_TRACK_NUMBER}</li> 671 * <li>{@link #METADATA_KEY_NUM_TRACKS}</li> 672 * <li>{@link #METADATA_KEY_DISC_NUMBER}</li> 673 * <li>{@link #METADATA_KEY_YEAR}</li> 674 * </ul> 675 * 676 * @param key The key for referencing this value 677 * @param value The String value to store 678 * @return The Builder to allow chaining 679 */ 680 public Builder putLong(@LongKey String key, long value) { 681 if (METADATA_KEYS_TYPE.containsKey(key)) { 682 if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_LONG) { 683 throw new IllegalArgumentException("The " + key 684 + " key cannot be used to put a long"); 685 } 686 } 687 mBundle.putLong(key, value); 688 return this; 689 } 690 691 /** 692 * Put a {@link RatingCompat} into the metadata. Custom keys may be used, but 693 * if the METADATA_KEYs defined in this class are used they may only be 694 * one of the following: 695 * <ul> 696 * <li>{@link #METADATA_KEY_RATING}</li> 697 * <li>{@link #METADATA_KEY_USER_RATING}</li> 698 * </ul> 699 * 700 * @param key The key for referencing this value 701 * @param value The String value to store 702 * @return The Builder to allow chaining 703 */ 704 public Builder putRating(@RatingKey String key, RatingCompat value) { 705 if (METADATA_KEYS_TYPE.containsKey(key)) { 706 if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_RATING) { 707 throw new IllegalArgumentException("The " + key 708 + " key cannot be used to put a Rating"); 709 } 710 } 711 if (Build.VERSION.SDK_INT >= 21) { 712 // On platform version 21 or higher, use Rating instead of RatingCompat so mBundle 713 // can be unmarshalled. 714 mBundle.putParcelable(key, (Parcelable) value.getRating()); 715 } else { 716 mBundle.putParcelable(key, value); 717 } 718 return this; 719 } 720 721 /** 722 * Put a {@link Bitmap} into the metadata. Custom keys may be used, but 723 * if the METADATA_KEYs defined in this class are used they may only be 724 * one of the following: 725 * <ul> 726 * <li>{@link #METADATA_KEY_ART}</li> 727 * <li>{@link #METADATA_KEY_ALBUM_ART}</li> 728 * <li>{@link #METADATA_KEY_DISPLAY_ICON}</li> 729 * </ul> 730 * 731 * @param key The key for referencing this value 732 * @param value The Bitmap to store 733 * @return The Builder to allow chaining 734 */ 735 public Builder putBitmap(@BitmapKey String key, Bitmap value) { 736 if (METADATA_KEYS_TYPE.containsKey(key)) { 737 if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_BITMAP) { 738 throw new IllegalArgumentException("The " + key 739 + " key cannot be used to put a Bitmap"); 740 } 741 } 742 mBundle.putParcelable(key, value); 743 return this; 744 } 745 746 /** 747 * Creates a {@link MediaMetadataCompat} instance with the specified fields. 748 * 749 * @return The new MediaMetadata instance 750 */ 751 public MediaMetadataCompat build() { 752 return new MediaMetadataCompat(mBundle); 753 } 754 } 755 756} 757