MediaStore.java revision f013e1afd1e68af5e3b868c26a653bbfb39538f8
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.provider; 18 19import android.annotation.SdkConstant; 20import android.annotation.SdkConstant.SdkConstantType; 21import android.content.ContentResolver; 22import android.content.ContentValues; 23import android.content.ContentUris; 24import android.database.Cursor; 25import android.database.DatabaseUtils; 26import android.graphics.Bitmap; 27import android.graphics.BitmapFactory; 28import android.graphics.Matrix; 29import android.net.Uri; 30import android.os.Environment; 31import android.util.Log; 32 33import java.io.FileInputStream; 34import java.io.FileNotFoundException; 35import java.io.IOException; 36import java.io.InputStream; 37import java.io.OutputStream; 38import java.io.UnsupportedEncodingException; 39import java.text.Collator; 40 41/** 42 * The Media provider contains meta data for all available media on both internal 43 * and external storage devices. 44 */ 45public final class MediaStore 46{ 47 private final static String TAG = "MediaStore"; 48 49 public static final String AUTHORITY = "media"; 50 51 private static final String CONTENT_AUTHORITY_SLASH = "content://" + AUTHORITY + "/"; 52 53 /** 54 * Activity Action: Perform a search for media. 55 * Contains at least the {@link android.app.SearchManager#QUERY} extra. 56 * May also contain any combination of the following extras: 57 * EXTRA_MEDIA_ARTIST, EXTRA_MEDIA_ALBUM, EXTRA_MEDIA_TITLE, EXTRA_MEDIA_FOCUS 58 * 59 * @see android.provider.MediaStore#EXTRA_MEDIA_ARTIST 60 * @see android.provider.MediaStore#EXTRA_MEDIA_ALBUM 61 * @see android.provider.MediaStore#EXTRA_MEDIA_TITLE 62 * @see android.provider.MediaStore#EXTRA_MEDIA_FOCUS 63 */ 64 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 65 public static final String INTENT_ACTION_MEDIA_SEARCH = "android.intent.action.MEDIA_SEARCH"; 66 67 /** 68 * The name of the Intent-extra used to define the artist 69 */ 70 public static final String EXTRA_MEDIA_ARTIST = "android.intent.extra.artist"; 71 /** 72 * The name of the Intent-extra used to define the album 73 */ 74 public static final String EXTRA_MEDIA_ALBUM = "android.intent.extra.album"; 75 /** 76 * The name of the Intent-extra used to define the song title 77 */ 78 public static final String EXTRA_MEDIA_TITLE = "android.intent.extra.title"; 79 /** 80 * The name of the Intent-extra used to define the search focus. The search focus 81 * indicates whether the search should be for things related to the artist, album 82 * or song that is identified by the other extras. 83 */ 84 public static final String EXTRA_MEDIA_FOCUS = "android.intent.extra.focus"; 85 86 /** 87 * The name of the Intent-extra used to control the orientation of a MovieView. 88 * This is an int property that overrides the MovieView activity's requestedOrientation. 89 * @see android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED 90 */ 91 public static final String EXTRA_SCREEN_ORIENTATION = "android.intent.extra.screenOrientation"; 92 93 /** 94 * The name of the Intent-extra used to control the onCompletion behavior of a MovieView. 95 * This is a boolean property that specifies whether or not to finish the MovieView activity 96 * when the movie completes playing. The default value is true, which means to automatically 97 * exit the movie player activity when the movie completes playing. 98 */ 99 public static final String EXTRA_FINISH_ON_COMPLETION = "android.intent.extra.finishOnCompletion"; 100 101 /** 102 * The name of the Intent action used to launch a camera in still image mode. 103 */ 104 public static final String INTENT_ACTION_STILL_IMAGE_CAMERA = "android.media.action.STILL_IMAGE_CAMERA"; 105 106 107 /** 108 * The name of the Intent action used to launch a camera in video mode. 109 */ 110 public static final String INTENT_ACTION_VIDEO_CAMERA = "android.media.action.VIDEO_CAMERA"; 111 112 /** 113 * Standard Intent action that can be sent to have the media application 114 * capture an image and return it. The image is returned as a Bitmap 115 * object in the extra field. 116 * @hide 117 */ 118 public final static String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE"; 119 120 /** 121 * Common fields for most MediaProvider tables 122 */ 123 124 public interface MediaColumns extends BaseColumns { 125 /** 126 * The data stream for the file 127 * <P>Type: DATA STREAM</P> 128 */ 129 public static final String DATA = "_data"; 130 131 /** 132 * The size of the file in bytes 133 * <P>Type: INTEGER (long)</P> 134 */ 135 public static final String SIZE = "_size"; 136 137 /** 138 * The display name of the file 139 * <P>Type: TEXT</P> 140 */ 141 public static final String DISPLAY_NAME = "_display_name"; 142 143 /** 144 * The title of the content 145 * <P>Type: TEXT</P> 146 */ 147 public static final String TITLE = "title"; 148 149 /** 150 * The time the file was added to the media provider 151 * Units are seconds since 1970. 152 * <P>Type: INTEGER (long)</P> 153 */ 154 public static final String DATE_ADDED = "date_added"; 155 156 /** 157 * The time the file was last modified 158 * Units are seconds since 1970. 159 * NOTE: This is for internal use by the media scanner. Do not modify this field. 160 * <P>Type: INTEGER (long)</P> 161 */ 162 public static final String DATE_MODIFIED = "date_modified"; 163 164 /** 165 * The MIME type of the file 166 * <P>Type: TEXT</P> 167 */ 168 public static final String MIME_TYPE = "mime_type"; 169 } 170 171 /** 172 * Contains meta data for all available images. 173 */ 174 public static final class Images 175 { 176 public interface ImageColumns extends MediaColumns { 177 /** 178 * The description of the image 179 * <P>Type: TEXT</P> 180 */ 181 public static final String DESCRIPTION = "description"; 182 183 /** 184 * The picasa id of the image 185 * <P>Type: TEXT</P> 186 */ 187 public static final String PICASA_ID = "picasa_id"; 188 189 /** 190 * Whether the video should be published as public or private 191 * <P>Type: INTEGER</P> 192 */ 193 public static final String IS_PRIVATE = "isprivate"; 194 195 /** 196 * The latitude where the image was captured. 197 * <P>Type: DOUBLE</P> 198 */ 199 public static final String LATITUDE = "latitude"; 200 201 /** 202 * The longitude where the image was captured. 203 * <P>Type: DOUBLE</P> 204 */ 205 public static final String LONGITUDE = "longitude"; 206 207 /** 208 * The date & time that the image was taken in units 209 * of milliseconds since jan 1, 1970. 210 * <P>Type: INTEGER</P> 211 */ 212 public static final String DATE_TAKEN = "datetaken"; 213 214 /** 215 * The orientation for the image expressed as degrees. 216 * Only degrees 0, 90, 180, 270 will work. 217 * <P>Type: INTEGER</P> 218 */ 219 public static final String ORIENTATION = "orientation"; 220 221 /** 222 * The mini thumb id. 223 * <P>Type: INTEGER</P> 224 */ 225 public static final String MINI_THUMB_MAGIC = "mini_thumb_magic"; 226 227 /** 228 * The bucket id of the image. This is a read-only property that 229 * is automatically computed from the DATA column. 230 * <P>Type: TEXT</P> 231 */ 232 public static final String BUCKET_ID = "bucket_id"; 233 234 /** 235 * The bucket display name of the image. This is a read-only property that 236 * is automatically computed from the DATA column. 237 * <P>Type: TEXT</P> 238 */ 239 public static final String BUCKET_DISPLAY_NAME = "bucket_display_name"; 240 } 241 242 public static final class Media implements ImageColumns { 243 public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) 244 { 245 return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER); 246 } 247 248 public static final Cursor query(ContentResolver cr, Uri uri, String[] projection, 249 String where, String orderBy) 250 { 251 return cr.query(uri, projection, where, 252 null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy); 253 } 254 255 public static final Cursor query(ContentResolver cr, Uri uri, String[] projection, 256 String selection, String [] selectionArgs, String orderBy) 257 { 258 return cr.query(uri, projection, selection, 259 selectionArgs, orderBy == null ? DEFAULT_SORT_ORDER : orderBy); 260 } 261 262 /** 263 * Retrieves an image for the given url as a {@link Bitmap}. 264 * 265 * @param cr The content resolver to use 266 * @param url The url of the image 267 * @throws FileNotFoundException 268 * @throws IOException 269 */ 270 public static final Bitmap getBitmap(ContentResolver cr, Uri url) 271 throws FileNotFoundException, IOException 272 { 273 InputStream input = cr.openInputStream(url); 274 Bitmap bitmap = BitmapFactory.decodeStream(input); 275 input.close(); 276 return bitmap; 277 } 278 279 /** 280 * Insert an image and create a thumbnail for it. 281 * 282 * @param cr The content resolver to use 283 * @param imagePath The path to the image to insert 284 * @param name The name of the image 285 * @param description The description of the image 286 * @return The URL to the newly created image 287 * @throws FileNotFoundException 288 */ 289 public static final String insertImage(ContentResolver cr, String imagePath, String name, 290 String description) throws FileNotFoundException 291 { 292 // Check if file exists with a FileInputStream 293 FileInputStream stream = new FileInputStream(imagePath); 294 try { 295 return insertImage(cr, BitmapFactory.decodeFile(imagePath), name, description); 296 } finally { 297 try { 298 stream.close(); 299 } catch (IOException e) { 300 } 301 } 302 } 303 304 private static final Bitmap StoreThumbnail( 305 ContentResolver cr, 306 Bitmap source, 307 long id, 308 float width, float height, 309 int kind) { 310 // create the matrix to scale it 311 Matrix matrix = new Matrix(); 312 313 float scaleX = width / source.getWidth(); 314 float scaleY = height / source.getHeight(); 315 316 matrix.setScale(scaleX, scaleY); 317 318 Bitmap thumb = Bitmap.createBitmap(source, 0, 0, 319 source.getWidth(), 320 source.getHeight(), matrix, 321 true); 322 323 ContentValues values = new ContentValues(4); 324 values.put(Images.Thumbnails.KIND, kind); 325 values.put(Images.Thumbnails.IMAGE_ID, (int)id); 326 values.put(Images.Thumbnails.HEIGHT, thumb.getHeight()); 327 values.put(Images.Thumbnails.WIDTH, thumb.getWidth()); 328 329 Uri url = cr.insert(Images.Thumbnails.EXTERNAL_CONTENT_URI, values); 330 331 try { 332 OutputStream thumbOut = cr.openOutputStream(url); 333 334 thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut); 335 thumbOut.close(); 336 return thumb; 337 } 338 catch (FileNotFoundException ex) { 339 return null; 340 } 341 catch (IOException ex) { 342 return null; 343 } 344 } 345 346 /** 347 * Insert an image and create a thumbnail for it. 348 * 349 * @param cr The content resolver to use 350 * @param source The stream to use for the image 351 * @param title The name of the image 352 * @param description The description of the image 353 * @return The URL to the newly created image, or <code>null</code> if the image failed to be stored 354 * for any reason. 355 */ 356 public static final String insertImage(ContentResolver cr, Bitmap source, 357 String title, String description) 358 { 359 ContentValues values = new ContentValues(); 360 values.put(Images.Media.TITLE, title); 361 values.put(Images.Media.DESCRIPTION, description); 362 values.put(Images.Media.MIME_TYPE, "image/jpeg"); 363 364 Uri url = null; 365 String stringUrl = null; /* value to be returned */ 366 367 try 368 { 369 url = cr.insert(EXTERNAL_CONTENT_URI, values); 370 371 if (source != null) { 372 OutputStream imageOut = cr.openOutputStream(url); 373 try { 374 source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut); 375 } finally { 376 imageOut.close(); 377 } 378 379 long id = ContentUris.parseId(url); 380 Bitmap miniThumb = StoreThumbnail(cr, source, id, 320F, 240F, Images.Thumbnails.MINI_KIND); 381 Bitmap microThumb = StoreThumbnail(cr, miniThumb, id, 50F, 50F, Images.Thumbnails.MICRO_KIND); 382 } else { 383 Log.e(TAG, "Failed to create thumbnail, removing original"); 384 cr.delete(url, null, null); 385 url = null; 386 } 387 } catch (Exception e) { 388 Log.e(TAG, "Failed to insert image", e); 389 if (url != null) { 390 cr.delete(url, null, null); 391 url = null; 392 } 393 } 394 395 if (url != null) { 396 stringUrl = url.toString(); 397 } 398 399 return stringUrl; 400 } 401 402 /** 403 * Get the content:// style URI for the image media table on the 404 * given volume. 405 * 406 * @param volumeName the name of the volume to get the URI for 407 * @return the URI to the image media table on the given volume 408 */ 409 public static Uri getContentUri(String volumeName) { 410 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + 411 "/images/media"); 412 } 413 414 /** 415 * The content:// style URI for the internal storage. 416 */ 417 public static final Uri INTERNAL_CONTENT_URI = 418 getContentUri("internal"); 419 420 /** 421 * The content:// style URI for the "primary" external storage 422 * volume. 423 */ 424 public static final Uri EXTERNAL_CONTENT_URI = 425 getContentUri("external"); 426 427 /** 428 * The MIME type of of this directory of 429 * images. Note that each entry in this directory will have a standard 430 * image MIME type as appropriate -- for example, image/jpeg. 431 */ 432 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/image"; 433 434 /** 435 * The default sort order for this table 436 */ 437 public static final String DEFAULT_SORT_ORDER = "name ASC"; 438 } 439 440 public static class Thumbnails implements BaseColumns 441 { 442 public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) 443 { 444 return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER); 445 } 446 447 public static final Cursor queryMiniThumbnails(ContentResolver cr, Uri uri, int kind, String[] projection) 448 { 449 return cr.query(uri, projection, "kind = " + kind, null, DEFAULT_SORT_ORDER); 450 } 451 452 public static final Cursor queryMiniThumbnail(ContentResolver cr, long origId, int kind, String[] projection) 453 { 454 return cr.query(EXTERNAL_CONTENT_URI, projection, 455 IMAGE_ID + " = " + origId + " AND " + KIND + " = " + 456 kind, null, null); 457 } 458 459 /** 460 * Get the content:// style URI for the image media table on the 461 * given volume. 462 * 463 * @param volumeName the name of the volume to get the URI for 464 * @return the URI to the image media table on the given volume 465 */ 466 public static Uri getContentUri(String volumeName) { 467 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + 468 "/images/thumbnails"); 469 } 470 471 /** 472 * The content:// style URI for the internal storage. 473 */ 474 public static final Uri INTERNAL_CONTENT_URI = 475 getContentUri("internal"); 476 477 /** 478 * The content:// style URI for the "primary" external storage 479 * volume. 480 */ 481 public static final Uri EXTERNAL_CONTENT_URI = 482 getContentUri("external"); 483 484 /** 485 * The default sort order for this table 486 */ 487 public static final String DEFAULT_SORT_ORDER = "image_id ASC"; 488 489 /** 490 * The data stream for the thumbnail 491 * <P>Type: DATA STREAM</P> 492 */ 493 public static final String DATA = "_data"; 494 495 /** 496 * The original image for the thumbnal 497 * <P>Type: INTEGER (ID from Images table)</P> 498 */ 499 public static final String IMAGE_ID = "image_id"; 500 501 /** 502 * The kind of the thumbnail 503 * <P>Type: INTEGER (One of the values below)</P> 504 */ 505 public static final String KIND = "kind"; 506 507 public static final int MINI_KIND = 1; 508 public static final int FULL_SCREEN_KIND = 2; 509 public static final int MICRO_KIND = 3; 510 511 /** 512 * The width of the thumbnal 513 * <P>Type: INTEGER (long)</P> 514 */ 515 public static final String WIDTH = "width"; 516 517 /** 518 * The height of the thumbnail 519 * <P>Type: INTEGER (long)</P> 520 */ 521 public static final String HEIGHT = "height"; 522 } 523 } 524 525 /** 526 * Container for all audio content. 527 */ 528 public static final class Audio { 529 /** 530 * Columns for audio file that show up in multiple tables. 531 */ 532 public interface AudioColumns extends MediaColumns { 533 534 /** 535 * A non human readable key calculated from the TITLE, used for 536 * searching, sorting and grouping 537 * <P>Type: TEXT</P> 538 */ 539 public static final String TITLE_KEY = "title_key"; 540 541 /** 542 * The duration of the audio file, in ms 543 * <P>Type: INTEGER (long)</P> 544 */ 545 public static final String DURATION = "duration"; 546 547 /** 548 * The id of the artist who created the audio file, if any 549 * <P>Type: INTEGER (long)</P> 550 */ 551 public static final String ARTIST_ID = "artist_id"; 552 553 /** 554 * The artist who created the audio file, if any 555 * <P>Type: TEXT</P> 556 */ 557 public static final String ARTIST = "artist"; 558 559 /** 560 * A non human readable key calculated from the ARTIST, used for 561 * searching, sorting and grouping 562 * <P>Type: TEXT</P> 563 */ 564 public static final String ARTIST_KEY = "artist_key"; 565 566 /** 567 * The composer of the audio file, if any 568 * <P>Type: TEXT</P> 569 */ 570 public static final String COMPOSER = "composer"; 571 572 /** 573 * The id of the album the audio file is from, if any 574 * <P>Type: INTEGER (long)</P> 575 */ 576 public static final String ALBUM_ID = "album_id"; 577 578 /** 579 * The album the audio file is from, if any 580 * <P>Type: TEXT</P> 581 */ 582 public static final String ALBUM = "album"; 583 584 /** 585 * A non human readable key calculated from the ALBUM, used for 586 * searching, sorting and grouping 587 * <P>Type: TEXT</P> 588 */ 589 public static final String ALBUM_KEY = "album_key"; 590 591 /** 592 * A URI to the album art, if any 593 * <P>Type: TEXT</P> 594 */ 595 public static final String ALBUM_ART = "album_art"; 596 597 /** 598 * The track number of this song on the album, if any. 599 * This number encodes both the track number and the 600 * disc number. For multi-disc sets, this number will 601 * be 1xxx for tracks on the first disc, 2xxx for tracks 602 * on the second disc, etc. 603 * <P>Type: INTEGER</P> 604 */ 605 public static final String TRACK = "track"; 606 607 /** 608 * The year the audio file was recorded, if any 609 * <P>Type: INTEGER</P> 610 */ 611 public static final String YEAR = "year"; 612 613 /** 614 * Non-zero if the audio file is music 615 * <P>Type: INTEGER (boolean)</P> 616 */ 617 public static final String IS_MUSIC = "is_music"; 618 619 /** 620 * Non-zero id the audio file may be a ringtone 621 * <P>Type: INTEGER (boolean)</P> 622 */ 623 public static final String IS_RINGTONE = "is_ringtone"; 624 625 /** 626 * Non-zero id the audio file may be an alarm 627 * <P>Type: INTEGER (boolean)</P> 628 */ 629 public static final String IS_ALARM = "is_alarm"; 630 631 /** 632 * Non-zero id the audio file may be a notification sound 633 * <P>Type: INTEGER (boolean)</P> 634 */ 635 public static final String IS_NOTIFICATION = "is_notification"; 636 } 637 638 /** 639 * Converts a name to a "key" that can be used for grouping, sorting 640 * and searching. 641 * The rules that govern this conversion are: 642 * - remove 'special' characters like ()[]'!?., 643 * - remove leading/trailing spaces 644 * - convert everything to lowercase 645 * - remove leading "the ", "an " and "a " 646 * - remove trailing ", the|an|a" 647 * - remove accents. This step leaves us with CollationKey data, 648 * which is not human readable 649 * 650 * @param name The artist or album name to convert 651 * @return The "key" for the given name. 652 */ 653 public static String keyFor(String name) { 654 if (name != null) { 655 if (name.equals(android.media.MediaFile.UNKNOWN_STRING)) { 656 return "\001"; 657 } 658 name = name.trim().toLowerCase(); 659 if (name.startsWith("the ")) { 660 name = name.substring(4); 661 } 662 if (name.startsWith("an ")) { 663 name = name.substring(3); 664 } 665 if (name.startsWith("a ")) { 666 name = name.substring(2); 667 } 668 if (name.endsWith(", the") || name.endsWith(",the") || 669 name.endsWith(", an") || name.endsWith(",an") || 670 name.endsWith(", a") || name.endsWith(",a")) { 671 name = name.substring(0, name.lastIndexOf(',')); 672 } 673 name = name.replaceAll("[\\[\\]\\(\\)'.,?!]", "").trim(); 674 if (name.length() > 0) { 675 // Insert a separator between the characters to avoid 676 // matches on a partial character. If we ever change 677 // to start-of-word-only matches, this can be removed. 678 StringBuilder b = new StringBuilder(); 679 b.append('.'); 680 int nl = name.length(); 681 for (int i = 0; i < nl; i++) { 682 b.append(name.charAt(i)); 683 b.append('.'); 684 } 685 name = b.toString(); 686 return DatabaseUtils.getCollationKey(name); 687 } else { 688 return ""; 689 } 690 } 691 return null; 692 } 693 694 public static final class Media implements AudioColumns { 695 /** 696 * Get the content:// style URI for the audio media table on the 697 * given volume. 698 * 699 * @param volumeName the name of the volume to get the URI for 700 * @return the URI to the audio media table on the given volume 701 */ 702 public static Uri getContentUri(String volumeName) { 703 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + 704 "/audio/media"); 705 } 706 707 public static Uri getContentUriForPath(String path) { 708 return (path.startsWith(Environment.getExternalStorageDirectory().getPath()) ? 709 EXTERNAL_CONTENT_URI : INTERNAL_CONTENT_URI); 710 } 711 712 /** 713 * The content:// style URI for the internal storage. 714 */ 715 public static final Uri INTERNAL_CONTENT_URI = 716 getContentUri("internal"); 717 718 /** 719 * The content:// style URI for the "primary" external storage 720 * volume. 721 */ 722 public static final Uri EXTERNAL_CONTENT_URI = 723 getContentUri("external"); 724 725 /** 726 * The MIME type for this table. 727 */ 728 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/audio"; 729 730 /** 731 * The default sort order for this table 732 */ 733 public static final String DEFAULT_SORT_ORDER = TITLE; 734 735 /** 736 * Activity Action: Start SoundRecorder application. 737 * <p>Input: nothing. 738 * <p>Output: An uri to the recorded sound stored in the Media Library 739 * if the recording was successful. 740 * May also contain the extra EXTRA_MAX_BYTES. 741 * @see #EXTRA_MAX_BYTES 742 */ 743 public static final String RECORD_SOUND_ACTION = 744 "android.provider.MediaStore.RECORD_SOUND"; 745 746 /** 747 * The name of the Intent-extra used to define a maximum file size for 748 * a recording made by the SoundRecorder application. 749 * 750 * @see #RECORD_SOUND_ACTION 751 */ 752 public static final String EXTRA_MAX_BYTES = 753 "android.provider.MediaStore.extra.MAX_BYTES"; 754 } 755 756 /** 757 * Columns representing an audio genre 758 */ 759 public interface GenresColumns { 760 /** 761 * The name of the genre 762 * <P>Type: TEXT</P> 763 */ 764 public static final String NAME = "name"; 765 } 766 767 /** 768 * Contains all genres for audio files 769 */ 770 public static final class Genres implements BaseColumns, GenresColumns { 771 /** 772 * Get the content:// style URI for the audio genres table on the 773 * given volume. 774 * 775 * @param volumeName the name of the volume to get the URI for 776 * @return the URI to the audio genres table on the given volume 777 */ 778 public static Uri getContentUri(String volumeName) { 779 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + 780 "/audio/genres"); 781 } 782 783 /** 784 * The content:// style URI for the internal storage. 785 */ 786 public static final Uri INTERNAL_CONTENT_URI = 787 getContentUri("internal"); 788 789 /** 790 * The content:// style URI for the "primary" external storage 791 * volume. 792 */ 793 public static final Uri EXTERNAL_CONTENT_URI = 794 getContentUri("external"); 795 796 /** 797 * The MIME type for this table. 798 */ 799 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/genre"; 800 801 /** 802 * The MIME type for entries in this table. 803 */ 804 public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/genre"; 805 806 /** 807 * The default sort order for this table 808 */ 809 public static final String DEFAULT_SORT_ORDER = NAME; 810 811 /** 812 * Sub-directory of each genre containing all members. 813 */ 814 public static final class Members implements AudioColumns { 815 816 public static final Uri getContentUri(String volumeName, 817 long genreId) { 818 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName 819 + "/audio/genres/" + genreId + "/members"); 820 } 821 822 /** 823 * A subdirectory of each genre containing all member audio files. 824 */ 825 public static final String CONTENT_DIRECTORY = "members"; 826 827 /** 828 * The default sort order for this table 829 */ 830 public static final String DEFAULT_SORT_ORDER = TITLE; 831 832 /** 833 * The ID of the audio file 834 * <P>Type: INTEGER (long)</P> 835 */ 836 public static final String AUDIO_ID = "audio_id"; 837 838 /** 839 * The ID of the genre 840 * <P>Type: INTEGER (long)</P> 841 */ 842 public static final String GENRE_ID = "genre_id"; 843 } 844 } 845 846 /** 847 * Columns representing a playlist 848 */ 849 public interface PlaylistsColumns { 850 /** 851 * The name of the playlist 852 * <P>Type: TEXT</P> 853 */ 854 public static final String NAME = "name"; 855 856 /** 857 * The data stream for the playlist file 858 * <P>Type: DATA STREAM</P> 859 */ 860 public static final String DATA = "_data"; 861 862 /** 863 * The time the file was added to the media provider 864 * Units are seconds since 1970. 865 * <P>Type: INTEGER (long)</P> 866 */ 867 public static final String DATE_ADDED = "date_added"; 868 869 /** 870 * The time the file was last modified 871 * Units are seconds since 1970. 872 * NOTE: This is for internal use by the media scanner. Do not modify this field. 873 * <P>Type: INTEGER (long)</P> 874 */ 875 public static final String DATE_MODIFIED = "date_modified"; 876 } 877 878 /** 879 * Contains playlists for audio files 880 */ 881 public static final class Playlists implements BaseColumns, 882 PlaylistsColumns { 883 /** 884 * Get the content:// style URI for the audio playlists table on the 885 * given volume. 886 * 887 * @param volumeName the name of the volume to get the URI for 888 * @return the URI to the audio playlists table on the given volume 889 */ 890 public static Uri getContentUri(String volumeName) { 891 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + 892 "/audio/playlists"); 893 } 894 895 /** 896 * The content:// style URI for the internal storage. 897 */ 898 public static final Uri INTERNAL_CONTENT_URI = 899 getContentUri("internal"); 900 901 /** 902 * The content:// style URI for the "primary" external storage 903 * volume. 904 */ 905 public static final Uri EXTERNAL_CONTENT_URI = 906 getContentUri("external"); 907 908 /** 909 * The MIME type for this table. 910 */ 911 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/playlist"; 912 913 /** 914 * The MIME type for entries in this table. 915 */ 916 public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/playlist"; 917 918 /** 919 * The default sort order for this table 920 */ 921 public static final String DEFAULT_SORT_ORDER = NAME; 922 923 /** 924 * Sub-directory of each playlist containing all members. 925 */ 926 public static final class Members implements AudioColumns { 927 public static final Uri getContentUri(String volumeName, 928 long playlistId) { 929 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName 930 + "/audio/playlists/" + playlistId + "/members"); 931 } 932 933 /** 934 * The ID within the playlist. 935 */ 936 public static final String _ID = "_id"; 937 938 /** 939 * A subdirectory of each playlist containing all member audio 940 * files. 941 */ 942 public static final String CONTENT_DIRECTORY = "members"; 943 944 /** 945 * The ID of the audio file 946 * <P>Type: INTEGER (long)</P> 947 */ 948 public static final String AUDIO_ID = "audio_id"; 949 950 /** 951 * The ID of the playlist 952 * <P>Type: INTEGER (long)</P> 953 */ 954 public static final String PLAYLIST_ID = "playlist_id"; 955 956 /** 957 * The order of the songs in the playlist 958 * <P>Type: INTEGER (long)></P> 959 */ 960 public static final String PLAY_ORDER = "play_order"; 961 962 /** 963 * The default sort order for this table 964 */ 965 public static final String DEFAULT_SORT_ORDER = PLAY_ORDER; 966 } 967 } 968 969 /** 970 * Columns representing an artist 971 */ 972 public interface ArtistColumns { 973 /** 974 * The artist who created the audio file, if any 975 * <P>Type: TEXT</P> 976 */ 977 public static final String ARTIST = "artist"; 978 979 /** 980 * A non human readable key calculated from the ARTIST, used for 981 * searching, sorting and grouping 982 * <P>Type: TEXT</P> 983 */ 984 public static final String ARTIST_KEY = "artist_key"; 985 986 /** 987 * The number of albums in the database for this artist 988 */ 989 public static final String NUMBER_OF_ALBUMS = "number_of_albums"; 990 991 /** 992 * The number of albums in the database for this artist 993 */ 994 public static final String NUMBER_OF_TRACKS = "number_of_tracks"; 995 } 996 997 /** 998 * Contains artists for audio files 999 */ 1000 public static final class Artists implements BaseColumns, ArtistColumns { 1001 /** 1002 * Get the content:// style URI for the artists table on the 1003 * given volume. 1004 * 1005 * @param volumeName the name of the volume to get the URI for 1006 * @return the URI to the audio artists table on the given volume 1007 */ 1008 public static Uri getContentUri(String volumeName) { 1009 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + 1010 "/audio/artists"); 1011 } 1012 1013 /** 1014 * The content:// style URI for the internal storage. 1015 */ 1016 public static final Uri INTERNAL_CONTENT_URI = 1017 getContentUri("internal"); 1018 1019 /** 1020 * The content:// style URI for the "primary" external storage 1021 * volume. 1022 */ 1023 public static final Uri EXTERNAL_CONTENT_URI = 1024 getContentUri("external"); 1025 1026 /** 1027 * The MIME type for this table. 1028 */ 1029 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/artists"; 1030 1031 /** 1032 * The MIME type for entries in this table. 1033 */ 1034 public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/artist"; 1035 1036 /** 1037 * The default sort order for this table 1038 */ 1039 public static final String DEFAULT_SORT_ORDER = ARTIST_KEY; 1040 1041 /** 1042 * Sub-directory of each artist containing all albums on which 1043 * a song by the artist appears. 1044 */ 1045 public static final class Albums implements AlbumColumns { 1046 public static final Uri getContentUri(String volumeName, 1047 long artistId) { 1048 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName 1049 + "/audio/artists/" + artistId + "/albums"); 1050 } 1051 } 1052 } 1053 1054 /** 1055 * Columns representing an album 1056 */ 1057 public interface AlbumColumns { 1058 1059 /** 1060 * The id for the album 1061 * <P>Type: INTEGER</P> 1062 */ 1063 public static final String ALBUM_ID = "album_id"; 1064 1065 /** 1066 * The album on which the audio file appears, if any 1067 * <P>Type: TEXT</P> 1068 */ 1069 public static final String ALBUM = "album"; 1070 1071 /** 1072 * The artist whose songs appear on this album 1073 * <P>Type: TEXT</P> 1074 */ 1075 public static final String ARTIST = "artist"; 1076 1077 /** 1078 * The number of songs on this album 1079 * <P>Type: INTEGER</P> 1080 */ 1081 public static final String NUMBER_OF_SONGS = "numsongs"; 1082 1083 /** 1084 * This column is available when getting album info via artist, 1085 * and indicates the number of songs on the album by the given 1086 * artist. 1087 * <P>Type: INTEGER</P> 1088 * 1089 * @hide pending API Council approval 1090 */ 1091 public static final String NUMBER_OF_SONGS_FOR_ARTIST = "numsongs_by_artist"; 1092 1093 /** 1094 * The year in which the earliest and latest songs 1095 * on this album were released. These will often 1096 * be the same, but for compilation albums they 1097 * might differ. 1098 * <P>Type: INTEGER</P> 1099 */ 1100 public static final String FIRST_YEAR = "minyear"; 1101 public static final String LAST_YEAR = "maxyear"; 1102 1103 /** 1104 * A non human readable key calculated from the ALBUM, used for 1105 * searching, sorting and grouping 1106 * <P>Type: TEXT</P> 1107 */ 1108 public static final String ALBUM_KEY = "album_key"; 1109 1110 /** 1111 * Cached album art. 1112 * <P>Type: TEXT</P> 1113 */ 1114 public static final String ALBUM_ART = "album_art"; 1115 } 1116 1117 /** 1118 * Contains artists for audio files 1119 */ 1120 public static final class Albums implements BaseColumns, AlbumColumns { 1121 /** 1122 * Get the content:// style URI for the albums table on the 1123 * given volume. 1124 * 1125 * @param volumeName the name of the volume to get the URI for 1126 * @return the URI to the audio albums table on the given volume 1127 */ 1128 public static Uri getContentUri(String volumeName) { 1129 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + 1130 "/audio/albums"); 1131 } 1132 1133 /** 1134 * The content:// style URI for the internal storage. 1135 */ 1136 public static final Uri INTERNAL_CONTENT_URI = 1137 getContentUri("internal"); 1138 1139 /** 1140 * The content:// style URI for the "primary" external storage 1141 * volume. 1142 */ 1143 public static final Uri EXTERNAL_CONTENT_URI = 1144 getContentUri("external"); 1145 1146 /** 1147 * The MIME type for this table. 1148 */ 1149 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/albums"; 1150 1151 /** 1152 * The MIME type for entries in this table. 1153 */ 1154 public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/album"; 1155 1156 /** 1157 * The default sort order for this table 1158 */ 1159 public static final String DEFAULT_SORT_ORDER = ALBUM_KEY; 1160 } 1161 } 1162 1163 public static final class Video { 1164 /** 1165 * The default sort order for this table 1166 */ 1167 public static final String DEFAULT_SORT_ORDER = "name ASC"; 1168 1169 public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) 1170 { 1171 return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER); 1172 } 1173 1174 public interface VideoColumns extends MediaColumns { 1175 1176 /** 1177 * The duration of the video file, in ms 1178 * <P>Type: INTEGER (long)</P> 1179 */ 1180 public static final String DURATION = "duration"; 1181 1182 /** 1183 * The artist who created the video file, if any 1184 * <P>Type: TEXT</P> 1185 */ 1186 public static final String ARTIST = "artist"; 1187 1188 /** 1189 * The album the video file is from, if any 1190 * <P>Type: TEXT</P> 1191 */ 1192 public static final String ALBUM = "album"; 1193 1194 /** 1195 * The resolution of the video file, formatted as "XxY" 1196 * <P>Type: TEXT</P> 1197 */ 1198 public static final String RESOLUTION = "resolution"; 1199 1200 /** 1201 * The description of the video recording 1202 * <P>Type: TEXT</P> 1203 */ 1204 public static final String DESCRIPTION = "description"; 1205 1206 /** 1207 * Whether the video should be published as public or private 1208 * <P>Type: INTEGER</P> 1209 */ 1210 public static final String IS_PRIVATE = "isprivate"; 1211 1212 /** 1213 * The user-added tags associated with a video 1214 * <P>Type: TEXT</P> 1215 */ 1216 public static final String TAGS = "tags"; 1217 1218 /** 1219 * The YouTube category of the video 1220 * <P>Type: TEXT</P> 1221 */ 1222 public static final String CATEGORY = "category"; 1223 1224 /** 1225 * The language of the video 1226 * <P>Type: TEXT</P> 1227 */ 1228 public static final String LANGUAGE = "language"; 1229 1230 /** 1231 * The latitude where the image was captured. 1232 * <P>Type: DOUBLE</P> 1233 */ 1234 public static final String LATITUDE = "latitude"; 1235 1236 /** 1237 * The longitude where the image was captured. 1238 * <P>Type: DOUBLE</P> 1239 */ 1240 public static final String LONGITUDE = "longitude"; 1241 1242 /** 1243 * The date & time that the image was taken in units 1244 * of milliseconds since jan 1, 1970. 1245 * <P>Type: INTEGER</P> 1246 */ 1247 public static final String DATE_TAKEN = "datetaken"; 1248 1249 /** 1250 * The mini thumb id. 1251 * <P>Type: INTEGER</P> 1252 */ 1253 public static final String MINI_THUMB_MAGIC = "mini_thumb_magic"; 1254 1255 /** 1256 * The bucket id of the video. This is a read-only property that 1257 * is automatically computed from the DATA column. 1258 * <P>Type: TEXT</P> 1259 */ 1260 public static final String BUCKET_ID = "bucket_id"; 1261 1262 /** 1263 * The bucket display name of the video. This is a read-only property that 1264 * is automatically computed from the DATA column. 1265 * <P>Type: TEXT</P> 1266 */ 1267 public static final String BUCKET_DISPLAY_NAME = "bucket_display_name"; 1268 } 1269 1270 public static final class Media implements VideoColumns { 1271 /** 1272 * Get the content:// style URI for the video media table on the 1273 * given volume. 1274 * 1275 * @param volumeName the name of the volume to get the URI for 1276 * @return the URI to the video media table on the given volume 1277 */ 1278 public static Uri getContentUri(String volumeName) { 1279 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + 1280 "/video/media"); 1281 } 1282 1283 /** 1284 * The content:// style URI for the internal storage. 1285 */ 1286 public static final Uri INTERNAL_CONTENT_URI = 1287 getContentUri("internal"); 1288 1289 /** 1290 * The content:// style URI for the "primary" external storage 1291 * volume. 1292 */ 1293 public static final Uri EXTERNAL_CONTENT_URI = 1294 getContentUri("external"); 1295 1296 /** 1297 * The MIME type for this table. 1298 */ 1299 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/video"; 1300 1301 /** 1302 * The default sort order for this table 1303 */ 1304 public static final String DEFAULT_SORT_ORDER = TITLE; 1305 } 1306 } 1307 1308 /** 1309 * Uri for querying the state of the media scanner. 1310 */ 1311 public static Uri getMediaScannerUri() { 1312 return Uri.parse(CONTENT_AUTHORITY_SLASH + "none/media_scanner"); 1313 } 1314 1315 /** 1316 * Name of current volume being scanned by the media scanner. 1317 */ 1318 public static final String MEDIA_SCANNER_VOLUME = "volume"; 1319} 1320