Reputation: 280
I am developing a music app and my app takes a lot of time to generate the list of music files(because it has to generate the bitmaps) so I searched the net and came to know about the asynctask, I was able to implement it successfully in one another problem I had (so I think I understand the logic behind it) but in this case I just cant figure a way how to do it,(
so please I need help. here is the logic behind the program
I have a class "SongDetails" which has the following elements
Bitmap icon;
String song;
String Artist;
String Album;
String Path;
I have created an arraylist of SongDetails now I have another class called getSongsFromDirectory which searches for music files, fetches album and artist info from it, and adds the each item to the ArrayList and when the list is generated it returns the list to the onCreate method.Now onCreate method sorts the list by name of the songs and then gives the list to the custom adapter which displays the result,I can't understand where I should put this async task thing...........here is the code I have used
public class FragmentSongs extends Fragment implements Serializable {
AdapterView.AdapterContextMenuInfo info;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_song, container, false);
ListView SngList = (ListView) view.findViewById(R.id.SongList);
registerForContextMenu(SngList);
//File f=new File(Environment.getExternalStorageDirectory()+"Music");
//File f=new File("/sdcard/Music");
File f=new File(Environment.getExternalStorageDirectory()+"musicz");
//File f=new File("/storage/extSdCard/My Music/");
int j=0;int i=0;
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
final ArrayList<SongDetails> Songinfo = getSongsFromDirectory(f);
FragmentSongs dv=new FragmentSongs ();
if (Songinfo.size()>0)
{
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("Fragdata",Songinfo);
dv.setArguments(bundle);
}
if (Songinfo.size()>0)
{
for( j=0; j<Songinfo.size();j++)
{
for ( i=j+1 ; i<Songinfo.size(); i++)
{
SongDetails a=Songinfo.get(i);
SongDetails b=Songinfo.get(j);
if(a.getSong().toLowerCase().compareTo(b.getSong().toLowerCase())<0)
{
Songinfo.set(i,b );
Songinfo.set(j,a);
}
}
}
SngList.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView a, View v, int position, long id) {
Intent intent = new Intent(getActivity(), NowPlaying.class);
intent.putParcelableArrayListExtra("Data1",Songinfo);
intent.putExtra("Data2",position);
startActivity(intent);
}
});
SngList.setAdapter(new CustomAdapter(Songinfo));
return view;
}
else return null;
}
public ArrayList<SongDetails> getSongsFromDirectory(File f)
{MediaMetadataRetriever mmr = new MediaMetadataRetriever();
ArrayList<SongDetails> songs = new ArrayList<SongDetails>();
Bitmap bitmap2;
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ab);
float ht_px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());
float wt_px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());
Bitmap bitmap3 = Bitmap.createScaledBitmap(bmp, (int) ht_px, (int) wt_px, true);
byte[] rawArt = null;
Bitmap art;
BitmapFactory.Options bfo=new BitmapFactory.Options();
if (!f.exists() || !f.isDirectory())
{
return songs;
}
File[] files = f.listFiles(new Mp3Filter());
for(int i=0; i<files.length; i++)
{
if (files[i].isFile())
{
mmr.setDataSource(files[i].getPath());
rawArt = mmr.getEmbeddedPicture();
SongDetails detail=new SongDetails();
if ( rawArt != null)
{
bitmap2=BitmapFactory.decodeByteArray(rawArt, 0, rawArt.length, bfo);
bitmap2 = Bitmap.createScaledBitmap(bitmap2, (int) ht_px, (int) wt_px, true);
detail.setIcon(bitmap2);
}else
{
detail.setIcon(bitmap3);
}
detail.setSong(files[i].getName());
detail.setArtist(files[i].getName());
detail.setArtist(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST));
if (mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)==null||(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)==""))
{ detail.setArtist("Unknow Artist"); }
detail.setAlbum(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM));
if (mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)==null||mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)=="")
{ detail.setAlbum("Unknow Album"); }
detail.setPath2( files[i].getPath()) ;
songs.add(detail);
}
else if (files[i].isDirectory())
{
songs.addAll(getSongsFromDirectory(files[i]));
}
} return songs;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, v, menuInfo);
info = (AdapterContextMenuInfo) menuInfo;
menu.add(Menu.NONE, v.getId(), 0, "Play");
menu.add(Menu.NONE, v.getId(), 0, "Delete");
menu.add(Menu.NONE, v.getId(), 0, "Queue Item");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
if (item.getTitle() == "Play") {
}
else if (item.getTitle() == "Delete") {
}
else if (item.getTitle() == "Queue Item") {
}
else {
return false;
}
return true;
}}
class Mp3Filter implements FileFilter
{
public boolean accept(File file)
{
return (file.isDirectory()||file.getName().endsWith(".mp3")|| file.getName().endsWith(".Mp3")||file.getName().endsWith(".wma")||file.getName().endsWith(".Wma")||file.getName().endsWith(".WMA")||file.getName().endsWith(".mp4"));
}
}
now here is the code for the adapter
public class CustomAdapter extends BaseAdapter {
private ArrayList<SongDetails> _data;
CustomAdapter (ArrayList<SongDetails> data){
_data = data;
}
public int getCount() {
return _data.size();
}
public Object getItem(int position) {
return _data.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
Context context = parent.getContext();
View v = convertView;
if (v == null) {
v = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
}
SongDetails sng = _data.get(position);
ImageView image = (ImageView) v.findViewById(R.id.icon);
ImageView image2 = (ImageView) v.findViewById(R.id.icon);
TextView SongView = (TextView)v.findViewById(R.id.Song);
TextView AlbumView = (TextView)v.findViewById(R.id.Album);
TextView ArtistView = (TextView)v.findViewById(R.id.Artist);
/*ImageLoaderConfiguration config=new ImageLoaderConfiguration.Builder(context).build();
ImageLoader imageloader=ImageLoader.getInstance();
imageloader.init(config);
imageloader.displayImage( null, image2);
*/
image.setImageBitmap(sng.icon);
image2.setBackgroundResource(sng.icLauncher);
SongView.setText(sng.song);
AlbumView.setText(sng.Album);
ArtistView.setText(sng.Artist);
return v;
}
}
Upvotes: 1
Views: 414
Reputation: 3122
i can't understand where i should put this async task thing.
The AsyncTask
should be used when you need your application to perform a long-running, and/or potentially blocking (e.g., file read) operation. The way you have it structured now, your application will seem to hang and be unresponsive because you're performing all these file reads on the main UI thread. This is where the AsyncTask
comes in. When you use this class, your "work" is done on a separate thread, so that the UI can still respond while the work is going on.
You can find plenty of examples on how to properly use this class on this site, or by searching Google, or by checking the official documentation here.
You can write a custom AsyncTask
class, instantiate it, and call its execute()
method inside your activity's onCreate()
method.
You will perform your file scans in the doInBackground()
method of your AsyncTask
and then deliver the final ArrayList
back to the adapter (e.g., by calling adapter.addAll(yourSongListArray)
) in the postExecute()
method.
Hope that helps.
Upvotes: 2