2012-05-07 5 views
11

viewflipper가 mediastore의 아티스트가 포함 된 목록을 보여주는 활동이 있습니다.이 목록에는 onitem click을 통해 앨범 목록이 선택된 아티스트는 해당 앨범의 노래를 차례로 표시합니다. 노래를 클릭하면 텍스트 뷰에 '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. 

아티스트/앨범/노래가 선택에 따라 달라집니다 읽을 수없는 특정 행. 코드는 다음과 같습니다. 당신의 도움을 주셔서 대단히 감사합니다.

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

Barak, 아래의 설명을 참조하십시오. 원하는 결과를 얻는 방법에 대한 정보를 조금 더 갖고 싶습니다. –

+0

code ... horror – 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 문에서 가져온 커서를 유지할 수있는 방법을 찾을 수도 있습니다.

편집 그것은 해결하기 위해 아주 간단

, 커서 클래스 변수합니다. 또한, 나는 "커서"를 다시 사용하지 않을 것입니다. 개별적으로 그리고 서술 적으로 레이블을 지정하면 코드에서 가독성을 유지하는 데 도움이됩니다. 나는 이것을 다음과 같이 할 수 있습니다 :

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, 많이 감사합니다. –

관련 문제