2012-05-07 3 views
11

私は、ビューファイヤーがmediastoreのアーティストを含むリストを表示します。選択されたアーティストは、そのアルバムの曲を順番に表示します。曲がクリックされると、文字列 'title'がテキストビューに入力されます。Androidカーソルエラー - 「カーソルがデータにアクセスする前にカーソルが正しく初期化されていることを確認してください」

これまでは、すべてのカーソルが正常に動作していましたが、最後のカーソルは何とか位置がずれているようです。

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. 

読み取ることができない特定の行は、アーティスト/アルバム/曲が選択されているによって異なります。logcatは私に言っている理由は、誰も私に言うことができます。コードは以下の通りです。ご助力ありがとうございます。

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); 

      } 
     } 
    } 
} 
+0

timususねえ、私の答えはあなたを助けている場合/解決問題がある場合は、その横のチェックマークをクリックしてクレジットを獲得し、問題が解決したことを他の人が知っていることを確認してください。がんばろう! – Barak

+0

バラク、下記のコメントをご覧ください。希望の結果を得るための方法を少し詳しく知りたいです。 –

+0

code ...ホラー – slinden77

答えて

22

問題は列にありません。

Couldn't read row 3, **col -1** from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 

基本的には、MediaColumns.TITLE列がカーソルに存在しないということです。それは本当です。最初のカーソル(参照しているカーソル)にはありません。あなたの他のカーソルはif内にありますので、範囲外に出て最初のものだけを残してください。

ifステートメントの他の部分と同様にカーソルを再プッシュするか、最後のifステートメントから取得したカーソルを保持する方法を見つけることができます。

EDIT

これは、カーソルクラス変数にし、修正するために非常に簡単です。また、私は "カーソル"を再使用し続けません。個々のものや説明的なものにラベルを付けると、コードの可読性を維持するのに役立ちます。私はこれのようにするかもしれません:

public class MusicFlipper extends Activity implements OnItemClickListener { 
    private Cursor artistCursor; 
    private Cursor albumCursor; 

あなたはあなたのようにそれらを呼び出すが、個々の名前を使用します。

albumCursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
       columns, where, whereVal, orderBy); 

あなたはそれはあなたがしたい最後の部分になるようクラス全体を通じて利用できるようになりますクラス変数として宣言しているので:

if (currentList.equals("Songs")) { 
    if (albumCursor.moveToPosition(position)) { 
      String title = albumCursor.getString(albumCursor.getColumnIndex(MediaColumns.TITLE)); 
      TextView myTextView = (TextView) findViewById(R.id.title); 
      myTextView.setText(title); 
    } 
} 
+0

バラクにお返事ありがとうございます。私はこのアイデアを持って遊んできましたが、何もできないようです。私は前のステートメントとまったく同じようにカーソルをまっすぐに引き出しましたが、同じエラーが発生します。私はそれが 'ポジション'が変わったためだと思っています。おそらくこれを達成する方法を私に見せてもらえますか?ありがとう。 –

+0

私の答えを更新しました。 – Barak

+0

Thanks heaps Barak、大変感謝しています。 –

関連する問題