Exemplo n.º 1
0
  /**
   * Builds a query that will return all the songs represented by the given parameters.
   *
   * @param type MediaUtils.TYPE_ARTIST, TYPE_ALBUM, or TYPE_SONG.
   * @param id The MediaStore id of the song, artist, or album.
   * @param projection The columns to query.
   * @param select An extra selection to pass to the query, or null.
   * @return The initialized query.
   */
  private static QueryTask buildMediaQuery(int type, long id, String[] projection, String select) {
    Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    StringBuilder selection = new StringBuilder();
    String sort = DEFAULT_SORT;

    switch (type) {
      case TYPE_SONG:
        selection.append(MediaStore.Audio.Media._ID);
        break;
      case TYPE_ARTIST:
        selection.append(MediaStore.Audio.Media.ARTIST_ID);
        break;
      case TYPE_ALBUM:
        selection.append(MediaStore.Audio.Media.ALBUM_ID);
        sort = ALBUM_SORT;
        break;
      default:
        throw new IllegalArgumentException("Invalid type specified: " + type);
    }

    selection.append('=');
    selection.append(id);
    selection.append(" AND length(_data) AND " + MediaStore.Audio.Media.IS_MUSIC);

    if (select != null) {
      selection.append(" AND ");
      selection.append(select);
    }

    QueryTask result = new QueryTask(media, projection, selection.toString(), null, sort);
    result.type = type;
    return result;
  }
Exemplo n.º 2
0
 /**
  * Builds a query that will return all the songs in the playlist with the given id.
  *
  * @param id The id of the playlist in MediaStore.Audio.Playlists.
  * @param projection The columns to query.
  * @param selection The selection to pass to the query, or null.
  * @return The initialized query.
  */
 public static QueryTask buildPlaylistQuery(long id, String[] projection, String selection) {
   Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", id);
   String sort = MediaStore.Audio.Playlists.Members.PLAY_ORDER;
   QueryTask result = new QueryTask(uri, projection, selection, null, sort);
   result.type = TYPE_PLAYLIST;
   return result;
 }
Exemplo n.º 3
0
  /**
   * Build a query that will contain all the media under the given path.
   *
   * @param path The path, e.g. /mnt/sdcard/music/
   * @param projection The columns to query
   * @return The initialized query.
   */
  public static QueryTask buildFileQuery(String path, String[] projection) {
    /* make sure that the path is:
       -> fixed-up to point to the real mountpoint if user browsed to the mediadir symlink
       -> terminated with a / if it is a directory
       -> ended with a % for the LIKE query
    */
    path = addDirEndSlash(sanitizeMediaPath(path)) + "%";
    final String query = "_data LIKE ? AND " + MediaStore.Audio.Media.IS_MUSIC;
    String[] qargs = {path};

    Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    QueryTask result = new QueryTask(media, projection, query, qargs, DEFAULT_SORT);
    result.type = TYPE_FILE;
    return result;
  }
Exemplo n.º 4
0
  /**
   * Builds a query that will return all the songs in the genre with the given id.
   *
   * @param id The id of the genre in MediaStore.Audio.Genres.
   * @param projection The columns to query.
   * @param selection The selection to pass to the query, or null.
   * @param selectionArgs The arguments to substitute into the selection.
   * @param sort The sort order.
   * @param type The media type to query and return
   * @param returnSongs returns matching songs instead of `type' if true
   */
  public static QueryTask buildGenreQuery(
      long id,
      String[] projection,
      String selection,
      String[] selectionArgs,
      String sort,
      int type,
      boolean returnSongs) {
    // Note: This function works on a raw sql query with way too much internal
    // knowledge about the mediaProvider SQL table layout. Yes: it's ugly.
    // The reason for this mess is that android has a very crippled genre implementation
    // and does, for example, not allow us to query the albumbs beloging to a genre.

    Uri uri = MediaStore.Audio.Genres.Members.getContentUri("external", id);
    String[] clonedProjection =
        projection
            .clone(); // we modify the projection, but this should not be visible to the caller
    String sql = "";
    String authority = "audio";

    if (type == TYPE_ARTIST) authority = "artist_info";
    if (type == TYPE_ALBUM) authority = "album_info";

    // Our raw SQL query includes the album_info table (well: it's actually a view)
    // which shares some columns with audio.
    // This regexp should matche duplicate column names and forces them to use
    // the audio table as a source
    final String _FORCE_AUDIO_SRC = "(^|[ |,\\(])(_id|album(_\\w+)?|artist(_\\w+)?)";

    // Prefix the SELECTed rows with the current table authority name
    for (int i = 0; i < clonedProjection.length; i++) {
      if (clonedProjection[i].equals("0") == false) // do not prefix fake rows
      clonedProjection[i] = (returnSongs ? "audio" : authority) + "." + clonedProjection[i];
    }

    sql += TextUtils.join(", ", clonedProjection);
    sql +=
        " FROM audio_genres_map_noid, audio" + (authority.equals("audio") ? "" : ", " + authority);
    sql += " WHERE(audio._id = audio_id AND genre_id=?)";

    if (selection != null && selection.length() > 0)
      sql += " AND(" + selection.replaceAll(_FORCE_AUDIO_SRC, "$1audio.$2") + ")";

    if (type == TYPE_ARTIST)
      sql +=
          " AND(artist_info._id = audio.artist_id)"
              + (returnSongs ? "" : " GROUP BY artist_info._id");

    if (type == TYPE_ALBUM)
      sql +=
          " AND(album_info._id = audio.album_id)" + (returnSongs ? "" : " GROUP BY album_info._id");

    if (sort != null && sort.length() > 0)
      sql += " ORDER BY " + sort.replaceAll(_FORCE_AUDIO_SRC, "$1audio.$2");

    // We are now turning this into an sql injection. Fun times.
    clonedProjection[0] = sql + " --";

    QueryTask result = new QueryTask(uri, clonedProjection, selection, selectionArgs, sort);
    result.type = TYPE_GENRE;
    return result;
  }