Why do contacts repeat in listview? - android

I was following an example off of the android site. I am new to android development. The problem I am having is that my contacts repeat over and over, about 6 times. Can anyone figure out why? I feel it may have to do with my imports as they were not included with the example but I am not certain. Also note that I did not create an xml file for the listview under res.
Thanks,
ListViewLoader.java
package com.example.contactlist;
import android.app.ListActivity;
import android.app.LoaderManager;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
//from http://developer.android.com/guide/topics/ui/layout/listview.html
public class ListViewLoader extends ListActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
// This is the Adapter being used to display the list's data
SimpleCursorAdapter mAdapter;
// These are the Contacts rows that we will retrieve
static final String[] PROJECTION = new String[] {
ContactsContract.Data._ID, ContactsContract.Data.DISPLAY_NAME };
// This is the select criteria
static final String SELECTION = "((" + ContactsContract.Data.DISPLAY_NAME
+ " NOTNULL) AND (" + ContactsContract.Data.DISPLAY_NAME
+ " != '' ))";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// For the cursor adapter, specify which columns go into which views
String[] fromColumns = { ContactsContract.Data.DISPLAY_NAME };
int[] toViews = { android.R.id.text1 }; // The TextView in
// simple_list_item_1
// Create an empty adapter we will use to display the loaded data.
// We pass null for the cursor, then update it in onLoadFinished()
mAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1, null, fromColumns,
toViews, 0);
setListAdapter(mAdapter);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
}
// Called when a new Loader needs to be created
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
return new CursorLoader(this, ContactsContract.Data.CONTENT_URI,
PROJECTION, SELECTION, null, null);
}
// Called when a previously created loader has finished loading
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mAdapter.swapCursor(data);
}
// Called when a previously created loader is reset, making the data
// unavailable
public void onLoaderReset(Loader<Cursor> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
mAdapter.swapCursor(null);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Do something when a list item is clicked
}
}

I've figured out the solution. I needed to query the Contacts table instead of the Data table. Apparently the Data table has duplicates. I've pasted a portion of my updated code.
public class ListViewLoader extends ListActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
// This is the Adapter being used to display the list's data
SimpleCursorAdapter mAdapter;
// These are the Contacts rows that we will retrieve
static final String[] PROJECTION = new String[] {
ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME };
// This is the select criteria
static final String SELECTION = "((" + ContactsContract.Contacts.DISPLAY_NAME
+ " NOTNULL) AND (" + ContactsContract.Contacts.DISPLAY_NAME
+ " != '' ))";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// For the cursor adapter, specify which columns go into which views
String[] fromColumns = { ContactsContract.Contacts.DISPLAY_NAME };
int[] toViews = { android.R.id.text1 }; // The TextView in
// simple_list_item_1
// Create an empty adapter we will use to display the loaded data.
// We pass null for the cursor, then update it in onLoadFinished()
mAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1, null, fromColumns,
toViews, 0);
setListAdapter(mAdapter);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
System.out.println("oncreate (Bundle)");
}
// Called when a new Loader needs to be created
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
System.out.println("oncreateloader");
System.out.println(PROJECTION);
System.out.println(SELECTION);
return new CursorLoader(this, ContactsContract.Contacts.CONTENT_URI,
PROJECTION, SELECTION, null, ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}

Try changing
mAdapter.swapCursor(data)
to
mAdapter.changeCursor(cursor)
and
mAdapter.swapCursor(null)
to
mAdapter.changeCursor(null)

Related

How to display more than one column data from the same table on ListView?

My ListView currently is able to display only one column data. I want it to display two column data.
Here is the code for my ListView:
public class ProjectExplorer extends ListActivity {
private projectdatabase database;
protected Cursor cursor;
protected ListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = new projectdatabase(ProjectExplorer.this);
getinfo();
}
private void getinfo() {
database.open();
cursor = database.getDataforDisplay();
adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, new String[] {"project_name"}, new int[] { android.R.id.text1 }, 0);
setListAdapter(adapter);
}
#Override
public void onListItemClick(ListView parent, View view, int position, long id) {
super.onListItemClick(parent, view, position, id);
Cursor c = ((SimpleCursorAdapter)parent.getAdapter()).getCursor();
c.moveToPosition(position);
// get project name here
String str_projectname= c.getString(c.getColumnIndex("project_name"));
Toast.makeText(this, str_projectname, Toast.LENGTH_LONG).show();
}
Here is the method in database class which return the cursor:
public Cursor getDataforDisplay () {
String[] columns = new String[] {KEY_ROWID, PROJECT_NAME, PROJECT_FINISH_DATE, PROJECT_DIFFICULTY, PROJECT_STATUS};
Cursor c = projectDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
projectDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
c.moveToFirst();
return c;
}
I also want to display KEY_ROWID which is defined as _id
You can use android.R.layout.simple_list_item_2 specifying column no.2 from table from where data can be retrieved and specifies location with help of it can be displayed on Activity - android.R.id.text2
adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursor, new String[] {"project_name","column_no2"}, new int[] { android.R.id.text1, andriod.R.id.text2 }, 0);
You can also create your on custom Adapter specifying your own Listview and creating it from scratch and customized everything.
The best way to achieve this at least in my opinion is to create custom Adapter for your ListView in that case you can set your own design how single listview element should look like . Just populate some arrays using your Cursor and set them to your custom adapter.

getLoadManager().initLoader(0, null, this) does not acceptable

API level is 8
I am sure that I use the support package
i get the getLoadManager().initLoader(0, null, this) does not acceptable
my code is as below:
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
public class ListViewLoader extends ListActivity implements LoaderManager.LoaderCallbacks<Cursor>
{
// This is the Adapter being used to display the list's data
SimpleCursorAdapter mAdapter;
// These are the Contacts rows that we will retrieve
static final String[] PROJECTION = new String[] { ContactsContract.Data._ID, ContactsContract.Data.DISPLAY_NAME };
// This is the select criteria
static final String SELECTION = "((" + ContactsContract.Data.DISPLAY_NAME + " NOTNULL) AND (" + ContactsContract.Data.DISPLAY_NAME + " != '' ))";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Create a progress bar to display while the list loads
ProgressBar progressBar = new ProgressBar(this);
progressBar.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
progressBar.setIndeterminate(true);
getListView().setEmptyView(progressBar);
// Must add the progress bar to the root of the layout
ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
root.addView(progressBar);
// For the cursor adapter, specify which columns go into which views
String[] fromColumns = { ContactsContract.Data.DISPLAY_NAME };
int[] toViews = { android.R.id.text1 }; // The TextView in simple_list_item_1
// Create an empty adapter we will use to display the loaded data.
// We pass null for the cursor, then update it in onLoadFinished()
mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, null, fromColumns, toViews);
setListAdapter(mAdapter);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoadManager().initLoader(0, null, this);
}
// Called when a new Loader needs to be created
public Loader<Cursor> onCreateLoader(int id, Bundle args)
{
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
return new CursorLoader(this, ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null, null);
}
// Called when a previously created loader has finished loading
public void onLoadFinished(Loader<Cursor> loader, Cursor data)
{
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mAdapter.swapCursor(data);
}
// Called when a previously created loader is reset, making the data unavailable
public void onLoaderReset(Loader<Cursor> loader)
{
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
mAdapter.swapCursor(null);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id)
{
// Do something when a list item is clicked
}
}

Use of setListAdapter

In my application 4 fragments are attached to one activity class. In my activity class i have set the root content view using this
setContentView(R.layout.fragment_pager);
my four fragments are in seperate java files.
In one of my fragment i am displaying a list of contact for this i used
mAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, null,
new String[] {ContactsContract.Contacts.DISPLAY_NAME},
new int[] { android.R.id.text1}, 0);
setListAdapter(mAdapter);
setListShown(true);
I want to know that what is the use of setListAdapter in my case and where it put list of content given by SimpleCursorAdapter class? and how can i set the title of my fragment.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:drawable/gallery_thumb">
<TextView android:id="#+id/text"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/hello_world"/>
<!-- The frame layout is here since we will be showing either
the empty view or the list view. -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<!-- Here is the list. Since we are using a ListActivity, we
have to call it "#android:id/list" so ListActivity will
find it -->
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false"/>
<!-- Here is the view to show if the list is emtpy -->
<TextView android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="No items."/>
</FrameLayout>
</LinearLayout>
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, null,
new String[] {ContactsContract.Contacts.DISPLAY_NAME},
new int[] { android.R.id.text1}, 0);
//setListAdapter(mAdapter);
// setListShown(true);
// getLoaderManager().initLoader(0, null, this);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("Contacts");
return v;
}
My Cursor display data when i use this method and removes two methods onCreate and onCreateView
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, null,
new String[] {ContactsContract.Contacts.DISPLAY_NAME},
new int[] { android.R.id.text1}, 0);
setListAdapter(mAdapter);
setListShown(true);
getLoaderManager().initLoader(0, null, this);
}
but when i use those three methods together then my application stops unexpectedly. What can be the error when i use these three method together?
package com.keepintouch.android;
import android.os.Bundle;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import com.actionbarsherlock.app.SherlockListFragment;
public class ContactsFragment extends SherlockListFragment implements LoaderManager.LoaderCallbacks<Cursor>{
// This is the Adapter being used to display the list's data.
SimpleCursorAdapter mAdapter;
// If non-null, this is the current filter the user has provided.
String mCurFilter;
View lv;
// These are the Contacts rows that we will retrieve.
static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
};
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
public static Fragment newInstance(Context context){
ContactsFragment contactFragment = new ContactsFragment();
return contactFragment;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, null,
new String[] {ContactsContract.Contacts.DISPLAY_NAME},
new int[] { android.R.id.text1}, 0);
setListAdapter(mAdapter);
setListShown(true);
getLoaderManager().initLoader(0, null, this);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Insert desired behavior here.
Log.i("FragmentComplexList", "Item clicked: " + id);
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// This is called when a new Loader needs to be created. This
// sample only has one Loader, so we don't care about the ID.
// First, pick the base URI to use depending on whether we are
// currently filtering.
Uri baseUri;
if (mCurFilter != null) {
baseUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI,
Uri.encode(mCurFilter));
} else {
baseUri = ContactsContract.Contacts.CONTENT_URI;
}
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
String select = "((" + ContactsContract.Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+ ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ ContactsContract.Contacts.DISPLAY_NAME + " != '' ))";
return new CursorLoader(getActivity(), baseUri,
CONTACTS_SUMMARY_PROJECTION, select, null,
ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mAdapter.swapCursor(data);
// The list should now be shown.
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
public void onLoaderReset(Loader<Cursor> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
mAdapter.swapCursor(null);
}
}
If you are using the Listfragement setListAdapter set the Adapter in your default list comes with Listfragement..
if using action bar (android:targetSdkVersion="15")
ActionBar ab = this.getActionBar();
ab.setTitle(" ");
if not then
getActivity().setTitle(" "); // after onAttach called

FragmentPagerAdapter - Create dynamic content for each fragment

I have implement FragmentPagerAdapter in my app but it show only a same list of items for each fragment whenever i swipe. I am using SherlockFragmentActivity and i want to show different non static pages for each fragment whenever i swipe to next or previous fragment in fragment pager.
How can i do so ?
Have i listed a list of contacts without any title of the current fragment so that i could know that this is my contacts fragment in my fragment using this code
public class ContactsFragment extends SherlockListFragment implements LoaderManager.LoaderCallbacks<Cursor>{
// This is the Adapter being used to display the list's data.
SimpleCursorAdapter mAdapter;
// If non-null, this is the current filter the user has provided.
String mCurFilter;
public static Fragment newInstance(Context context){
ContactsFragment contactFragment = new ContactsFragment();
return contactFragment;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Give some text to display if there is no data. In a real
// application this would come from a resource.
// setEmptyText("No phone numbers");
// Create an empty adapter we will use to display the loaded data.
mAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, null,
new String[] {ContactsContract.Contacts.DISPLAY_NAME},
new int[] { android.R.id.text1}, 0);
setListAdapter(mAdapter);
// Start out with a progress indicator.
setListShown(true);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
}
#Override public void onListItemClick(ListView l, View v, int position, long id) {
// Insert desired behavior here.
Log.i("FragmentComplexList", "Item clicked: " + id);
}
// These are the Contacts rows that we will retrieve.
static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
};
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// This is called when a new Loader needs to be created. This
// sample only has one Loader, so we don't care about the ID.
// First, pick the base URI to use depending on whether we are
// currently filtering.
Uri baseUri;
if (mCurFilter != null) {
baseUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI,
Uri.encode(mCurFilter));
} else {
baseUri = ContactsContract.Contacts.CONTENT_URI;
}
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
String select = "((" + ContactsContract.Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+ ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ ContactsContract.Contacts.DISPLAY_NAME + " != '' ))";
return new CursorLoader(getActivity(), baseUri,
CONTACTS_SUMMARY_PROJECTION, select, null,
ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mAdapter.swapCursor(data);
// The list should now be shown.
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
public void onLoaderReset(Loader<Cursor> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
mAdapter.swapCursor(null);
}
}
But I want to show tile above the contact list. For this i put two more methods in my fragment class which i have listed below
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("Contacts");
return v;
}
But when i run my app " Your app stopped unexpetedly" this popup mesage is come.
Without these methods my app is working fine but without any title of fragment. Whats wrong with it?
hi you can achieve this using view pager here the exmple
you can use this in your one.xml layout
<ListView android:id="#+id/List" android:background="#00000000"
android:scrollbars="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollingCache="false"
android:fastScrollEnabled="true"
android:cacheColorHint="#color/white"
/>

Android cursor error - "make sure cursor is initialized correctly before accessing data from it..."

I've got an activity where a viewflipper shows a list containing the artists from mediastore, which onitem click display a list of albums by the chosen artist, which in turn displays the songs on that album. Once a song is clicked, it should populate a textview with the string 'title'.
Until this point, all of the cursors are working fine, but the very last one seems to get put out of position somehow. Could anyone tell me why logcat is telling me:
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.
The particular row which cannot be read varies depending on which artist/album/song is chosen. The code is as follows. Thank you very much for your help.
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);
}
}
}
}
The problem isn't in the row, it's in the column.
Couldn't read row 3, **col -1** from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
It's basically saying that your MediaColumns.TITLE column doesn't exist in the cursor. Which is true. It's not in your first cursor (the one that it is referencing). Your other cursors are all within if statements so go out of scope and leave only the first one.
You can either re-pull the cursor like you do in the other portions of the if statement, or find some way to persist the cursor you got from the last if statement.
EDIT
It's pretty simple to fix, make the cursor a class variable. Also, I wouldn't keep re-using "cursor". Label them somethign individual and descriptive, it'll help you maintain readability in your code. I might do it like this:
public class MusicFlipper extends Activity implements OnItemClickListener {
private Cursor artistCursor;
private Cursor albumCursor;
Then you call them like you were but use the individual names.
albumCursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
columns, where, whereVal, orderBy);
Since you declared it as a class variable it will be available through the whole class so in the last part you'd do:
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);
}
}

Categories

Resources