2016-10-27 2 views
0

Meine App muss alle Musik auf dem Gerät auflisten, einschließlich: Titel, Interpret, Album, Genre und mehr.Android erhalten alle Musik und Genres ohne verschachtelte Cursor. (MediaStore.Audio ...)

Die Art und Weise ich kenne das Genre für ein Lied zu bekommen, ist wie dies ein weiterer Cursor mit dem Song-ID zu erstellen:

Uri uri = MediaStore.Audio.Genres.getContentUriForAudioId("external", (int) id); 
Cursor genresCursor = mContentResolver.query(uri, genresProjection, null, null, null); 

Allerdings, wenn ich dies tun in der Cursor, die alle Lieder aufgelistet, Die Ladezeit wird sehr zunehmen. (für die Anzahl der Songs auf meinem Handy, von 0,5 Sekunden bis etwa 3 Sekunden).

Dies ist mein Code:

// If you change this to `false`, it will load a lot quicker. 
private static final boolean LOAD_GENRE = true; 

private static String[] mediaProjection = { 
     MediaStore.Audio.AudioColumns._ID, 
     MediaStore.Audio.AudioColumns.DATA, 
     MediaStore.Audio.AudioColumns.TITLE, 
     MediaStore.Audio.AudioColumns.ARTIST, 
     MediaStore.Audio.AudioColumns.ALBUM, 
     MediaStore.Audio.AudioColumns.ALBUM_ID, 
     MediaStore.Audio.AudioColumns.DURATION 
}; 
private static String[] genresProjection = { 
     MediaStore.Audio.GenresColumns.NAME 
}; 

private ArrayList<MediaMetadataCompat> getAllMusic() { 
    Uri uriAudio = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
    Cursor cursor = mContentResolver.query(uriAudio, mediaProjection, null, null, null); 

    if (cursor != null) { 
     int count = cursor.getCount(); 

     if (count > 0) { 
      ArrayList<MediaMetadataCompat> audioFiles = new ArrayList<>(); 

      while (cursor.moveToNext()) { 
       MediaMetadataCompat song = buildFromCursor(cursor); 
       if (song != null) { 
        audioFiles.add(song); 
       } 
      } 
      cursor.close(); 

      return audioFiles; 
     } 
    } 
    return new ArrayList<>(); 
} 

private MediaMetadataCompat buildFromCursor(Cursor cursor, boolean loadGenre) { 
    long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.AudioColumns._ID)); 
    String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DATA)); 
    String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.AudioColumns.TITLE)); 
    String artist = ...; 
    String album = ...; 
    long albumId = ...; 
    long duration = ...; 

    //File file = new File(data); 
    //if (!file.exists()) { 
    // Log.e(TAG, "Skipping song because it does not exist: " + title); 
    // return null; 
    //} 


    Uri uri = MediaStore.Audio.Genres.getContentUriForAudioId("external", (int) id); 

    if (LOAD_GENRE) { 
     String genre = null; 
     Cursor genresCursor = mContentResolver.query(uri, genresProjection, null, null, null); 
     if (genresCursor != null && genresCursor.moveToFirst()) { 
      int genreColumnIndex = genresCursor.getColumnIndex(MediaStore.Audio.GenresColumns.NAME); 
      do { 
       String genreColumn = genresCursor.getString(genreColumnIndex); 
       if (genre == null) { 
        genre = genreColumn; 
       } else { 
        genre += " " + genre; 
       } 
      } while (genresCursor.moveToNext()); 
      genresCursor.close(); 
     } 
    } 

    // Workaround to avoid ANOTHER cursor to load album art. 
    Uri albumArtUri = ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), albumId); 

    MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder() 
      .putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, String.valueOf(id)) 
      .put... 
      .put...; 


    return builder.build(); 
} 

Gibt es eine Möglichkeit, diesen Code zu verbessern, eine verschachtelte Cursor zu vermeiden? Ich habe bereits einen Workaround für das Album gefunden. Ist es möglich, sie irgendwie zu kombinieren? Wird ein CursorJoiner dafür arbeiten? Das Problem ist, dass Sie die Medien-ID benötigen, um das Genre zu erhalten. Vielen Dank.

Antwort

0

Ein SO Benutzer Suhaib Roomey gepostet dies vor kurzem (get genre_id and audio_id from audio_genres_map from mediastore). Vielleicht hilft es bei dem, was Sie erreichen möchten

String[] genresProjection = { 
     Audio.Genres.Members.AUDIO_ID, 
     Audio.Genres.Members.GENRE_ID 
}; 
     context.getContentResolver().query(Uri.parse("content://media/external/audio/genres/all/members"), genresProjection, null, null, null); 
Verwandte Themen