views:

170

answers:

2

I am new to Android development, and I am working on a media player app as a learning experience. I am currently trying to add a menu view that utilizes album art in a gridview. Here is my code:

public class coverMenu extends Activity {

 private Cursor audioCursor;
 public String artistInput;
 private static final String TAG = "coverMenu";

 @Override
 public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        setContentView(R.layout.cover);
        Bundle data = this.getIntent().getExtras();
        String artistKey = data.getString("artistPass");


       Toast.makeText(this, artistKey, Toast.LENGTH_LONG).show();

       audioCursor = getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, null, 
         MediaStore.Audio.Albums.ARTIST + "='" + artistKey + "'", null,MediaStore.Audio.Albums.ALBUM + " ASC");
        startManagingCursor(audioCursor);

        String[]from = new String[]{MediaStore.Audio.Albums.ALBUM_ART};


        int[] to = new int []{android.R.id.text1};

        ListAdapter mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1,
          audioCursor, from, to);
        GridView gridview = (GridView) findViewById(R.id.gridview);
         gridview.setAdapter(mAdapter);

My problem is that the grid item now lists the path to the art, but does not show it. Can anyone help me by explaining how to parse this into a bitmap and send it to the gridview?

I have spent some time looking at the stock Android music player, but cannot find a simple solution to this.

Any help is appreciated.

[Latest Debug:]

DalvikVM[localhost:8615]
Thread [<3> main] (Suspended (exception RuntimeException))
ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2496
ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2512
ActivityThread.access$2200(ActivityThread, ActivityThread$ActivityRecord, Intent) line: 119 ActivityThread$H.handleMessage(Message) line: 1863
ActivityThread$H(Handler).dispatchMessage(Message) line: 99 Looper.loop() line: 123 ActivityThread.main(String[]) line: 4363
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 521
ZygoteInit$MethodAndArgsCaller.run() line: 860
ZygoteInit.main(String[]) line: 618 NativeStart.main(String[]) line: not available [native method]
Thread [<13> Binder Thread #2] (Running)
Thread [<11> Binder Thread #1] (Running)
Thread [<15> Binder Thread #3] (Running)

A: 

You need to create a custom adapter class that returns a populated grid view item based on the cursor's position. Here's a pretty crude example.

custom_grid_item.xml:

<LinearLayout android:id="@+id/LinearLayout01"
android:layout_width="fill_parent" android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"&gt;
<ImageView android:id="@+id/album_image"
android:layout_height="wrap_content" android:layout_width="wrap_content">
</ImageView>
</LinearLayout>

MySimpleListAdapter.java:

import java.io.File;
import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SimpleCursorAdapter;
import android.widget.ImageView.ScaleType;

public class MySimpleListAdapter extends SimpleCursorAdapter {

private Context mContext;

public MySimpleListAdapter(Context context, int layout, Cursor c,
        String[] from, int[] to) {
    super(context, layout, c, from, to);
    mContext = context;
}

public View getView(int position, View convertView, ViewGroup parent) {
    View v;
    ImageView iv;
    if (convertView != null)
        v = convertView;
    else {
        LayoutInflater layout = LayoutInflater.from(mContext);
        v = layout.inflate(R.layout.custom_grid_item, null);
    }

    this.getCursor().moveToPosition(position);

    iv = (ImageView) v.findViewById(R.id.album_image);

    iv.setImageURI(Uri.fromFile(new File(this.getCursor().getString(9))));
    iv.setScaleType(ScaleType.CENTER_INSIDE);
    return v;

}}

Activity:

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.widget.GridView;
import android.widget.Toast;

public class CoverMenu extends Activity {
private Cursor audioCursor;
public String artistInput;
private static final String TAG = "coverMenu";

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Set to some artist you know
String artistKey = "Devo";

Toast.makeText(this, artistKey, Toast.LENGTH_LONG).show();

audioCursor = getContentResolver().query(
        MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, null,
        MediaStore.Audio.Albums.ARTIST + "='" + artistKey + "'", null,
        MediaStore.Audio.Albums.ALBUM + " ASC");
startManagingCursor(audioCursor);

String[] from = new String[] { MediaStore.Audio.Albums.ALBUM_ART };

int[] to = new int[] { android.R.id.text1 };

MySimpleListAdapter mAdapter = new MySimpleListAdapter(this,
        android.R.layout.simple_list_item_1, audioCursor, from, to);

GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(mAdapter);
}}

Check out this nice video from Google I/O on creating custom listviews, it will be a big help to you in the future.

magaio
Catching a force close when clicking on the 'artist' list that leads to the main activity.
Josh
Thread [<3> main] (Suspended (exception RuntimeException)) ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2496 ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2512 ActivityThread.access$2200(ActivityThread,
Josh
ActivityThread$ActivityRecord, Intent) line: 119 ActivityThread$H.handleMessage(Message) line: 1863 ActivityThread$H(Handler).dispatchMessage(Message) line: 99 Looper.loop() line: 123 ActivityThread.main(String[]) line: 4363 Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] Method.invoke(Object, Object...) line: 521 ZygoteInit$MethodAndArgsCaller.run() line: 860 ZygoteInit.main(String[]) line: 618 NativeStart.main(String[]) line: not available [native method]
Josh
Thank you for the help by the way. I didn't mean to reply and not seem grateful.
Josh
It's OK, Josh. I tested mine on a Nexus One and I didn't use any Intent bundles, I just added that in hoping you'd work it out. I'll fix it to my (working) version.
magaio
Edit: See if the above works for you.
magaio
Thanks magaio. Still force closing. Incedently if I comment out the final line of the Activity: //gridview.setAdapter(mAdapter); it will not force close, and starts a new list, but it only shows my program name at the top.
Josh
I am able to get a gridview using the below code, but any time I add a filter or sort to the managedQuery I get force closed: Cursor cur = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null, null,null,null); cur.moveToPosition(position); int dataCol = cur.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART); String data = cur.getString(dataCol); Uri dataURI = Uri.parse(data); imageView.setImageURI(dataURI);
Josh
Can you paste the stack trace from the log cat? What is the exception with the gridview.setAdapter(mAdapter)?
magaio
Thread [<3> main] (Suspended (exception RuntimeException)) ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2496 ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2512 ActivityThread.access$2200(ActivityThread, ActivityThread$ActivityRecord, Intent) line: 119 ActivityThread$H.handleMessage(Message) line: 1863 ActivityThread$H(Handler).dispatchMessage(Message) line: 99
Josh
Looper.loop() line: 123 ActivityThread.main(String[]) line: 4363 Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] Method.invoke(Object, Object...) line: 521 ZygoteInit$MethodAndArgsCaller.run() line: 860 ZygoteInit.main(String[]) line: 618 NativeStart.main(String[]) line: not available [native method]
Josh
Easier to read Debug added to the question at top.
Josh
Thanks again for all of your help magaio
Josh
Keep hitting continue until the program force closes and paste in the red stack trace at the bottom of logcat ... You have to let the exception message propagate down. Meanwhile I'll modify my code so it works when called via an intent. I think that'd where your problem is because my activity is running as the start activity.
magaio
Did you put coverMenu in your AndroidManifest.xml?
magaio
A: 

Yes, all activities are included in the AndroidManifest. Not sure where you would like for me to hit continue above.... When running the emulator in debug and clicking on the artist name in the lead-in menu the program stalls, and Eclipse opens a new tab reading: ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2496 . The emulator then switches to a totally black screen and that's the end.

Sorry for being such a noob.

Josh

Josh