I am creating music player app and I used cursor to get songs from local storage. I successfully displayed songs along with album arts but when I scroll list it hangs. What should I do to solve this problem.
This is my cursor :
cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,MediaStore.Audio.AudioColumns.DURATION+">0", null, sortOrder);
Here is class which binds songs and album art with listview fields :
private class MediaCursorAdapter extends SimpleCursorAdapter {
String backgroundColor = "white";
String someOtherBackgroundColor = "#F5F5F5";
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});
}
public Bitmap getAlbumart(Context context, Long album_id){
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, album_id);
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;
}
#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);
ImageView iv_art = (ImageView) view.findViewById(R.id.iv_art);
String a = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
Long l = Long.parseLong(a);
Bitmap art = getAlbumart(songlist.this,l);
if(art!=null)
{
iv_art.setImageBitmap(art);
}
else
{
iv_art.setImageResource(R.mipmap.app_splash_screen_icon);
}
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.listitem, parent, false);
bindView(v, context, cursor);
return v;
}
}
Here is the code which sets adapter of listview :
mediaAdapter = new MediaCursorAdapter(this, R.layout.listitem, cursor);
lv_songlist.setAdapter(mediaAdapter);
Every time you create a new row in your ListView you load the image from the storage on the UI-Thread. As loading data (especially images) from the storage is an operation that can take a little while it will block the UI-Thread from performing any work other than loading that image for a little while. This results in the "hanging" you experience.
Best solution would be to offload the image loading onto a different Thread. You can do this either manually or using one of the wildly used Image Loading Libraries out there (Picasso, Glide, UniversalImageLoader) which can do the work for you.
Related
I'm trying to show album art with album names.
If I use MediaStore.Audio.Media.EXTERNAL_CONTENT_URI then the album names are repeated; but I am able to show album art.
And if I use MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI then album names are not repeated but no album art is shown.
How can I get unrepeated Album Names with album art (if available)?
Screenshot
Note: I created a songs list before in which song name, artist name, song duration and album arts were fetched. But I can't fetch album name and album art(either album art is fetched or album name) with same methodology in Albums tab (I have four tabs for Songs, Artists, Albums and Playlists).
Thank you for your help.
Here is the code:
Albums.java
List<Album> sampleAlbum = new ArrayList<>();
public void getAlbum() {
ContentResolver contentResolver = getActivity().getContentResolver();
Uri songUri = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
Cursor songCursor = contentResolver.query(songUri, null, null, null, null);
if (songCursor != null && songCursor.moveToFirst()) {
int songAlbum = songCursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM);
int songPath = songCursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART);
do {
Album newAlbum = new Album();
newAlbum.albumName = songCursor.getString(songAlbum);
newAlbum.pathName = songCursor.getString(songPath);
sampleAlbum.add(newAlbum);
}
while (songCursor.moveToNext());
}
}
AlbumRecyclerAdapter.java
public class AlbumRecyclerAdapter extends RecyclerView.Adapter<AlbumViewHolder> {
private List<Album> albums;
private Context context;
public AlbumRecyclerAdapter(Context context, List<Album> albums) {
this.albums = albums;
this.context = context;
}
#Override
public AlbumViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.album_recycler_item, parent, false);
return new AlbumViewHolder(view);
}
#Override
public void onBindViewHolder(AlbumViewHolder holder, final int position) {
final Album sampleAlbum = albums.get(position);
holder.album_name.setText(sampleAlbum.albumName);
try {
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(albums.get(position).pathName);
byte[] data = mmr.getEmbeddedPicture();
if (data != null) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
holder.album_image.setImageBitmap(bitmap);
holder.album_image.setAdjustViewBounds(true);
holder.album_image.setLayoutParams(new LinearLayout.LayoutParams(500, 500));
}
else {
holder.album_image.setImageResource(R.drawable.default);
holder.album_image.setAdjustViewBounds(true);
holder.album_image.setLayoutParams(new LinearLayout.LayoutParams(500, 500));
}
}
catch (Exception e) {
e.printStackTrace();
}
holder.constraintLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "Album " + sampleAlbum.albumName + "'s songs will be opened", Toast.LENGTH_LONG).show();
}
});
}
#Override
public int getItemCount() {
return albums.size();
}
}
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.
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;
}
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);
}
}
When I start my application I have a Asynctask kick off which looks for any new videos and creates the thumbnails and adds them to a database. I later use the Universal Image Loader to find and set that bitmap to the view. My problem is when I start my application for the first time all the data is loaded to the database but nothing shows up in the gridview. I don't even think the adapter gets called. However, when I start the application once all the data is loaded the gridview shows all the thumbnails and it runs smoothly.
I was wondering why this happens and what I could do to fix this problem. My code is below
AsyncTask
private class DataEntry extends AsyncTask<Void, Integer, GridviewData>{
GridviewData dataentry;
DataEntry(GridviewData gridviewdata){
this.dataentry = gridviewdata;
}
#Override
protected GridviewData doInBackground(Void... params) {
cursor.moveToFirst();
do {
String videoid = cursor.getString(columnindexid);
String videopath = cursor.getString(columnindexdata);
int result = dataentry.findVideoID(videoid);
if (result == 1){
Bitmap bmthumb = ThumbnailUtils.createVideoThumbnail(videopath, MediaStore.Video.Thumbnails.MINI_KIND);
if (bmthumb != null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmthumb.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] thumbnailBitmapBytes = stream.toByteArray();
dataentry.addVideoinfo(videoid, videopath, thumbnailBitmapBytes);
}
}
if (result == 0){
Log.i(TAG, "Cursor wasn't processed, no getcount");
}
if(result == 2){
//there is data already there
}
} while (cursor.moveToNext());
Log.i(TAG, "After dowhile loop");
cursor.close();
return dataentry;
}
}
Base Image Loader
public class SqliteImageDownloader extends BaseImageDownloader {
private static final String SCHEME_DB = "db";
private static final String DB_URI_PREFIX = SCHEME_DB + "://";
Cursor cursor;
public SqliteImageDownloader(Context context) {
super(context);
}
#Override
protected InputStream getStreamFromOtherSource(String imageUri, Object extra) throws IOException {
if (imageUri.startsWith(DB_URI_PREFIX)) {
String path = imageUri.substring(19);
cursor = entry.BitFinder(path);
byte[] imageData = cursor.getBlob(0);
return new ByteArrayInputStream(imageData);
} else {
return super.getStreamFromOtherSource(imageUri, extra);
}
}
}
Cursor Adapter
class VideoAdapter extends CursorAdapter {
Cursor curs;
Context context;
public VideoAdapter(Context context, Cursor c) {
super(context, c);
this.context = context;
this.curs = c;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) view.getTag();
String filepath = curs.getString(videopathindex);
ImageLoader.getInstance().displayImage("db://VideoandThumbs" + filepath, holder.imageview);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View eachgrid = inflater.inflate(R.layout.eachgrid, parent, false);
ViewHolder holder = new ViewHolder();
holder.imageview = (ImageView) eachgrid.findViewById(R.id.Imageview1);
eachgrid.setTag(holder);
return eachgrid;
}
}