Android : Alphabet Indexer Crashing App

on Friday, January 30, 2015


Hello I Have a problem with my Indexer. So basically its a ListView That displays songs and an Alphabet Indexer that shows the first letter of the song title.Now the problem is that "sometimes" the app crashes and the log says that the indexer tried to access a cursor after it closed. So Any Help Would Be Great.


SongFragment :



public class SongFragment extends Fragment implementsLoaderManager.LoaderCallbacks<Cursor>,OnItemClickListener{
String Song;
Cursor cursor;
public static ListView songList;
TextView songNumb;
EditText search;

private AlphabetIndexer mAlphaIndexer;
SongAdapter mAdapter;
private String mPlaylist;
public static String value;


int music_column_index;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_song, container, false);
songList = (ListView) myFragmentView.findViewById(R.id.songlist);
songNumb = (TextView) myFragmentView.findViewById(R.id.songnumb);






return myFragmentView;
}


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

boolean mEditMode = false;
//Log.i("@@@", "starting query");
mAdapter = new SongAdapter(
getActivity(), // need to use application context to avoid leaks
this,
mEditMode ? R.layout.rowlayout : R.layout.rowlayout,
null, // cursor
new String[] {},
new int[] {},
"nowplaying".equals(mPlaylist),
mPlaylist != null &&
!(mPlaylist.equals("podcasts") || mPlaylist.equals("recentlyadded")));



songList.setAdapter(mAdapter);
songList.setFastScrollEnabled(true);


songList.setScrollingCacheEnabled(true);
getLoaderManager().initLoader(0, null, this);
songList.setOnItemClickListener(this);


}








@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String select = null;
final StringBuilder mSelection = new StringBuilder();
mSelection.append(AudioColumns.IS_MUSIC + "=1");
mSelection.append(" AND " + AudioColumns.TITLE + " != ''");
return new CursorLoader(getActivity(), MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[] {
/* 0 */
BaseColumns._ID,
/* 1 */
AudioColumns.TITLE,
/* 2 */
AudioColumns.ARTIST,
/* 3 */
AudioColumns.ALBUM,
/* 4 */
AudioColumns.DURATION,
/*5*/
AudioColumns.ALBUM_ID
}, mSelection.toString(), null,
AudioColumns.TITLE);
}





@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
int songh = mAdapter.getCount();
String sonnum = String.valueOf(songh);
songNumb.setText(sonnum);
}



@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}


@Override
public void onItemClick(final AdapterView<?> parent, final View view, final int position,
final long id) {

Cursor cursor = Utils.makeSongCursor(getActivity());
final long[] list = Utils.getSongListForCursor(cursor);
Utils.playAll(getActivity(), list, position, false);
cursor.close();
cursor = null;

}


}


SongAdapter :



public class SongAdapter extends SimpleCursorAdapter implements SectionIndexer {
AlphabetIndexer mAlphabetIndexer;
String title;
String album;
String artist;
int titleindexer;
int song;



int mAudioId;
long albumId;

public long duration;

static Cursor cursor;
Context context;


String filename;
int data;


private final LayoutInflater mInflater;

public SongAdapter(Context context, SongFragment songFragment,
int layout, Cursor cursor, String[] from, int[] to,
boolean isnowplaying, boolean disablenowplayingindicator) {
super(context, layout, cursor, from, to);

mInflater=LayoutInflater.from(context);





}





public void getColumnIndices(Cursor cursor) {
filename = cursor.getString(data);


try {
mAudioId = cursor.getColumnIndexOrThrow(
MediaStore.Audio.Playlists.Members.AUDIO_ID);
data = cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
} catch (IllegalArgumentException ex) {
mAudioId = cursor.getColumnIndexOrThrow(BaseColumns._ID);
}

if (mAlphabetIndexer != null) {
mAlphabetIndexer.setCursor(cursor);
}



}



@Override
public void bindView(View view, Context context, Cursor cursor) {

mAlphabetIndexer = new MusicAlphabetIndexer(cursor, titleindexer, "\u0020ABCDEFGHIJKLMNOPQRSTUVWXYZ");
titleindexer = cursor.getColumnIndexOrThrow(AudioColumns.TITLE);
song =cursor.getColumnIndexOrThrow(AudioColumns._ID);
title = cursor.getString(cursor.getColumnIndexOrThrow(AudioColumns.TITLE));
artist = cursor.getString(cursor.getColumnIndexOrThrow(AudioColumns.ARTIST));
album = cursor.getString(cursor.getColumnIndexOrThrow(AudioColumns.ALBUM));
duration = cursor.getLong(cursor.getColumnIndexOrThrow(AudioColumns.DURATION));
albumId = cursor.getLong(cursor.getColumnIndexOrThrow(AudioColumns.ALBUM_ID));

ViewHolder holder = (ViewHolder) view.getTag();
if (holder == null) {
holder = new ViewHolder();
holder.songTitle = (TextView) view.findViewById(R.id.titlelist);
holder.duration = (TextView) view.findViewById(R.id.durationlist);
holder.artistName = (TextView) view.findViewById(R.id.artistlist);
holder.coverAlbum = (ImageView)view.findViewById(R.id.iconlist);
}view.setTag(holder);








StringBuilder titleBuild = new StringBuilder();
titleBuild.append(title);
titleBuild.setCharAt(0, Character.toUpperCase(titleBuild.charAt(0)));
if(titleBuild.length() > 35)
{
titleBuild.setLength(32);
title = titleBuild.toString()+"...";
}

StringBuilder artistBuild = new StringBuilder();
artistBuild.append(artist);
if(artistBuild.length() > 35)
{
artistBuild.setLength(32);
artist = artistBuild.toString()+"...";
}


final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, albumId);

holder.coverAlbum.setBackgroundResource(R.drawable.default_artwork);





Picasso.with(context).load(albumArtUri).
into(holder.coverAlbum);



holder.duration.setText(Utils.makeTimeString(context,duration / 1000));
holder.songTitle.setText(title);
holder.artistName.setText(artist);

}

static class ViewHolder {
TextView songTitle;
TextView duration;
TextView artistName;
ImageView coverAlbum;

}
@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.rowlayout, parent, false);
}



@Override
public void changeCursor(Cursor cursor) {

if (cursor != SongAdapter.cursor) {
SongAdapter.cursor = cursor;
super.changeCursor(cursor);
getColumnIndices(cursor);
}
}


// SectionIndexer methods

@Override
public Object[] getSections() {
if (mAlphabetIndexer != null) {
return mAlphabetIndexer.getSections();
} else {
return new String [] { " " };
}
}

@Override
public int getPositionForSection(int section) {
if (mAlphabetIndexer != null) {
return mAlphabetIndexer.getPositionForSection(section);
}
return 0;
}

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


Log:



Process: com.ray.mimp, PID: 346
android.database.StaleDataException: Attempted to access a cursor after it has been closed.
at android.database.BulkCursorToCursorAdaptor.throwIfCursorIsClosed(BulkCursorToCursorAdaptor.java:64)
at android.database.BulkCursorToCursorAdaptor.getCount(BulkCursorToCursorAdaptor.java:70)
at android.database.CursorWrapper.getCount(CursorWrapper.java:61)
at android.widget.AlphabetIndexer.getPositionForSection(AlphabetIndexer.java:164)
at com.ray.mimp.adapters.SongAdapter.getPositionForSection(SongAdapter.java:198)
at android.widget.FastScroller.scrollTo(FastScroller.java:944)
at android.widget.FastScroller.onTouchEvent(FastScroller.java:1427)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:3767)
at android.view.View.dispatchTouchEvent(View.java:8444)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2158)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2436)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2178)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2436)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2178)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2436)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2178)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2436)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2178)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2436)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2178)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2436)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2178)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2436)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2178)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2436)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2178)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2383)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1724)
at android.app.Activity.dispatchTouchEvent(Activity.java:2764)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2332)
at android.view.View.dispatchPointerEvent(View.java:8655)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4238)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4094)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3635)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3694)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3660)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3773)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3668)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3830)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3640)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3694)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3660)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3668)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3640)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5940)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5908)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5872)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6030)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:211)
at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
at android.vie

0 comments:

Post a Comment