Erreur du curseur Android - "assurez-vous que le curseur est initialisé correctement avant d'y accéder ..."
J'ai une activité où une viewflipper affiche une liste contenant les artistes de mediastore, qui onitem cliquez sur afficher la liste des albums de l'artiste sélectionné, qui à son tour affiche les chansons sur cet album. Une fois qu'une chanson est cliqué, il doit remplir un textview avec la chaîne "titre".
Jusqu'à ce point, tous les curseurs fonctionnent très bien, mais la dernière semble se mettre hors de position en quelque sorte. Quelqu'un pourrait-il me dire pourquoi logcat me dit:
05-07 23:58:54.195: E/AndroidRuntime(1961): java.lang.IllegalStateException: Couldn't read row 3, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
La ligne particulière qui ne peut pas être lu varie en fonction de l'artiste/album/morceau est choisi. Le code est comme suit. Merci beaucoup pour votre aide.
package music.flipper;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AlbumColumns;
import android.provider.MediaStore.Audio.ArtistColumns;
import android.provider.MediaStore.Audio.AudioColumns;
import android.provider.MediaStore.MediaColumns;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.ViewFlipper;
public class MusicFlipper extends Activity implements OnItemClickListener {
/** Called when the activity is first created. */
ViewFlipper viewflipper;
Cursor cursor;
private String currentList = "Artist";
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.flipper);
//set the main view to flipper.
viewflipper = (ViewFlipper) findViewById(R.id.viewFlipper1);
String[] columns = {
BaseColumns._ID,
ArtistColumns.ARTIST
};
//The columns to return for each row.
cursor = managedQuery(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
columns, null, null, null);
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setOnItemClickListener(this);
//set an onitemclicklistener to the first listview in flipper
String[] displayFields = new String[] { ArtistColumns.ARTIST };
//set all the artist names to the array 'displayfields'
int[] displayViews = new int[] { R.id.rowItem };
//number of rows to display and where to bind them
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.row_item, cursor, displayFields, displayViews);
listView.setAdapter(adapter); }
//Take the display fields array, and bind to the matching display row
@SuppressWarnings("deprecation")
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
if( currentList.equals("Artist")) {
if (cursor.moveToPosition(position)) {
//once an item is clicked, move the cursor to that items position
String where = AudioColumns.ARTIST + "=?";
//Have the cursor look within the artist row?
String whereVal[] = { cursor.getString(cursor
.getColumnIndex(AlbumColumns.ARTIST)) };
//Choose the particular row with the chosen artist's name
String[] columns = {
BaseColumns._ID,
AudioColumns.ALBUM,
};
String orderBy = BaseColumns._ID;
cursor = managedQuery(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
columns, where, whereVal, orderBy);
ListView listView = (ListView) findViewById(R.id.listView2);
listView.setOnItemClickListener(this);
String[] displayFields = new String[] { AudioColumns.ALBUM };
int[] displayViews = new int[] { R.id.rowItem };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.row_item, cursor, displayFields, displayViews);
listView.setAdapter(adapter);
currentList = "Album";
viewflipper.showNext();}
} if (currentList.equals("Album")) {
if (cursor.moveToPosition(position)) {
String where = AudioColumns.ALBUM
+ "=?";
String whereVal[] = { cursor.getString(cursor
.getColumnIndex(AlbumColumns.ALBUM)) };
String[] columns = {
MediaColumns.DATA,
BaseColumns._ID,
MediaColumns.TITLE,
MediaColumns.DISPLAY_NAME,
MediaColumns.MIME_TYPE,
};
String orderBy = MediaColumns.TITLE;
cursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
columns, where, whereVal, orderBy);
ListView listView = (ListView) findViewById(R.id.listView3);
listView.setOnItemClickListener(this);
String[] displayFields = new String[] { MediaColumns.TITLE };
int[] displayViews = new int[] { R.id.rowItem };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.row_item, cursor, displayFields, displayViews);
listView.setAdapter(adapter);
currentList.equals("Songs");
viewflipper.showNext();}
} if (currentList.equals("Songs")) {
if (cursor.moveToPosition(position)) {
String title = cursor.getString(cursor.getColumnIndex(MediaColumns.TITLE));
TextView myTextView = (TextView) findViewById(R.id.title);
myTextView.setText(title);
}
}
}
}
source d'informationauteur
Vous devez vous connecter pour publier un commentaire.
Le problème n'est pas dans la ligne, c'est dans la colonne.
C'est essentiellement à dire que votre MediaColumns.Le TITRE de la colonne n'existe pas dans le curseur. Ce qui est vrai. Il n'est pas dans votre premier curseur (la référence). Vos autres curseurs sont tous dans
if
les déclarations afin de sortir de la portée et de ne laisser que la première.Vous pouvez re-tirez le curseur comme vous le faites dans les autres parties de la
if
déclaration, ou de trouver un moyen de conserver le curseur que vous avez obtenu à partir de la dernièreif
déclaration.MODIFIER
C'est assez simple à corriger, faites le curseur d'une variable de classe. Aussi, je ne voudrais pas continuer indéfiniment à l'aide de "curseur". Étiquette eux somethign individuels et descriptif, il va vous aider à maintenir la lisibilité de votre code. Je pourrais faire comme ceci:
Puis vous les appelez comme vous étiez, mais utiliser le nom de l'individu.
Depuis que vous avez déclaré comme une variable de classe qui sera disponible dans l'ensemble de la classe donc dans la dernière partie que vous souhaitez faire: