How to Dynamically show images from a folder in sdcard - android

I have to create a gridview that is loaded with images from a specific folder that resides on an SDCard. The path to the folder is "/sdcard/images/". i tried with this code,the app
is taking too much time to load and it is displaying only one image.
public class ImAdapterh extends BaseAdapter{
File dir=new File(Environment.getExternalStorageDirectory(),"/myImages/");
int count=dir.list().length;
String[] fileNames = dir.list();
private Context mContext;
public ImAdapterh(Context c) {
mContext = c;
}
public int getCount() {
return count;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = null;
for(String bitmapFileName : fileNames)
{
if (convertView == null)
{ // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
Bitmap bmp = BitmapFactory.decodeFile(dir.getPath() + "/" + bitmapFileName);
System.out.println(dir);
imageView.setImageBitmap(bmp);
}else
{
imageView = (ImageView) convertView;
}
}
return imageView;
}
the app is taking too much time and it is displaying only one image
this is my activity class
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImAdapterh(this));}

The path to the folder is "/sdcard/images/".
No, it is not, at least not for most devices. Never hard-code paths in Android. Always use Environment.getExternalStorageDirectory() to get the root of external storage.
i tried with this code,the app is taking too much time to load and it is displaying only one image.
Of course. There is very little correct in what you have done here.
The biggest problem is that your getView() loads every image into the same ImageView, for each and every row returned by your Adapter. Presumably, you should be only loading one image into the ImageView for a given row.
Your next-biggest problem is that you are doing disk I/O on the main application thread.

To get images from any specific directory. Use the following code
public void searchImageFromSpecificDirectory() {
String path = null;
String uri = MediaStore.Images.Media.DATA;
// if GetImageFromThisDirectory is the name of the directory from which image will be retrieved
String condition = uri + " like '%/GetImageFromThisDirectory/%'";
String[] projection = { uri, MediaStore.Images.Media.DATE_ADDED,
MediaStore.Images.Media.SIZE };
Vector additionalFiles = null;
try {
if (additionalFiles == null) {
additionalFiles = new Vector<String>();
}
Cursor cursor = managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection,
condition, null, null);
if (cursor != null) {
boolean isDataPresent = cursor.moveToFirst();
if (isDataPresent) {
do {
path = cursor.getString(cursor.getColumnIndex(uri));
System.out.println("...path..."+path);
additionalFiles.add(path);
}while(cursor.moveToNext());
}
if (cursor != null) {
cursor.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

Related

Album art is not displaying correct when I use AsyncTask class

When I display album art directly in my music app, it hangs. In stackoverflow, someone suggested me to implemented AsyncTask. So, I implemented AsyncTask to make my app faster. Right now, my app is not hanging but it is not displaying correct album art. And album arts are random means changing frequently when I scroll my listview.
Please help me.
Here is AsyncTask class :
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private int data = 0;
private long l;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
public BitmapWorkerTask(ImageView imageView, long l) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
this.l = l;
}
// Decode image in background.
#Override
protected Bitmap doInBackground(Integer... params) {
//Bitmap art = getAlbumart(songlist.this, l);
Context context = songlist.this;
Bitmap bm = null;
BitmapFactory.Options options = new BitmapFactory.Options();
try {
final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
Uri uri = ContentUris.withAppendedId(sArtworkUri, l);
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
if (pfd != null) {
FileDescriptor fd = pfd.getFileDescriptor();
bm = BitmapFactory.decodeFileDescriptor(fd, null, options);
pfd = null;
fd = null;
}
} catch (Error ee) {
} catch (Exception e) {
}
return bm;
}
// Once complete, see if ImageView is still around and set bitmap.
#Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (bitmap != null) {
iv_art.setImageBitmap(bitmap);
} else {
iv_art.setImageResource(R.mipmap.app_splash_screen_icon);
}
}
}
}
My class which displays song in the listview :
public class MediaCursorAdapter extends SimpleCursorAdapter {
String backgroundColor = "white";
String someOtherBackgroundColor = "#FAFAFA";
public MediaCursorAdapter(Context context, int layout, Cursor c) {
super(context, layout, c,
new String[]{MediaStore.MediaColumns.DISPLAY_NAME, MediaStore.MediaColumns.TITLE, MediaStore.Audio.AudioColumns.DURATION, MediaStore.Audio.Media.ALBUM_ID},
new int[]{R.id.displayname, R.id.title, R.id.duration, R.id.iv_art});
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
if (cursor.getPosition() % 2 == 0) {
view.setBackgroundColor(
Color.parseColor(backgroundColor));
} else {
view.setBackgroundColor(
Color.parseColor(someOtherBackgroundColor));
}
TextView title = (TextView) view.findViewById(R.id.title);
TextView name = (TextView) view.findViewById(R.id.displayname);
TextView duration = (TextView) view.findViewById(R.id.duration);
iv_art = (ImageView) view.findViewById(R.id.iv_art);
String a = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
l = Long.parseLong(a);
bwc = new BitmapWorkerTask(iv_art,l);
bwc.execute();
long durationInMs = Long.parseLong(cursor.getString(
cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION)));
name.setText(cursor.getString(
cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)));
title.setText(cursor.getString(
cursor.getColumnIndex(MediaStore.MediaColumns.TITLE)));
Utility d = new Utility();
String durationInMin = d.convertDuration(durationInMs);
duration.setText("" + durationInMin);
view.setTag(cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.songlist_listitem, parent, false);
bindView(v, context, cursor);
return v;
}
}
Its because of row reordering. The image view you want to load it into when you start a fetch is not necessarily where you want to load it at the end. The weak reference isn't helping because the view isn't being destroyed, its just not the right one anymore.
Instead of loading the data directly into the view, store it in a cache, then call notifyDataSetChanged. When you bind the row, check and see if the image is int he cache. If so, use it. If not, send the request. That will fix the majority of the issues you see, and prevent OOM errors (you can put a max memory usage on the cache).
Or use a library that does all this for you, like Volley.

Make adapter more efficient

I tried to make a custom Adapter and I made it functionall maybe not the best way and may be not the intelligentes Way so I ask here what I can do to make this a little more efficient
public class MovieDataAdapter extends BaseAdapter implements FetchImage.AsyncResponse {
private Context mContext;
public MovieDataAdapter(Context context) {
mContext = context;
}
#Override
public int getCount() { // get coutn Method
SQLiteDatabase db = new MvDBHelper(mContext).getReadableDatabase();
Cursor cur = db.query(MovieContract.MovieEntry.TABLE_NAME, null, null, null, null, null, null);
return cur.getCount();
}
#Override
public Object getItem(int position) {
return null;
}//Not needed at the moment
#Override
public long getItemId(int position) {
return 0;
}// Not needed at the moment
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ImageView imageview;
if (convertView != null) {
imageview = (ImageView) convertView; //if used view just use ist again
} else {//if new view set the fitting parameters
imageview = new ImageView(mContext);
imageview.setLayoutParams(new GridView.LayoutParams(getw('w'), getw('h')));
imageview.setScaleType(ImageView.ScaleType.FIT_XY);
}
SQLiteDatabase picturedb = new MvDBHelper(mContext).getReadableDatabase();
Cursor cur = picturedb.query(MovieContract.MovieEntry.TABLE_NAME,
null, null, null, null, null, null
);//get the entries from the db
if (cur != null && cur.moveToFirst()) {
cur.moveToPosition(position); // move to the appropriate position
//defining nessesary Variables
int index_PosterPath = cur.getColumnIndex(MovieContract.MovieEntry.COL_POSTERPATH);
int index_FilePath = cur.getColumnIndex(MovieContract.MovieEntry.COL_FILE);
int index_ortTitel = cur.getColumnIndex(MovieContract.MovieEntry.COL_ORTITEL);
final String Filename = cur.getString(index_ortTitel) + ".jpg";
final String selection = MovieContract.MovieEntry.COL_ORTITEL + " = ?";
final String[] where = {cur.getString(index_ortTitel)};
picturedb.close();// db not needed so is closed
if (cur.isNull(index_FilePath)) {//if file not already saved in the storage save it there
FetchImage getImage = new FetchImage(mContext, new FetchImage.AsyncResponse() {
#Override
public void processfinished(Bitmap output) { // get the image as an Bitmap in asynchronus task throug interface callback
FileOutputStream fos = null;
try {
fos = mContext.openFileOutput(Filename, Context.MODE_PRIVATE);
if (fos != null)
output.compress(Bitmap.CompressFormat.PNG, 100, fos); //put bitmap in file
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
ContentValues values = new ContentValues();
values.put(MovieContract.MovieEntry.COL_FILE, Filename);
SQLiteDatabase picwr = new MvDBHelper(mContext).getWritableDatabase();
int updated = picwr.update(MovieContract.MovieEntry.TABLE_NAME, values, selection, where);
//put the filname in the db for later use
picwr.close();
}
BitmapDrawable draw = new BitmapDrawable(mContext.getResources(), output);
Drawable gridimag = draw;
imageview.setImageDrawable(gridimag); // set the drawable as an image
}
});
String[] ptg = {cur.getString(index_PosterPath)};
getImage.execute(ptg);
} else { // if pic already saved in the internal storage get it from there
FileInputStream fis = null;
try {
fis = mContext.openFileInput(Filename);
Bitmap pic = BitmapFactory.decodeStream(fis);
BitmapDrawable draw = new BitmapDrawable(mContext.getResources(), pic);
Drawable gridimag = draw;
imageview.setImageDrawable(gridimag);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
cur.close();
}
return imageview;
}
public int getw(char c) {
int DisplayWidth = mContext.getResources().getDisplayMetrics().widthPixels;
if (c == 'w') {
return (int) (DisplayWidth / 2);
} else {
return DisplayWidth;
}
}
public static float convertDpToPixel(float dp, Context context) {
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
return px;
}
#Override
public void processfinished(Bitmap output) {
}
}
Would be happy about every help I can get even if it's a complet new Way because at the moment the grid view does not work fluently
You should avoid close cursor each time you draw a cell. You can close it only when you done with your activity.
Also you need to avoid using cur.moveToFirst(). Because you are already moving your cursor to given position, why should i moving it first before?
Another trick to use a image loader library (Picasso is one of the best) to load it async and faster. It also handles to stop threads if view is not shown. More optimized.
You dont need to find indexs of coloumn each time you want a new cell. Find them once, use them everytime :)
Also you can use CursorAdapter class to implement it way better :)

Contact Image in listview is repeating when use a Baseadapter

I am building an application where I am storing all contact data in my sqlite database and populating that data in listview.
In the process the contact images are repeating and is displayed without any ordering.
The adapter:
private class ContactAdapter extends SimpleCursorAdapter
{
//Context context;
ArrayList<HashMap<String, String>> data;
private Cursor c;
private Context context;
LayoutInflater inflater;
public ContactAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;
inflater = LayoutInflater.from(this.context);
}
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolderContact viewHolder;
//viewHolder = new ViewHolderContact();
if(convertView==null)
{
viewHolder = new ViewHolderContact();
convertView = inflater.inflate(R.layout.layout_contactlist, null);
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.ivimage);
viewHolder.imgNext = (ImageView) convertView.findViewById(R.id.imgnext);
viewHolder.textView_Name = (TextView)convertView .findViewById(R.id.txtname);
// view.imgad.setScaleType(ImageView.ScaleType.FIT_XY);
/*view.imgad.setScaleType(ImageView.ScaleType.FIT_XY);
//view.imgad.setPadding(0,10,0,0);
//view.imgad.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,100));
//LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,90);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,90);
lp.setMargins(0,20,0,0);
view.imgad.setLayoutParams(lp);
*/
convertView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolderContact)convertView.getTag();
}
this.c.moveToPosition(position);
String contactid = this.c.getString(this.c.getColumnIndex("_id"));
String contactname = this.c.getString(this.c.getColumnIndex("contactname"));
String contactnumber = this.c.getString(this.c.getColumnIndex("contactnumber"));
String contactimage= this.c.getString(this.c.getColumnIndex("contactimage"));
String isInstalled= this.c.getString(this.c.getColumnIndex("isInstalled"));
//System.out.println("Isinstalled--->"+isInstalled);
if(isInstalled.equals("Y"))
{
viewHolder.imgNext.setVisibility(View.GONE);
}
if (contactimage == null || contactimage.equals("")) {
if (Build.VERSION.SDK_INT >= 16) {
viewHolder.imageView.setBackground(getResources().getDrawable(R.drawable.ic_launcher));
}
else {
viewHolder.imageView.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_launcher));
}
// If there is no image in the database "NA" is stored instead of a blob
// test if there more than 3 chars "NA" + a terminating char if more than
// there is an image otherwise load the default
} //iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
else{
try {
Bitmap bmp=getContactBitmapFromURI(ContactList.this,Uri.parse(contactimage));
Bitmap round=getRoundedShape(bmp);
viewHolder.imageView.setImageBitmap(round);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
viewHolder.textView_Name.setText(contactname);
return convertView;
}
class ViewHolderContact {
TextView textView_Name;
ImageView imageView,imgNext;
}
}
c is the cursor instance
The method getContactBitmapFromURI(Context context, Uri uri)
public static Bitmap getContactBitmapFromURI(Context context, Uri uri) throws FileNotFoundException {
InputStream input = context.getContentResolver().openInputStream(uri);
if (input == null) {
return null;
}
return BitmapFactory.decodeStream(input);
}
Output:
When I scroll then the output becomes:
As you can see that the image is not properly displayed.They are repeating or/and disappearing.Please help.
Possibly this is the case of Image caching save your Image in a cache after decode it into Bitmap. Please go through the url to how to cache Image : http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
Listview reuse views. I think the problem is in the cursor. Maybe you can try setting the data first at the method getItem(). You can also try by doing notifyDataChanged when reached a certain position, if images change then is going to be a good point to start of.
I think thats because of your if else part . In first case you are setting background of image and in second case you are setting src of image . The seImageBitmap() method set the bitmap as src . Change one of the case . Use same in both cases .So i suggest Use Circle image view for getting rounded image and use UILoader or Picasso
to load the images . In that way you will get rid of caching and outofmemory error too ..
You can get image url fro uri like this
private String getPathFromUri(Uri uri) {
String url = null;
Cursor cursor = getContentResolver().query(uri, new String[] { android.provider.MediaStore.Images.Media.DATA }, null, null, null);
if (cursor.moveToFirst()) {
url = cursor.getString(0);
}
return url;
}

Images from server does not show in listview

Hello I am using listview and display images from server into it.
But the problem is that all loaded images are displayed in last item one by one instead display on respective position.
please help me to display that images in respective position
public class Offer_adapter extends ArrayAdapter<String> {
Context context1;
String[] offer_title;
String[] offerimg1;
String[] mrp;
String[] offerprice;
String[] you_save;
String[] imgURLArray;
Bitmap bitmap;
ImageView offerimg;
int a;
LayoutInflater inflater1;
public Offer_adapter(Context context1, String[] offer_title, String[] offerimg1, String[] mrp, String[] you_save, String[] offerprice) {
super(context1, R.id.offer_list, offer_title);
this.context1 = context1;
this.offer_title = offer_title;
this.offerimg1 = offerimg1;
this.mrp = mrp;
this.offerprice = offerprice;
this.you_save = you_save;
}
private static class ViewHolder {
String offerimg;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
inflater1 = (LayoutInflater) context1.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater1.inflate(R.layout.offer_list, null);
viewHolder = new ViewHolder();
}
android.util.Log.v("abhi", "" + position);
imgURLArray = new String[position + 1];
for (int i = 0; i <= position; i++) {
android.util.Log.v("abhijit", "" + position);
imgURLArray[i] = "http://www.surun.co/preost/mod_offer/images/" + offerimg1[position];
android.util.Log.v("abhi", "" + imgURLArray[position]);
}
a=position;
viewHolder = (ViewHolder) convertView.getTag();
TextView offertitle = (TextView) convertView.findViewById(R.id.ofrtitle);
TextView offermrp = (TextView) convertView.findViewById(R.id.offeroriginal);
offermrp.setPaintFlags(offermrp.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
TextView offersave = (TextView) convertView.findViewById(R.id.saveoffer);
TextView ofrprice = (TextView) convertView.findViewById(R.id.priceoffer);
offerimg = (ImageView) convertView.findViewById(R.id.ofr_img);
offertitle.setText(offer_title[position]);
offermrp.setText("Original Price: \u20B9" + mrp[position]);
offersave.setText("You Save: \u20B9" + you_save[position]);
ofrprice.setText("Offer Price: \u20B9" + offerprice[position]);
// Bitmap imageBitmap = null;
new DownloadAsyncTask().execute(imgURLArray[position]);
Log.v("abhi","async");
return convertView;
}
private class DownloadAsyncTask extends AsyncTask<String, String, Bitmap> {
protected Bitmap doInBackground(String... args) {
try {
Log.v("abhi","in do background");
bitmap = BitmapFactory.decodeStream((InputStream) new URL(args[0]).getContent());
bitmap = Bitmap.createScaledBitmap(bitmap, 270, 375, true);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (bitmap !=null) {
offerimg.setImageBitmap(bitmap);
} else {
offerimg.setImageResource(R.drawable.nooffer);
}
}
}
}
All images are shown in last item one after another. I just want to show it on respective position.
you should use lazyloading instead of downloading image as bitmap.
Bitmap will create problem sometime or will give you outofmemory error in some devices
There are lots of image loading library available for android.
Have a look at these
https://github.com/square/picasso
https://github.com/nostra13/Android-Universal-Image-Loader
https://code.google.com/p/android-query/wiki/ImageLoading
https://android.googlesource.com/platform/frameworks/volley
https://github.com/koush/UrlImageViewHelper
https://github.com/novoda/image-loader

Album Art Drawable Not Showing Up in ListView [Android]

I have been trying to figure this out for days, but can't seem to find the solution.
The problem is that even after getting the album art bitmap from MediaStore, and converting it to a drawable, it is assigned to an ImageView in a custom ListView layout via HashMap (String, Object), but finally after running on actual device and emulator, no album art is shown.
No LogCat error either. The ImageView of the custom listview layout does not show the album art.
public class AllSongs extends Fragment
{
Bitmap bitmap = null;
BitmapDrawable drawable = null;
private ArrayList<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();
private HashMap<String, Object> item;
private SimpleAdapter sa;
private ListView listview;
...
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
...
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute("500");
}
private class AsyncTaskRunner extends AsyncTask<String, String, String>
{
#Override
protected String doInBackground(String... params) {
getAllMusicFiles();
return "Done!";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
listview.setAdapter(sa); //Set all the file in the list.
}
}
private void getAllMusicFiles() {
// TODO Auto-generated method stub
//Some audio may be explicitly marked as not being music
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
String[] projection = {
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID
};
Cursor cursor = getActivity().getApplicationContext().getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
null,
null);
while(cursor.moveToNext()){
item = new HashMap<String,Object>();
String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, albumId);
ContentResolver res = context.getContentResolver();
InputStream in;
try { // Yes, the album art has been found. I am sure of this.
if(bitmap != null)
{
bitmap.recycle();
bitmap = null;
if(drawable != null)
{
drawable = null;
}
}
in = res.openInputStream(albumArtUri);
bitmap = BitmapFactory.decodeStream(in);
drawable = new BitmapDrawable(getResources(), bitmap);
} catch (FileNotFoundException e) { // Album not found so set default album art
e.printStackTrace();
drawable = (BitmapDrawable) getActivity().getResources().getDrawable(R.drawable.default_albumart);
}
item.put("icon", drawable);
item.put("title", title);
item.put("artist", artist);
list.add(item);
if(cursor.isLast())
{
sa = new SimpleAdapter(getActivity(), list,
R.layout.custom_listview_layout,
new String[] {"icon", "title","artist" },
new int[] {R.id.icon,R.id.title, R.id.artist});
}
}
}
I have detected that the drawable may be the one causing the image to not be shown because if I replace -
item.put("icon", drawable);
with -
item.put("icon", R.drawable.default_albumart);
it shows the default album art.
Any idea what's causing this?
It's your adapter implementation is causing the problems, not the Drawable.
Look at these two lines of code:
item.put("icon", drawable) - this puts a Drawable object to your hashmap
item.put("icon", R.drawable.default_albumart) - this puts an int value to your map, but as map only works with objects, it is autoboxed before being put there
Thus, the problem is that your adapter works fine with integer identifiers of drawables, but not the drawables themselves. These are the constraints of SimpleAdapter
To solve this issue I would suggest you to implement your custom CursorAdapter. Its implementation is simply straightforward, and will save you from unnecessary steps, such as creating unnecessary lists, hashmaps etc, wasting app memory.
Feel free to ask anything else in comments, good luck!
The answer was given correctly by Drew but here is how it was finally implemented. Here are the changes -
private void getAllMusicFiles() {
// TODO Auto-generated method stub
//Some audio may be explicitly marked as not being music
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
String[] projection = {
MediaStore.Audio.Media._ID, // this is required acc to documentation
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID
};
cursor = getActivity().getApplicationContext().getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
null,
null);
getActivity().startManagingCursor(cursor);
listview.setAdapter(new CustomCursorAdapter(context, cursor));
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
if(cursor != null)
{
getActivity().stopManagingCursor(cursor);
cursor.close();
}
super.onDestroy();
}
removed the AsyncTask as it wasn't here required anymore.
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
...
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute("500");
}
CustomCursorAdapter.java -
public class CustomCursorAdapter extends CursorAdapter {
#SuppressWarnings("deprecation")
public CustomCursorAdapter(Context context, Cursor c) {
super(context, c);
// TODO Auto-generated constructor stub
}
private Bitmap bitmap = null;
private BitmapDrawable drawable = null;
#Override
public void bindView(View view, Context context, Cursor cursor) {
// TODO Auto-generated method stub
TextView title1 = (TextView) view.findViewById(R.id.title);
TextView artist1 = (TextView) view.findViewById(R.id.artist);
ImageView album1 = (ImageView) view.findViewById(R.id.icon);
String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
StringBuilder titleBuild = new StringBuilder();
titleBuild.append(title);
if(titleBuild.length() > 35)
{
titleBuild.setLength(32);
title = titleBuild.toString()+"...";
}
else
{
title = titleBuild.toString();
}
StringBuilder artistBuild = new StringBuilder();
artistBuild.append(artist);
if(artistBuild.length() > 35)
{
artistBuild.setLength(32);
artist = artistBuild.toString()+"...";
}
else
{
artist = artistBuild.toString();
}
final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, albumId);
ContentResolver res = context.getContentResolver();
InputStream in;
try {
if(bitmap != null)
{
bitmap = null;
if(drawable != null)
{
drawable = null;
}
}
in = res.openInputStream(albumArtUri);
bitmap = BitmapFactory.decodeStream(in);
// bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), albumArtUri);
drawable = new BitmapDrawable(context.getResources(), bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
drawable = (BitmapDrawable) context.getResources().getDrawable(R.drawable.default_albumart);
}
album1.setImageDrawable(drawable);
title1.setText(title);
artist1.setText(artist);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
return inflater.inflate(R.layout.custom_listview_layout, parent, false);
}
}

Categories

Resources