Android Open Source - DroidDoesMusic Library Album View






From Project

Back to project page DroidDoesMusic.

License

The source code is released under:

Copyright (C) 2011 by Michael Rose, Nick Hansen, Joe Zeimen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Soft...

If you think the Android project DroidDoesMusic listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.uid.DroidDoesMusic.UI;
/*from ww w  . j  a v  a2 s .  com*/
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeSet;

import android.app.ListActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AlphabetIndexer;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SectionIndexer;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.ImageView.ScaleType;

import com.uid.DroidDoesMusic.R;

public class LibraryAlbumView extends ListActivity {
  protected static final String TAG = "DroidDoesMusic";
  public static final String INTENT_ITEM_KEY = "artistName";
  public static final String INTENT_ITEM_KEY2 = "artistId";
  
  private Cursor cur;
  private String artistName = new String();
  private int artistId;
  private boolean populated = false;
  
  @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, getClass().getSimpleName() + ": onCreate");
        
        super.onCreate(savedInstanceState);
        setContentView(R.layout.library);
        
        // Get extra data from intent
        
        try {
          artistName = getIntent().getExtras().getString(INTENT_ITEM_KEY);
          artistId = getIntent().getExtras().getInt(INTENT_ITEM_KEY2);
          setTitle(artistName);
          
          if (artistName == null) {
            artistName = "";
          }
        } catch (NullPointerException e) {
          artistName = "";
        }
        
        getListView().setFastScrollEnabled(true);
        
        // Populate ListView
        populateDataIfReady();
    }
  
  @Override
  public void onResume() {
        Log.d(TAG, getClass().getSimpleName() + ": onResume");
    super.onResume();
    
    IntentFilter iff = new IntentFilter();
    iff.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
    iff.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
    iff.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
    iff.addDataScheme("file");
    registerReceiver(this.externalMediaListener, iff);
    
    populateDataIfReady();
  }
  
  @Override
  public void onPause() {
        Log.d(TAG, getClass().getSimpleName() + ": onPause");
    super.onPause();
    
    unregisterReceiver(this.externalMediaListener);
  }
  
  @Override
  public void onListItemClick(ListView l, View v, int position, long id) {
    Log.d(TAG, getClass().getSimpleName() + ": onListItemClick: (" + id + ")");
    super.onListItemClick(l, v, position, id);
    cur.moveToPosition(position);
    
    Intent i = new Intent(Intent.ACTION_PICK);
    i.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/ddm.track");
    i.putExtra(LibrarySongView.INTENT_ITEM_KEY, cur.getString(1));
    i.putExtra(LibrarySongView.INTENT_ITEM_KEY2, (Long)v.getTag(R.id.artist_id));
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    
//    View view = LibraryGroup.group.getLocalActivityManager().startActivity("SongView", i).getDecorView();
//    LibraryGroup.group.replaceView(view);

    startActivity(i);
  }
  
  public static <T>
  String join(final Iterable<T> objs, final String delimiter) {
      Iterator<T> iter = objs.iterator();
      if (!iter.hasNext())
          return "";
      StringBuffer buffer = new StringBuffer('"' + String.valueOf(iter.next()) + '"');
      while (iter.hasNext())
          buffer.append(delimiter).append('"' + String.valueOf(iter.next()) + '"');
      return buffer.toString();
  }
  
  public void getAlbums(int... artistId) {
    int artist;
    String filter = new String();
    
        // Grabs content URI for a unique list of albums on the SDcard
    try {
      artist = artistId[0];
      
      if (artist > 0) {
        filter = Audio.Media.ARTIST_ID + " = '" + artist + "'";
      } else {
        filter = null;
      }
    } catch (ArrayIndexOutOfBoundsException e) {
      artist = 0;
      filter = null;
    }
    
    Uri extUri = Audio.Albums.EXTERNAL_CONTENT_URI;
    
    TreeSet<String> ts = new TreeSet<String>();
    
    String[] sproj = new String[] {Audio.Media.ALBUM};
    
    Cursor c = managedQuery(Audio.Media.EXTERNAL_CONTENT_URI, sproj, filter, null, Audio.Albums.ALBUM + " ASC");
    
    for(int i = 0; i < c.getCount(); i++) {
      c.moveToPosition(i);
      String u_album = c.getString(c.getColumnIndex(Audio.Media.ALBUM));
      Log.d(TAG, "album: " + u_album);
      ts.add(u_album);
    }
    
    filter = Audio.Media.ALBUM + " IN (" + join(ts, ", ") + ")";

        // Columns to grab from the DB, then the expected mappings
        String[] projection = new String[] {Audio.Albums._ID, Audio.Albums.ALBUM, Audio.Media.ARTIST_ID, Audio.Albums.ARTIST, Audio.Albums.ALBUM_ART};

        String[] displayColumns = new String[] {Audio.Albums.ALBUM, Audio.Albums.ARTIST};
        int[] display = new int[] { android.R.id.text1, android.R.id.text2 };

        String sort = Audio.Media.ARTIST + " ASC, " + Audio.Albums.ALBUM + " ASC";
        
        int layout = R.layout.album;
        
        getData(extUri, projection, filter, displayColumns, display, sort, layout);
  }
  
  public void getData(Uri datauri, String[] projection, String filter, String[] displayColumns, int[] display, String sort, int layout) {
    // Flag
    populated = true;

        // Activity-managed cursor to get sorted list of artists
        cur = managedQuery(datauri, projection, filter, null, sort);
        
        // Check if cursor is empty
        if (cur.getCount() < 1) {
        Intent i = new Intent(Intent.ACTION_PICK);
        i.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/ddm.track");
        i.putExtra(LibrarySongView.INTENT_ITEM_KEY, "");
        i.putExtra(LibrarySongView.INTENT_ITEM_KEY2, artistId);
        i.putExtra(LibrarySongView.INTENT_ITEM_KEY3, artistName);
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        }
        
        // SimpleCursorAdapter maps the cursor columns to simplelistitems
        AlbumListAdapter mAdapter = new AlbumListAdapter(this, layout, cur, displayColumns, display);
        
        // Set adapter of listview to the SimpleCursorAdapter 
        setListAdapter(mAdapter);
  }
  
  public void populateDataIfReady() {
        if (!isSdPresent()) {
          TextView tv = (TextView)findViewById(android.R.id.empty);
          tv.setText(getResources().getString(R.string.no_sd_card));
        } else if (!populated) {
          getAlbums(artistId);
        }
  }
  
  public static boolean isSdPresent() {
      return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
  }
  
  private BroadcastReceiver externalMediaListener = new BroadcastReceiver() {
    @Override
    public void onReceive(Context content, Intent intent) {
          Log.d(TAG, getClass().getSimpleName() + ": onReceive: " + intent.getData());
          receivedBroadcast(intent);
    }
  };
  
  private void receivedBroadcast(Intent i) {
    Log.d(TAG, getClass().getSimpleName() + ": receivedBroadcast: " + i.getData());
    
    if (i.getAction().equals(Intent.ACTION_UMS_CONNECTED) || i.getAction().equals(Intent.ACTION_MEDIA_SHARED) || i.getAction().equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
      populated = false;
    } else {
      // Try again after 5 seconds using a handler
      Handler h = new Handler();
      h.postDelayed(new Runnable() {
        public void run() {
          populateDataIfReady();
        }
      }, 5000);
    }
  }
  
  public static class AlbumListAdapter extends SimpleCursorAdapter implements SectionIndexer {
    private AlphabetIndexer mIndexer;
    private final Resources mResources;
    
    public AlbumListAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
      super(context, layout, c, from, to);
      
      // Get resources for use later
      mResources = context.getResources();
      
      try {
        // Fire up an AlphabetIndexer for ListView fastscroll
        mIndexer = new AlphabetIndexer(c, c.getColumnIndex(Audio.Albums.ALBUM), mResources.getString(R.string.fastscroll_index));
      } catch (IllegalArgumentException e) {
        e.printStackTrace();
      } catch (NullPointerException e) {
        e.printStackTrace();
      }
    }
    
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
      View v = super.newView(context, cursor, parent);
      
      // Container for views
      ViewHolder vh = new ViewHolder();
      
      // Set views into container
      vh.icon = (ImageView)v.findViewById(R.id.icon);
      vh.line1 = (TextView)v.findViewById(R.id.text1);
      vh.line2 = (TextView)v.findViewById(R.id.text2);
      
      // 'tag' the view with the ViewHolder for use by bindView
      v.setTag(vh);
      return v;
    }
    
    @Override
    public void bindView(View view, Context context, Cursor c) {
      ViewHolder vh = (ViewHolder)view.getTag();
      
      // Album ID
      long albumId = c.getLong(c.getColumnIndex(Audio.Albums._ID));
      
      // Get album icon
      Drawable d;
      String art = c.getString(c.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART));
  
      ArtRender.Instance(mResources);
      d = ArtRender.getArt(art, albumId);
      
      // Get artist name, set "unknown" if missing
      String artistName = c.getString(c.getColumnIndex(Audio.Albums.ARTIST));
      if (artistName == null || artistName.equals(MediaStore.UNKNOWN_STRING)) {
        artistName = mResources.getString(R.string.unknown_artist);
      }
      
      // Get album name, set "unknown" if missing
      String albumName = c.getString(c.getColumnIndex(Audio.Albums.ALBUM));
      if (albumName == null || albumName.equals(MediaStore.UNKNOWN_STRING)) {
        albumName = mResources.getString(R.string.unknown_album);
      }

      view.setTag(R.id.artist_id, c.getLong(c.getColumnIndex(Audio.Media.ARTIST_ID)));
      
      // Set view
      vh.icon.setImageDrawable(d);
      vh.icon.setScaleType(ScaleType.CENTER);
      vh.icon.setPadding(0, 0, 1, 0);
      vh.line1.setText(albumName);
      vh.line2.setText(artistName);
    }

    public int getPositionForSection(int section) {
      return mIndexer.getPositionForSection(section);
    }

    public int getSectionForPosition(int position) {
      return 0;
    }

    public Object[] getSections() {
      return mIndexer.getSections();
    }
    
    private static class ViewHolder {
      ImageView icon;
      TextView line1;
      TextView line2;
    }
  }
  
  private static class ArtRender {
    private static ArtRender single;
    
    private static Resources mResources;
    private static final HashMap<Point, Matrix> matrixCache = new HashMap<Point, Matrix>(5);
    private static BitmapDrawable defaultDrawable;
    private static final HashMap<Long, BitmapDrawable> artCache = new HashMap<Long, BitmapDrawable>(25);
    
    private final static int defaultIconResourceId = R.drawable.icon;
    
    private ArtRender(Resources mResources) {
      ArtRender.mResources = mResources;
    }
    
    public static ArtRender Instance(Resources mResources) {
      if (single == null) {
        single = new ArtRender(mResources);
      }
      
      return single;
    }
    
    public static BitmapDrawable getArt(String art, long albumId) {
      BitmapDrawable d;
      
      if (defaultDrawable == null) {
        defaultDrawable = resizeBitmap(BitmapFactory.decodeResource(mResources, defaultIconResourceId));
      }
      
      if (art == null || art.length() == 0) {
        d = defaultDrawable;
      } else {
        if (artCache.containsKey(albumId)) {
          d = artCache.get(albumId);
        } else {
          try {
            Bitmap orig = BitmapFactory.decodeFile(art);

            d = resizeBitmap(orig);
            artCache.put(albumId, d);
          } catch (Exception e) {
            e.printStackTrace();
            d = defaultDrawable;
          }
        }
      }
      
      if (d != null) {
        d.setDither(false);
      } else {
        d = defaultDrawable;
      }
      
      return d;
    }
    
    private static BitmapDrawable resizeBitmap(Bitmap orig) {
      final float scale = mResources.getDisplayMetrics().density;
      Log.d(TAG, String.valueOf(scale));
      
      int w = orig.getWidth();
      int h = orig.getHeight();
      Point pair = new Point(w, h);
      
      Matrix m;
      
      if (matrixCache.containsKey(pair)) {
        m = matrixCache.get(pair);
      } else {
        final int newWidth = 64; // dip
        final int newHeight = 64;
        // Convert the dips to pixels
        float scaleWidth = (float)newWidth/w * scale * scale;
        float scaleHeight = (float)newHeight/h * scale * scale;
        
        m = new Matrix();
        m.postScale(scaleWidth, scaleHeight);
      }
      

      Bitmap resized = Bitmap.createBitmap(orig, 0, 0, w, h, m, true);
      return new BitmapDrawable(resized);
    }
  }
}




Java Source Code List

com.uid.DroidDoesMusic.UI.About.java
com.uid.DroidDoesMusic.UI.ControlView.java
com.uid.DroidDoesMusic.UI.LibraryAlbumView.java
com.uid.DroidDoesMusic.UI.LibraryArtistView.java
com.uid.DroidDoesMusic.UI.LibrarySongView.java
com.uid.DroidDoesMusic.UI.Main.java
com.uid.DroidDoesMusic.UI.NowPlaying.java
com.uid.DroidDoesMusic.UI.PlaylistSongView.java
com.uid.DroidDoesMusic.UI.Playlist.java
com.uid.DroidDoesMusic.UI.Preferences.java
com.uid.DroidDoesMusic.UI.QueueView.java
com.uid.DroidDoesMusic.UI.SimpleGestureFilter.java
com.uid.DroidDoesMusic.player.Player.java
com.uid.DroidDoesMusic.util.PlaylistManager.java