This may turn out as a lame question, but I am a beginner and don't seem to understand the behavior of my app.
I have a SQLite data base, and a list view in the main activity.
In the list view I display the List no.(row id) and other details.
and on pressing the list item, a new activity opens up which displays the details in a textview and has 2 image buttons for delete and sync.
The app works just fine until I delete any entry.
Once I delete any entry the row id on the listview doesn't seem to update the row number. (if i delete the first row, the row on top shows 2(should be 1, as it is the new first row)).
However when I display the details of record it comes out correct. (the second item on the list show the row number 2)
Also when I press press an item in the list view whose position is same as the position i have deleted earlier the app crashes(Suppose i delete the first entry, after that whenever I click on the first Item on the list view to display it the app crashes)
Error I get on app crash :
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.aakashmaroti.fillup/com.example.aakashmaroti.fillup.DisplayDetails}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
My main activity
package com.example.aakashmaroti.fillup;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class StartScreen extends ActionBarActivity implements View.OnClickListener {
FavoriteList favList = new FavoriteList();
TextView rid,ts,sd;
ListView lv;
Context context=this;
Find db=new Find(this);
List<FavoriteList> favoriteList;
LinearLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start_screen);
Button b = (Button) findViewById(R.id.AddButton);
b.setOnClickListener(this);
lv = (ListView) findViewById(R.id.listview);
try
{
populateListViewFromDatabase();
} catch (Exception e)
{
Toast.makeText(getApplicationContext(), "Oops there has been an error "+e.toString()+"", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
showsDialog(position);
}
});
}
#Override
public void onResume()
{
super.onResume();
try
{
populateListViewFromDatabase();
} catch (Exception e)
{
Toast.makeText(getApplicationContext(), "Oops there has been an error "+e.toString()+"", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_start_screen, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
switch (v.getId())
{
case R.id.AddButton:
startActivity(new Intent(this,Form.class));
break;
default: break;
}
}
public void populateListViewFromDatabase()throws Exception
{
Find info=new Find(this);
try
{
info.open();
SimpleCursorAdapter myCursorAdapter;
myCursorAdapter = info.listUp();
lv.setAdapter(myCursorAdapter);
info.close();
} catch (SQLException e)
{
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Oops there has been an error "+e.toString()+"", Toast.LENGTH_LONG).show();
}
}
public void showsDialog(int pos)
{
pos++;
String s = "";
s += pos;
Intent i = new Intent(getApplicationContext(), DisplayDetails.class);
i.putExtra("position", s);
startActivity(i);
try
{
populateListViewFromDatabase();
} catch (Exception e)
{
e.printStackTrace();
}
}
}
The sqlite data base managing class
package com.example.aakashmaroti.fillup;
import android.app.Dialog;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Aakash Maroti on 28-Dec-14.
*/
public class Find
{
public static final String KEY_ROWID = "_id";
public static final String KEY_TIMESTAMP= "time_stamp";
public static final String KEY_IS_SYNCED = "sync";
public static final String KEY_NameOfCompany="name_of_company";
private static final String DATABASE_NAME = "FillUpFormsDB";
private static final String DATABASE_TABLE = "FillUpFormsTable";
private static final int DATABASE_VERSION = 1;
private DbHelper ourHelper;
private final Context ourContext;
private SQLiteDatabase ourDatabase;
private static class DbHelper extends SQLiteOpenHelper
{
public DbHelper(Context context)
{
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" +
KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_IS_SYNCED +" TEXT NOT NULL, " +
KEY_TIMESTAMP +" TEXT NOT NULL, " +
KEY_NameOfCompany+" TEXT NOT NULL);"
);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS "+DATABASE_TABLE);
onCreate(db);
}
}
public Find(Context c)
{
ourContext = c;
}
public Find open()throws SQLException
{
ourHelper = new DbHelper(ourContext);
ourDatabase=ourHelper.getWritableDatabase();
return this;
}
public void close()
{
ourHelper.close();
}
public long createEntry(String isSynced, String timeStamp, String nameOfCompany)
{
ContentValues cv=new ContentValues();
cv.put(KEY_IS_SYNCED,isSynced);
cv.put(KEY_TIMESTAMP,timeStamp);
cv.put(KEY_NameOfCompany,nameOfCompany);
return ourDatabase.insert(DATABASE_TABLE,null,cv);
}
public SimpleCursorAdapter listUp()
{
String columns[]=new String[]{KEY_ROWID,KEY_TIMESTAMP,KEY_IS_SYNCED};
Cursor c= ourDatabase.query(DATABASE_TABLE,columns,null,null,null,null,null);
int toViewIDs[] = new int[]{R.id.rowno,R.id.timestamp,R.id.syncdetails};
SimpleCursorAdapter CursorAdapter;
CursorAdapter = new SimpleCursorAdapter(ourContext,R.layout.design_row,c,columns,toViewIDs,0);
return CursorAdapter;
}
public String getDetails(long row)
{
String columns[]=new String[] {KEY_ROWID, KEY_IS_SYNCED, KEY_TIMESTAMP,KEY_NameOfCompany};
String result="";
Cursor c= ourDatabase.query(DATABASE_TABLE,columns,KEY_ROWID+"="+row,null,null,null,null);
if(c!=null)
{
String r;
c.moveToFirst();
r="\nRecord No. : "+c.getString(0)+"\n\nSync Status:"+c.getString(1)+"\n\nTime of Creation:\n"+c.getString(2)+"\n\nName of Company:\n"+c.getString(3);
return r;
}
return result;
}
public void DeleteRow(int pos)
{
ourDatabase.delete(DATABASE_TABLE,KEY_ROWID+"="+pos,null);
}
}
the class for the new activity that shows the result.
package com.example.aakashmaroti.fillup;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import java.sql.SQLException;
public class DisplayDetails extends ActionBarActivity implements View.OnClickListener
{
ImageButton ibSync;
ImageButton ibDelete;
TextView DispDetails;
int pos;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
String value="1";
if (extras != null) {
value = extras.getString("position");
}
pos=Integer.parseInt(value);
setContentView(R.layout.activity_display_details);
ibSync=(ImageButton)findViewById(R.id.imageButtonSync);
ibDelete=(ImageButton)findViewById(R.id.imageButtonDelete);
DispDetails = (TextView)findViewById(R.id.textViewDisplayDetails);
String s="";
ibSync.setOnClickListener(this);
ibDelete.setOnClickListener(this);
Find info1=new Find(this);
try
{
info1.open();
s=info1.getDetails(pos);
info1.close();
} catch (SQLException e)
{
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Oops there has been an error "+e.toString()+"", Toast.LENGTH_LONG).show();
}
DispDetails.setText(s);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_display_details, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings)
{
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v)
{
if(v.getId()==R.id.imageButtonSync)
{
Toast.makeText(getApplicationContext(), "This functionality has not yet been added", Toast.LENGTH_LONG).show();
}
if(v.getId()==R.id.imageButtonDelete)
{ Find info1=new Find(this);
try
{
info1.open();
info1.DeleteRow(pos);
info1.close();
} catch (SQLException e)
{
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Oops there has been an error "+e.toString()+"", Toast.LENGTH_LONG).show();
}
Toast.makeText(getApplicationContext(), "This record has been successfully deleted", Toast.LENGTH_LONG).show();
cancel();
}
}
public void cancel()
{
this.finish();
return;
}
}
Xml file of a single row in the listview
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text=""
android:textStyle="bold"
android:clickable="true"
android:id="#+id/rowno"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text=""
android:clickable="true"
android:id="#+id/timestamp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:textStyle="bold"
android:text=""
android:clickable="true"
android:id="#+id/syncdetails"/>
</LinearLayout>
Any help will be greatly appreciated.
Thanks in advance.
Its because you are passing the list view item position, it should be the database row id.
Change
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
showsDialog(position);
}
to
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
TextView pos = (TextView) view.findViewById(R.id.rowno);
showsDialog(pos.getText().toString());
}
Also you said
Once I delete any entry the row id on the listview doesn't seem to update the row number. (if i delete the first row, the row on top shows 2(should be 1, as it is the new first row)).
But it wouldn't because this is the database row id not the list view position.
You only fetch your Cursor in onResume or onCreate. So your Cursor remains same although Data changes. Look into LoaderManager Class.
Related
I am working on have been getting contacts from the device's address book. I have an issue with getting the Email. I have tried and it keeps showing either phone number or a number (I am guessing it is a type). Please Help.
Here is my AdressBook.java
package newgbacard.gbacard.com.gbacard.fragments;
import android.content.Intent;
import android.support.v4.app.Fragment;
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import newgbacard.gbacard.com.gbacard.R;
import newgbacard.gbacard.com.gbacard.activities.ContactDetailActivity;
import newgbacard.gbacard.com.gbacard.activities.SettingsActivity;
import newgbacard.gbacard.com.gbacard.adapters.ContactUserAdapter;
import newgbacard.gbacard.com.gbacard.models.Contact;
import newgbacard.gbacard.com.gbacard.utils.Constants;
public class AddressBookFragment2 extends Fragment {
private ArrayList<Contact> selectUsers;
private ListView listView;
private Cursor phoneCursor;
private Cursor emailCursor;
private MenuItem searchMenuItem;
// Pop up
ContentResolver resolver;
SearchView searchView;
ContactUserAdapter adapter;
String email;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_addressbook, null);
selectUsers = new ArrayList<Contact>();
resolver = getActivity().getContentResolver();
listView = (ListView) view.findViewById(R.id.list);
try {
phoneCursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
LoadContact loadContact = new LoadContact();
loadContact.execute();
setHasOptionsMenu(true);
} catch (Exception e){
e.printStackTrace();
}
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_addressbook_fragment, menu);
searchMenuItem = menu.findItem(R.id.action_search);
searchView = (SearchView) searchMenuItem.getActionView();
searchView.setOnQueryTextListener(listener);
searchView.setFocusable(true);
searchView.setIconified(false);
searchView.requestFocusFromTouch();
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent intent = new Intent(getActivity(), SettingsActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
SearchView.OnQueryTextListener listener = new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// newText is text entered by user to SearchView
adapter.filter(newText);
return false;
}
};
// Load data on background
class LoadContact extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... voids) {
// Get Contact list from Phone
if (phoneCursor != null) {
Log.e("count", "" + phoneCursor.getCount());
if (phoneCursor.getCount() == 0) {
Toast.makeText(getActivity(), "No contacts in your contact list.", Toast.LENGTH_LONG).show();
}
while (phoneCursor.moveToNext()) {
Bitmap bitmapThumbnail = null;
String id = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String displayName = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String email = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS));
String address = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POBOX));
String imageThumbnail = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI));
try {
if (imageThumbnail != null) {
bitmapThumbnail = MediaStore.Images.Media.getBitmap(resolver, Uri.parse(imageThumbnail));
} else {
// Log.e("No Image Thumb", "--------------");
}
} catch (IOException e) {
e.printStackTrace();
}
Contact contact = new Contact();
contact.setThumb(bitmapThumbnail);
contact.setFirstName(displayName);
contact.setLastName("");
contact.setPhoneNumber(phoneNumber);
contact.setEmail(email);
contact.setAddress(address);
selectUsers.add(contact);
}
}
//phones.close();
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
adapter = new ContactUserAdapter(selectUsers, getActivity());
listView.setAdapter(adapter);
// Select item on listclick
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
try {
Contact contact = selectUsers.get(i);
Intent intent = new Intent(getActivity(), ContactDetailActivity.class);
intent.putExtra(Constants.TAG_CONTACT_DETAIL, contact);
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
});
//listView.setFastScrollEnabled(true);
}
}
}
Please I would appreciate if this issue is resolved. Thanks
You're trying the get an email from your phoneCursor field, which you initalize like this:
phoneCursor = getActivity().getContentResolver().query(Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
The table at Phone.CONTENT_URI contains only phone-number related information, it doesn't contain any emails.
If you want more then one type of data, you should query on CommonDataKinds.Data.CONTENT_URI which should return all types of contact information, you can limit it to phones and emails by using the selection:
Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "' OR " + Data.MIMETYPE + "='" + Email.CONTENT_ITEM_TYPE + "'"
docs: https://developer.android.com/reference/android/provider/ContactsContract.Data.html
I'm making an app that will let users add their school subjects.
Before i continue let me give you my code:
MainActivity:
package cannon.gaming.mymarks;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends ActionBarActivity {
TextView textSubject;
String SUBJECT, PASS;
Context ctx = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
/*Button buttonAdd = (Button) findViewById(R.id.buttonAdd);
buttonAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), RegisterActivity.class);
intent.setFlags(intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivityForResult(intent, 0);
}
});*/
Button buttonAdd = (Button) findViewById(R.id.buttonAdd);
textSubject = (TextView) findViewById(R.id.textSubject);
buttonAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showInputDialog();
}
});
}
protected void showInputDialog() {
// get prompts.xml view
LayoutInflater layoutInflater = LayoutInflater.from(MainActivity.this);
View promptView = layoutInflater.inflate(R.layout.activity_dialog, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
alertDialogBuilder.setView(promptView);
final EditText editText = (EditText) promptView.findViewById(R.id.edittext);
// setup a dialog window
alertDialogBuilder.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
SUBJECT = editText.getText().toString();
PASS = "0";
DatabaseOperations DB = new DatabaseOperations(ctx);
DB.putInformation(DB, SUBJECT, PASS);
Toast.makeText(getBaseContext(), "Subject added", Toast.LENGTH_SHORT).show();
finish();
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
// create an alert dialog
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
TableData:
package cannon.gaming.mymarks;
import android.provider.BaseColumns;
/**
* Created by Asuspc on 01/07/2015.
*/
public class TableData {
public TableData()
{
}
public static abstract class TableInfo implements BaseColumns
{
public static final String USER_NAME = "user_name";
public static final String USER_PASS = "user_pass";
public static final String DATABASE_NAME = "user_info";
public static final String TABLE_NAME = "reg_info";
}
}
DatabaseOperations:
package cannon.gaming.mymarks;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/**
* Created by Asuspc on 01/07/2015.
*/
public class DatabaseOperations extends SQLiteOpenHelper {
public static final int database_version = 1;
public String CREATE_QUERY = "CREATE TABLE "+ TableData.TableInfo.TABLE_NAME+"("+ TableData.TableInfo.USER_NAME+" TEXT,"+ TableData.TableInfo.USER_PASS+" TEXT);";
public DatabaseOperations(Context context) {
super(context, TableData.TableInfo.DATABASE_NAME, null, database_version);
Log.d("Database Operations", "Database created");
}
#Override
public void onCreate(SQLiteDatabase sdb)
{
sdb.execSQL(CREATE_QUERY);
Log.d("Database Operations", "Table created");
}
#Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2)
{
}
public void putInformation(DatabaseOperations dop,String name, String pass)
{
SQLiteDatabase SQ = dop.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(TableData.TableInfo.USER_NAME, name);
cv.put(TableData.TableInfo.USER_PASS, pass);
long k = SQ.insert(TableData.TableInfo.TABLE_NAME, null, cv);
Log.d("Database Operations", "One row inserted");
}
public Cursor getInformation(DatabaseOperations dop)
{
SQLiteDatabase SQ = dop.getReadableDatabase();
String[] columns = {TableData.TableInfo.USER_NAME, TableData.TableInfo.USER_PASS};
Cursor CR = SQ.query(TableData.TableInfo.TABLE_NAME, columns, null, null, null, null, null);
return CR;
}
}
Now let me explain.
When I press the "buttonAdd" button it will let me enter the subject name obviously, and save it in database.
But what I can't make is, I want to display all database on MainActivity.
And it should be like this:
names of subjects on the left side,
average of those subjects on the right side (the string PASS should be that average, that's why it is 0 when you first add the subject).
And I want to make each of those subjects clickable, so when you click it it should show you all marks from that subject and let you add or remove them.
Now, I guess, displaying data shouldn't be so hard, but still I need your help.
But making each subject clickable I really have no idea how.
And each subject having its own marks, I don't know, does it mean new activity for every new subject or new database or what?
EDIT:
MainActivity now:
package cannon.gaming.mymarks;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Build;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends ActionBarActivity {
String SUBJECT, PASS;
Context CTX = this;
private SimpleCursorAdapter adapter;
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
/*Button buttonAdd = (Button) findViewById(R.id.buttonAdd);
buttonAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), RegisterActivity.class);
intent.setFlags(intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivityForResult(intent, 0);
}
});*/
Button buttonAdd = (Button) findViewById(R.id.buttonAdd);
displayListView();
buttonAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showInputDialog();
}
});
}
protected void showInputDialog() {
// get prompts.xml view
LayoutInflater layoutInflater = LayoutInflater.from(MainActivity.this);
View promptView = layoutInflater.inflate(R.layout.activity_dialog, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
alertDialogBuilder.setView(promptView);
final EditText editText = (EditText) promptView.findViewById(R.id.edittext);
// setup a dialog window
alertDialogBuilder.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
SUBJECT = editText.getText().toString();
PASS = "0";
DatabaseOperations DB = new DatabaseOperations(CTX);
DB.putInformation(DB, SUBJECT, PASS);
Toast.makeText(getBaseContext(), "Subject added", Toast.LENGTH_SHORT).show();
adapter.notifyDataSetChanged();
displayListView();
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
// create an alert dialog
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void displayListView()
{
DatabaseOperations DOP = new DatabaseOperations(CTX);
Cursor CR = DOP.getInformation(DOP);
CR.moveToFirst();
// The desired columns to be bound
String[] columns = new String[]{
TableData.TableInfo.USER_NAME,
TableData.TableInfo.USER_PASS
};
// the XML defined views which the data will be bound to
int[] to = new int[]{
R.id.code,
R.id.name,
};
adapter = new SimpleCursorAdapter(
this, R.layout.activity_login,
CR,
columns,
to,
0);
ListView listView = (ListView) findViewById(R.id.listView);
// Assign adapter to ListView
listView.setAdapter(adapter);
}
}
To display data, you should use ListView and CursorAdapter.
Here is sample code for you: http://www.mysamplecode.com/2012/07/android-listview-cursoradapter-sqlite.html
In that sample code, you can see:
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
// Get the state's capital from this row in the database.
String countryCode =
cursor.getString(cursor.getColumnIndexOrThrow("code"));
Toast.makeText(getApplicationContext(),
countryCode, Toast.LENGTH_SHORT).show();
}
});
OnItemClickListener will help you to handle when a item in the listview is clicked.
Hope this will help you.
Im able to write data to a the database in the main activity but im having problems reading and displaying the data in a different activity. I'm using a SQLHelperDatabase class with a 'addData' method (which works fine according to the debugger) and a showData method (and this is where the problem lies). After entering data in the main activity i want to be able to press the send message button and the data to be displayed on the new activity. Ive been stuck on this for a week now and i been searching the WWW and every tutorial says that my code should work. Please can someone help me get to the bottom of this frustrating ordeal.
package com.doors.waynderful.myapp;
import android.content.Intent;
import android.database.Cursor;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class DisplayMessageActivity extends ActionBarActivity {
DatabaseHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
db = new DatabaseHelper(this);
Cursor cursor = db.showData();
cursor.moveToFirst();
String nam = cursor.getString(cursor.getColumnIndex(DatabaseHelper.THE_TABLE_COLUMN_NAME));
if (!cursor.isClosed()){
cursor.close();
}
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(nam);
setContentView(textView);
//setContentView(R.layout.activity_display_message);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_display_message, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Below is the SQLHelperDatabase.
package com.doors.waynderful.myapp;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper
{
public static final String THE_DATABASE = "theDatabase";
public static final String THE_TABLE = "infoTable";
public static final String THE_TABLE_COLUMN_ID = "id";
public static final String THE_TABLE_COLUMN_NAME = "name";
public static final String THE_TABLE_COLUMN_DETAILS = "details";
DatabaseHelper(Context context)
{
super(context,THE_DATABASE, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " +THE_TABLE+"(id integer primary key, name text, details text) ");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + THE_TABLE + "");
onCreate(db);
}
public void addData(String nameIn, String detailsIn)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues data = new ContentValues();
data.put("name", nameIn);
data.put("details", detailsIn);
db.insert(THE_TABLE,null,data);
}
public Cursor showData()
{
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor;
cursor = db.rawQuery("select * from "+THE_TABLE+"", null);
return cursor;
}
}
Below is the MainActivity
package com.doors.waynderful.myapp;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends ActionBarActivity {
public final static String EXTRA_MESSAGE = "com.doors.waynderful.myapp.MESSAGE";
DatabaseHelper myDb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void sendMessage(View view){
myDb = new DatabaseHelper(this);
Intent intent = new Intent(this,DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_name);
EditText editText1 = (EditText) findViewById(R.id.edit_details);
String name = editText.getText().toString();
String details = editText1.getText().toString();
myDb.addData(name, details);
//intent.putExtra(EXTRA_MESSAGE,message);
startActivity(intent);
}
}
LOGCAT shows
03-31 09:40:31.100 1351-1351/com.doors.waynderful.myapp E/SQLiteLog﹕ (1) no such table: infoTable
I'm not sure why you think that you must necessarily have a row in the database with an id = 1
If you want to find a row with a specific name, use a sql statement that selects the row with that name.
If you want to list all rows, then select all rows.
But inserting a row, and then assuming that you know it's id simply isn't going to work.
Also, you should use your (currently commented out) code that uses a layout instead of creating a new text view and setting that as the content view.
Finally, you don't seem to have any code that actually creates the table in the database?
I user LoaderManager and CursorLoader to load the data from my database using a ContentProvider.
Now, the initial load is fine. I have a ListView that display all the rows from the DB(only the names-String adapter).
Now, when I add/delete a row from the database, I want to refresh the ListView so it will display the recent changes.
Currently I just restart the loader with the method "restartLoader" whenever a change is commited but I want to ask if there is another way of doing this without restarting the loader.
Here is my activity class code:
package com.silverfix.phony.activities;
import java.util.ArrayList;
import com.silverfix.phony.R;
import com.silverfix.phony.contentprovider.PhonyContentProvider;
import com.silverfix.phony.database.RingtonesTable;
import android.app.Activity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentValues;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.Editable;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
public class RingtonesActivity extends Activity implements LoaderCallbacks<Cursor>{
private final int PICK_RINGTONE_CODE = 1;
private final int CURSOR_LOADER_ID = 1;
private final int EDIT_ID = 1;
private final int DELETE_ID = 2;
private String[] ContextCommands;
private ArrayAdapter<String> adapter;
private ArrayList<String> ringtones;
private ListView listview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ringtones);
listview = (ListView) findViewById(R.id.list);
Button add = (Button) findViewById(R.id.add_ringtone);
add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, PICK_RINGTONE_CODE);
}
});
fillData();
}
#Override
protected void onActivityResult(int arg0, int arg1, Intent arg2) {
super.onActivityResult(arg0, arg1, arg2);
switch (arg0) {
case 1: // PICK_RINGTONE_CODE
if (arg1 == RESULT_OK) {
Uri ringtoneURI = arg2.getData();
String[] projection = { MediaStore.MediaColumns.DISPLAY_NAME };
Cursor cursor = getContentResolver().query(ringtoneURI,
projection, null, null, null);
cursor.moveToFirst();
int column = cursor
.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
String displayName = cursor.getString(column);
addRingtone(ringtoneURI, displayName);
cursor.close();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.ringtones, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void fillData() {
getLoaderManager().initLoader(CURSOR_LOADER_ID, null, this);
ringtones = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, ringtones);
ContextCommands = getResources().getStringArray(R.array.commands);
listview.setAdapter(adapter);
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
editRingtone();
}
});
registerForContextMenu(listview);
listview.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
if (v.getId()==R.id.list) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
menu.setHeaderTitle(ContextCommands[info.position]);
String[] menuItems = getResources().getStringArray(R.array.commands);
menu.add(Menu.NONE, EDIT_ID, 0, menuItems[0]);
menu.add(Menu.NONE, DELETE_ID, 0, menuItems[1]);
}
}
});
}
#Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case EDIT_ID:
editRingtone();
return true;
case DELETE_ID:
String name = adapter.getItem(((AdapterContextMenuInfo) item.getMenuInfo()).position);
getContentResolver().delete(PhonyContentProvider.RINGTONES_URI, RingtonesTable.COLUMN_NAME
+ "='" + name + "'", null);
return true;
default:
return super.onContextItemSelected(item);
}
}
private void editRingtone() {
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, PICK_RINGTONE_CODE);
}
private void addRingtone(Uri uri, String name) {
String[] projection = { RingtonesTable.COLUMN_NAME };
Cursor cursor = getContentResolver().query(
PhonyContentProvider.RINGTONES_URI, projection,
RingtonesTable.COLUMN_NAME + "='"+name+"'", null, null);
if (cursor.getCount() == 0) {
ContentValues values = new ContentValues();
values.put(RingtonesTable.COLUMN_NAME, name);
values.put(RingtonesTable.COLUMN_URI, uri.toString());
getContentResolver().insert(PhonyContentProvider.RINGTONES_URI,
values);
getLoaderManager().restartLoader(CURSOR_LOADER_ID, null, this);
} else {
Toast.makeText(this, "You already picked that ringtone!",
Toast.LENGTH_LONG).show();
cursor.close();
}
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = {RingtonesTable.COLUMN_ID, RingtonesTable.COLUMN_NAME, RingtonesTable.COLUMN_URI};
return new CursorLoader(this, PhonyContentProvider.RINGTONES_URI, projection, null, null, null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
swapCursor(null);
}
private void swapCursor(Cursor cursor) {
if(cursor != null) {
cursor.moveToFirst();
ringtones.clear();
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
int column = cursor.getColumnIndex(RingtonesTable.COLUMN_NAME);
ringtones.add(cursor.getString(column));
}
adapter.notifyDataSetChanged();
cursor.close();
return;
}
ringtones.clear();
adapter.notifyDataSetChanged();
}
}
Since you already have access to the loader, you may not expect that much of a change, but another way of implementing this is by having the cursor setting PhonyContentProvider.RINGTONES_URI as its notification uri and notifying the uri whenever the database data changes.
Relevant methods:
setNotificationUri
notifyChange
I have an error that I don't know why in my Galaxy Ace Samsung(Android 2.3.6) doesn't work but in my Motorola G (Android 4.4) works perfectly. The exception are so strange this is my code:
adapter = new SimpleCursorAdapter(this,R.layout.single_row_profession, cursor,from,to,0);
package com.orun.app;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
import com.orun.database.DataBaseManager;
import com.orun.model.Profession;
import com.orun.s.SConnection;
public class ProfessionsActivity extends Activity {
public static SConnection sConnection;
public static DataBaseManager manager;
private static Cursor cursor;
private static ListView listView;
private static SimpleCursorAdapter adapter;
private static EditText etSearch;
private static ImageButton btSearch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_professions);
SharedPreferences sharedPref = getSharedPreferences(getString(R.string.PREFERENCE_FILE_KEY), Context.MODE_PRIVATE);
Toast.makeText(getApplicationContext(), "Rol "+sharedPref.getString("ROL","Estudiante"),Toast.LENGTH_LONG).show();
manager = new DataBaseManager(this);
listView = (ListView) findViewById(R.id.listView);
etSearch = (EditText)findViewById(R.id.etSearch);
new LoadTask().execute();
cursor = manager.searchProfession(etSearch.getText().toString());
int[] to = new int[]{R.id.textCode, R.id.textName,R.id.textType};
String[] from = new String[]{"_id","name","type"};
try {
adapter = new SimpleCursorAdapter(this,R.layout.single_row_profession, cursor,from,to,0);
}catch (Exception e){
e.printStackTrace();
}
listView.setAdapter(adapter);
etSearch.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
new SearchTask().execute();
adapter.changeCursor(cursor);
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {}
public void onTextChanged(CharSequence s, int start, int before,
int count) {}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(ProfessionsActivity.this,PrincipalActivity.class);
int codeProfession = Integer.parseInt(((TextView)(view.findViewById(R.id.textCode))).getText().toString());
SharedPreferences sharedPref = getSharedPreferences(getString(R.string.PREFERENCE_FILE_KEY), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("CODE_PROFESSION", codeProfession);
editor.commit();
startActivity(intent);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.professions, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class SearchTask extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
cursor = manager.searchProfession(etSearch.getText().toString());
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
private class LoadTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
try {
sConnection = new SConnection();
for(Profession p : sConnection.getPlansPreg())
manager.insertProfession(p.getCode(),p.getName(),"PRE");
for(Profession p : sConnection.getPlansPos())
manager.insertProfession(p.getCode(),p.getName(),"POS");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
Toast.makeText(getApplicationContext(),"Se han cargador todos los planes",Toast.LENGTH_SHORT).show();
}
}
}
The exception is: Cannot resolve constructor
'(Landroid/context/Context;ILandroid/database/Cursor;[Ljava/lang/String;[II)V
The constructor you are using was added in API level 11, so it's no wonder it doesn't exist in Android 2.3.6 (API level 10).
public SimpleCursorAdapter (Context context, int layout, Cursor c,
String[] from, int[] to, int flags) Added in API level 11
Standard constructor.
Parameters
context The context where the
ListView associated with this SimpleListItemFactory is running
layout resource identifier of a layout file that defines the views for this list item. The layout file should include at least those named views defined in "to"
c The database cursor. Can be null if the cursor is not available yet.
from A list of column names representing the data to bind to the UI. Can be null if the cursor is not available yet.
to The views that should display column in the "from" parameter. These should all be TextViews. The first N views in this list are given the values of the first N columns in the from parameter. Can be null if the cursor is not available yet.
flags Flags used to determine the behavior of the adapter, as per CursorAdapter(Context, Cursor, int).
See class reference.