Good day all, please been having this trouble and i can't seem to see why. Basically what am trying to do is pick a contact via the contact api, save in database, and then display in a listview. but for some reason, after i get the contacts details, my custom adapter is not called anymore, its only called on when the activity is first created, and hence empty. Please what could i have missed. Thank you.
heres my code:
public class GroupDetails extends FragmentActivity implements OnClickListener, LoaderCallbacks<Cursor> {
//variable for debugging the application
public static final String TAG = "MyApp.Debug";
//request code for using with action pick intent
static final int PICK_CONTACT = 1;
//initial variables
Button add_button;
TextView label;
ListView list;
ResponderDB dbadapter;
DueCustomCursorAdapter cursoradapter;
//DueCustomCursorLoader loader;
//cursor to retrieve contact details
private Cursor contactsCursor;
String groupname;
long rowId;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.group_detail_list);
//only intialize here. database will be open in custom cursor loader
dbadapter = new ResponderDB(this);
getSupportLoaderManager().initLoader(0, null, this);
/*Read intent and the extras passed*/
Bundle extra = getIntent().getExtras();
if(!extra.isEmpty() || extra.equals(null)){
groupname = extra.getString("group_name");
rowId = extra.getLong("rowId");
}
list = (ListView)findViewById(android.R.id.list);
add_button = (Button)findViewById(R.id.add_button_id);
label = (TextView)findViewById(R.id.group_label_id);
Log.d(TAG, "calling custom adapter here now");
cursoradapter = new DueCustomCursorAdapter(GroupDetails.this, null, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER );
list.setAdapter(cursoradapter);
add_button.setOnClickListener(this);
}
#Override
public void onClick(View view) {
int selection = view.getId();
if(selection == R.id.add_button_id){
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == PICK_CONTACT){
getContactInfo(data);
}
}
private void getContactInfo(Intent intent) {
String number = null;
String name = null;
String[] projection = {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
CursorLoader loader = new CursorLoader(this,intent.getData(),
null,null,null,null);
contactsCursor = loader.loadInBackground();
if(contactsCursor.moveToFirst()){
String id = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts._ID));
name = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
//get the Phone Number
Cursor numberCursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI
, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] {id}, null);
while(numberCursor.moveToNext()){
number = numberCursor.getString(numberCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
}
Log.d(TAG, "Successfully added contacts for group");
//dbadapter.updateGroup(rowId, values);
dbadapter.saveContacts(name, number, String.valueOf(rowId));
cursoradapter.notifyDataSetChanged();
getSupportLoaderManager().getLoader(0).onContentChanged();
}
public static final class DueCustomCursorLoader extends SimpleCursorLoader {
public static final String TAG = "MyApp.Debug";
public static int RETRIEVE_CODE = 1;
ResponderDB dbadapter1;
int retrieveCode;
public DueCustomCursorLoader(Context context, ResponderDB dbadapter) {
super(context);
this.dbadapter1= dbadapter;
}
public DueCustomCursorLoader(Context context, ResponderDB dbadapter, int retrieveCode){
super(context);
this.dbadapter1 = dbadapter;
this.retrieveCode = retrieveCode;
}
#Override
public Cursor loadInBackground() {
Cursor cursor = null;
dbadapter1.open();
cursor = dbadapter1.readContact(retrieveCode);
return cursor;
}
}
public class DueCustomCursorAdapter extends CursorAdapter {
public static final String TAG = "SmsResponder.Debug";
private Context myContext;
public DueCustomCursorAdapter(Context context,Cursor c, int flags) {
super(context, c, flags);
myContext = context;
}
//never seem to get here
#Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder)view.getTag();
String contactName = cursor.getString(cursor.getColumnIndexOrThrow(ResponderDB.NAME));
String contactNumber = cursor.getString(cursor.getColumnIndex(ResponderDB.NUMBER));
Log.d(TAG, "contact name is " + contactName);
Log.d(TAG, "contact number is " + contactNumber);
holder.contact_name.setText(contactName);
holder.contact_number.setText(contactNumber);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
View view = LayoutInflater.from(myContext).inflate(R.layout.group_detail_item, parent,false);
holder.contact_name = (TextView)view.findViewById(R.id.group_item_id);
holder.contact_number = (TextView)view.findViewById(R.id.group_subitem_id);
view.setTag(holder);
return view;
}
}
static class ViewHolder {
TextView text;
TextView contact_name;
TextView contact_number;
CheckBox checkbox;
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
return new DueCustomCursorLoader(GroupDetails.this, dbadapter, (int)rowId);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
cursoradapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> arg0) {
cursoradapter.swapCursor(null);
}
}
Am not getting any issue from the database, so code not added here.
After saving contact to the database You need to restartLoader() to get yours database requery and let onLoadFinished to be called again to allow adapter work with new data.
I would try reversing these two lines (it looks to me like your telling the list to update itself before you update the cursor):
cursoradapter.notifyDataSetChanged();
getSupportLoaderManager().getLoader(0).onContentChanged();
To this:
getSupportLoaderManager().getLoader(0).onContentChanged();
cursoradapter.notifyDataSetChanged();
Related
So just to describe the app im building, there are 3 buttons on the home screen, "Data Input", "Info Display" and "Exit". When user clicks "Data Input", they get to fill in some EditText boxes with info and also UPLOAD AN IMAGE from gallery. Once they click a "Save" button on the page, all data entered will be sent to a ListView widget in the "Info Display" screen. However my problem now is that I have managed to get the EditText values to the list view throught the use of Sqlite, but i currently have no clue on how to get the image which was uploaded from the gallery to the ListView widget
These are the working codes I have(only missing the image part)
TouristHelper
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class TouristHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "assignment.db";
private static final int SCHEMA_VERSION = 1;
public TouristHelper(Context context){
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db){
//will be called once when the database 1s not created
db.execSQL("CREATE TABLE tourist_table ( _id INTEGER PRIMARY KEY AUTOINCREMENT," +
" Vactivity TEXT, Vdate TEXT, Vdescription TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
//Will not be called until SCHEMA_VERSION increases
// Here we can upgrade the database e.g. add more tables
}
/*Read all records from restaurants_Table */
public Cursor getAll() {
return (getReadableDatabase().rawQuery(
"SELECT _id, Vactivity, Vdate, Vdescription " +
"FROM tourist_table ORDER BY Vactivity", null));
}
public Cursor getById(String id) {
String[] args = {id};
return (getReadableDatabase().rawQuery(
"SELECT _id, Vactivity, Vdate, Vdescription" +
" FROM tourist_table WHERE _ID = ?", args));
}
public void insert (String Vactivity, String Vdate,
String Vdescription) {
ContentValues cv = new ContentValues();
cv.put("Vactivity", Vactivity);
cv.put("Vdate", Vdate);
cv.put("Vdescription", Vdescription);
getWritableDatabase().insert("tourist_table", "Vactivity", cv);
}
public void update(String id, String Vactivity, String Vdate,
String Vdescription) {
ContentValues cv = new ContentValues();
String[] args = {id};
cv.put("Vactivity", Vactivity);
cv.put("Vdate", Vdate);
cv.put("Vdescription", Vdescription);
getWritableDatabase().update("tourist_table", cv, "_ID = ?", args);
}
public String getID(Cursor c) { return (c.getString(0)); }
public String getActivity(Cursor c){
return (c.getString(1));
}
public String getDate(Cursor c){
return (c.getString(2));
}
public String getDescription(Cursor c){
return (c.getString(3));
}
}
InfoDisplay
public class InfoDisplay extends AppCompatActivity {
private Cursor model = null;
private VietnamAdapter adapter = null;
private ListView list;
private TouristHelper helper = null;
private TextView empty = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.info_display);
empty = findViewById(R.id.empty);
helper = new TouristHelper(this);
list = findViewById(R.id.listview);
model = helper.getAll();
adapter = new VietnamAdapter(this, model, 0);
list.setOnItemClickListener(onListClick);
list.setAdapter(adapter);
}
#Override
protected void onResume() {
super.onResume();
if (model != null) {
model.close();
}
model = helper.getAll();
if (model.getCount() > 0) {
empty.setVisibility(View.INVISIBLE);
}
adapter.swapCursor(model);
}
#Override
protected void onDestroy() {
helper.close();
super.onDestroy();
}
private AdapterView.OnItemClickListener onListClick = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
model.moveToPosition(position);
String recordID = helper.getID(model);
Intent intent;
intent = new Intent(InfoDisplay.this, DataIn.class);
intent.putExtra("ID", recordID);
startActivity(intent);
}
};
static class DataHolder {
private TextView VietACTI = null;
private TextView VietDATE = null;
private TextView VietDES = null;
DataHolder(View row) {
VietACTI = row.findViewById(R.id.VAct);
VietDATE = row.findViewById(R.id.VDate);
VietDES = row.findViewById(R.id.VDes);
}
void populateFrom(Cursor c, TouristHelper helper) {
VietACTI.setText(helper.getActivity(c));
VietDATE.setText(helper.getDate(c));
VietDES.setText(helper.getDescription(c));
}
}
class VietnamAdapter extends CursorAdapter {
VietnamAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, flags);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
DataHolder holder = (DataHolder) view.getTag();
holder.populateFrom(cursor, helper);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
DataHolder holder = new DataHolder(row);
row.setTag(holder);
return (row);
}
}
}
DataIn
public class DataIn extends AppCompatActivity {
private EditText Vactivity;
private EditText Vdate;
private EditText Vdescription;
private Button buttonSave;
private Button buttonImg;
ImageView imageView;
private Bitmap imageToStore;
private static int RESULT_LOAD_IMAGE = 1;
private TouristHelper helper = null;
private String touristID = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_data_input);
Vactivity = findViewById(R.id.activity);
Vdate = findViewById(R.id.date);
Vdescription = findViewById(R.id.description);
buttonSave = findViewById(R.id.button_save);
buttonSave.setOnClickListener(onSave);
buttonImg = findViewById(R.id.imginput);
buttonImg.setOnClickListener(onImg);
imageView = findViewById(R.id.imgView);
helper = new TouristHelper(this);
touristID = getIntent().getStringExtra("ID");
if (touristID != null) {
load();
}
/*list = findViewById(R.id.Data);
adapter = new DataAdapter();
list.setAdapter(adapter);*/
}
#Override
protected void onDestroy() {
super.onDestroy();
helper.close();
}
private void load() {
Cursor c = helper.getById(touristID);
c.moveToFirst();
Vactivity.setText(helper.getActivity(c));
Vdate.setText(helper.getDate(c));
Vdescription.setText(helper.getDescription(c));
}
View.OnClickListener onImg = new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(
/*Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE*/);
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "pick an image"), RESULT_LOAD_IMAGE);
}
};
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && data != null) {
Uri selectedImage = data.getData();
/*String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();*/
// String picturePath contains the path of selected Image
imageView.setImageURI(selectedImage);
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmap = drawable.getBitmap();
}
}
private View.OnClickListener onSave = new View.OnClickListener(){
#Override
public void onClick(View v){
//read data from restaurantName EditText
String nameStr = Vactivity.getText().toString();
String dateStr = Vdate.getText().toString();
String desStr = Vdescription.getText().toString();
if (touristID == null) {
helper.insert(nameStr, dateStr, desStr);
}
else {
helper.update(touristID, nameStr, dateStr, desStr);
}
// To clase current Activity class and exit
finish();
}
};
}
At this point you have two options:
Save the image in the private storage of your app and save on the DB the URI to this image so you can load it later.
Having the Bitmap with the image get the ByteArray of the image and save it directly to the DB.
I prefer the first option, but the second one could do the job too, hope it helps you.
in my Application i have an Activity that has a ListView and a button. i am using loader to automatically loading data to listview from my table in the database.and i am using the button to change the table rows.
i want the loader to automatically load the data from table when a change happens to the table.
right now my code loads the data into listview but it doesn't update it when table changes after that.
here are my classes :
item
public class Item {
public int id;
public String name;
}
MainActivity :
public class MainActivity extends Activity implements
LoaderManager.LoaderCallbacks<List<Item>> {
ItemAdapter adapter;
List<Item> items;
Button button;
TextView tv;
ListView listview;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
button = (Button) findViewById(R.id.button);
listview = (ListView) findViewById(R.id.listview);
items = new ArrayList<Item>();
adapter = new ItemAdapter(this, items);
listview.setAdapter(adapter);
getLoaderManager().initLoader(0, savedInstanceState, this).forceLoad();
}
//button code for changing db
public void change(View view) {
ItemHelper helper = new ItemHelper(this);
Item item = new Item();
item.name = "Samsung P6800";
helper.insert(item);
}
#Override
public Loader<List<Item>> onCreateLoader(int id, Bundle args) {
final ItemHelper helper = new ItemHelper(getApplicationContext());
return new AsyncTaskLoader<List<Item>>(MainActivity.this) {
#Override
public List<Item> loadInBackground() {
return helper.read();
}
};
}
#Override
public void onLoadFinished(Loader<List<Item>> loader, List<Item> data) {
adapter.addAll(data);
adapter.notifyDataSetChanged();
}
#Override
public void onLoaderReset(Loader<List<Item>> loader) {
adapter.clear();
adapter.notifyDataSetChanged();
}
ItemHelper
public class ItemHelper {
public static final String DB_NAME = "Test";
private static Context m_context;
private static SQLiteDatabase m_db;
private static DatabaseHelper m_helper;
String[] columns = { "id", "name" };
public ItemHelper(Context context) {
m_context = context;
m_helper = new DatabaseHelper(m_context, DB_NAME, null, 1);
}
private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, DB_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
public void insert(Item item) {
m_db = m_helper.getWritableDatabase();
ContentValues initialValues = new ContentValues();
initialValues.put("name", item.name);
m_db.insert("item", null, initialValues);
m_db.close();
}
public List<Item> read() {
List<Item> items = new ArrayList<Item>();
m_db = m_helper.getReadableDatabase();
Cursor cursor = m_db.query("item", columns, null, null, null, null,
null);
if (cursor.moveToFirst()) {
do {
Item item = new Item();
item.id = cursor.getInt(cursor.getColumnIndexOrThrow("id"));
item.name = cursor.getString(cursor
.getColumnIndexOrThrow("name"));
items.add(item);
} while (cursor.moveToNext());
}
m_db.close();
return items;
}
}
ItemAdapter
public class ItemAdapter extends ArrayAdapter<Item> {
private Context context;
private List<Item> items;
private LayoutInflater vi;
public ItemAdapter(Context context, int resource) {
super(context, resource);
// TODO Auto-generated constructor stub
}
public ItemAdapter(Context context, List<Item> items) {
super(context, 0, items);
this.context = context;
this.items = items;
vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
Item item = items.get(position);
if (item != null) {
view = vi.inflate(R.layout.item_info, parent, false); // custom xml
// for
// desired
// view
TextView tv1 = (TextView) view.findViewById(R.id.tvID);
tv1.setText(""+item.id);
TextView tv2 = (TextView) view.findViewById(R.id.tvName);
tv2.setText(item.name);
}
return view;
}
#Override
public Item getItem(int position) {
return items.get(position);
}
}
how can i do it ? ( i don't want to use content providers )
finally i used ContentProviders to solve this issue.
i created a method inside my database helper class that returns a Cursor according to it's parameters,
and used it inside ContentProvider to get Data.
public Cursor getCursor(int status, boolean isAccepted) {
m_db = m_helper.getReadableDatabase();
String sql = "SELECT id as _id , rid , isaccepted , status FROM torder";
Cursor cursor = m_db.rawQuery(sql, null);
return cursor;
}
also in helper when i insert data to db i notify the content provider :
public void notifyProvider(int status) {
ContentValues values = new ContentValues();
values.put("status", status);
Uri uri = m_context.getContentResolver().insert(
OrderProvider.CONTENT_URI, values);
}
public void insert(Order order) {
int flag = (order.isAccepted()) ? 1 : 0;
String[] args = { String.valueOf(order.getId()),
String.valueOf(order.getR_id()), String.valueOf(flag),
String.valueOf(order.getStatus()) };
m_db.execSQL(
"INSERT OR REPLACE INTO torder(id,rid,isaccepted,status) VALUES(?,?,?,?)",
args);
// save to orderdetails
List<OrderDetails> orderDetailsList = order.getOrders();
OrderDetailsHelper helper = OrderDetailsHelper.getInstance(m_context);
helper.open();
helper.insertAll(orderDetailsList);
helper.close();
notifyProvider(1);
}
Change your change method:
public void change(View view) {
ItemHelper helper = new ItemHelper(this);
Item item = new Item();
item.name = "Samsung P6800";
helper.insert(item);
getLoaderManager().restartLoader(0, null, this);
}
I am trying to get a list of names with total amounts from a sqlite db.
It is working in a way that shows a list of all the transactions with the
correct combined total. I also have a table in the same db that has usernames
& phone numbers, but I don't think that would be too useful for this activity.
Also, how do I use the onListItemClick to send the next activity something
that I can use to pull only names from the User the person selected? The ID
is being sent, but I don't know how to use it.
ie:
trans table:
Justin 25
Justin 25
Justin 25
Sophia 80
Hoped results:
Justin 75
Sophia 80
Actual results:
Justin 75
Justin 75
Justin 75
Sophia 80
ListActivity that populates the list (with cursor and TextView link)
public class Totals extends ListActivity {
PaymentHelper helper;
Cursor model = null;
PaymentAdapter adapter = null;
UserHelper uhelp;
Cursor umodel = null;
public final static String ID_EXTRA = "com.curtis.bookkeeping._ID";
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_person);
helper = new PaymentHelper(this);
model = helper.getAll();
startManagingCursor(model);
adapter = new PaymentAdapter(model);
setListAdapter(adapter);
}
public void onDestroy() {
super.onDestroy();
helper.close();
}
#Override
public void onListItemClick(ListView list, View view, int position, long id) {
Intent i = new Intent(Totals.this, Detail.class);
i.putExtra(ID_EXTRA, String.valueOf(id));
startActivity(i);
}
public class PaymentAdapter extends CursorAdapter {
PaymentAdapter(Cursor c) {
super(Totals.this, c, FLAG_REGISTER_CONTENT_OBSERVER);
}
#Override
public void bindView(View row, Context context, Cursor c) {
PaymentHolder holder = (PaymentHolder)row.getTag();
holder.populateFrom(c, helper);
}
#Override
public View newView(Context context, Cursor c, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.person_row, parent, false);
PaymentHolder holder = new PaymentHolder(row);
row.setTag(holder);
return row;
}
}
static class PaymentHolder {
private TextView name_line = null;
private TextView amount_line = null;
PaymentHolder(View row) {
name_line = (TextView)row.findViewById(R.id.name_row);
amount_line = (TextView)row.findViewById(R.id.amount_row);
}
void populateFrom(Cursor c, PaymentHelper helper) {
name_line.setText(helper.getName(c));
amount_line.setText(Integer.toString(helper.sumPerson(c, helper.getName(c))));
}
}
}
SQLiteOpenHelper code to retrieve info
public class PaymentHelper extends SQLiteOpenHelper{
private static final String DATABASE_NAME = "bookkeeping.db";
private static final int SCHEMA_VERSION = 1;
SQLiteDatabase db;
public PaymentHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db1) {
db = db1;
String sql = "CREATE TABLE IF NOT EXISTS trans (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, date TEXT, amount INT, note TEXT)";
//execute the sql statement
db.execSQL(sql);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void insert(String name, String date, int amount, String note){
Log.e(name, date + " " + amount);
db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("name", name);
cv.put("date", date);
cv.put("amount", amount);
cv.put("note", note);
Log.e("Almost", "there");
db.insert("trans", "abc", cv);
Log.e("successfully", "inserted");
}
public Cursor getAll(){
String sql = "SELECT * FROM trans ORDER BY name";
Cursor cursor = getReadableDatabase().rawQuery(sql, null);
return cursor;
}
public Cursor getAllNames(){
String sql = "SELECT * FROM users";
Cursor cursor = getReadableDatabase().rawQuery(sql, null);
return cursor;
}
public String getName(Cursor c){
return c.getString(c.getColumnIndex("name"));
}
public String getDate(Cursor c){
return c.getString(c.getColumnIndex("date"));
}
public int getAmount(Cursor c){
return c.getInt(c.getColumnIndex("amount"));
}
public String getNote(Cursor c){
return c.getString(c.getColumnIndex("note"));
}
public void delete(String id){
String[] args = {id};
getWritableDatabase().delete("trans", "_id=?", args);
}
public Cursor getById(String id){
String[] args = {id};
String sql = "SELECT * FROM trans WHERE _id=?";
Cursor cursor = getReadableDatabase().rawQuery(sql, args);
return cursor;
}
public void update(String id, String name, String date, int amount, String note){
String[] args = {id};
ContentValues cv = new ContentValues();
cv.put("name", name);
cv.put("date", date);
cv.put("amount", amount);
cv.put("note", note);
getWritableDatabase().update("trans", cv, "_ID=?", args);
}
public int sumPerson(Cursor c, String name){
int total = 0;
// add up totals
String sql = "SELECT amount FROM trans WHERE name=?";
String[] aname = new String[]{name};
getReadableDatabase().rawQuery(sql,aname);
for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
if(name.equals(getName(c))){
total += c.getInt(c.getColumnIndex("amount"));
}
}
return total;
}
}
This is the activity that is receiving the ID from Totals:
I would like it to show only one user (which they selected
from the totals page) with all of their transactions.
public class Detail extends ListActivity {
PaymentHelper helper;
Cursor model = null;
PaymentAdapter adapter = null;
public final static String ID_EXTRA = "com.curtis.bookkeeping._ID";
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view);
helper = new PaymentHelper(this);
model = helper.getAll();
startManagingCursor(model);
adapter = new PaymentAdapter(model);
setListAdapter(adapter);
}
public void onDestroy() {
super.onDestroy();
helper.close();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.details_menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.totals:
startActivity(new Intent(this, Totals.class));
break;
case R.id.users:
startActivity(new Intent(this, Users.class));
break;
case R.id.home:
startActivity(new Intent(this, MainMenu.class));
break;
}
return true;
}
#Override
public void onListItemClick(ListView list, View view, int position, long id) {
Intent i = new Intent(Detail.this, DeletePayment.class);
i.putExtra(ID_EXTRA, String.valueOf(id));
startActivity(i);
}
public class PaymentAdapter extends CursorAdapter {
PaymentAdapter(Cursor c) {
super(Detail.this, c, FLAG_REGISTER_CONTENT_OBSERVER);
}
#Override
public void bindView(View row, Context context, Cursor c) {
PaymentHolder holder = (PaymentHolder)row.getTag();
holder.populateFrom(c, helper);
}
#Override
public View newView(Context context, Cursor c, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
PaymentHolder holder = new PaymentHolder(row);
row.setTag(holder);
return row;
}
}
static class PaymentHolder {
private TextView name_line = null;
private TextView date_line = null;
private TextView amount_line = null;
private TextView note_line = null;
PaymentHolder(View row) {
name_line = (TextView)row.findViewById(R.id.name_line);
amount_line = (TextView)row.findViewById(R.id.amount_line);
date_line = (TextView)row.findViewById(R.id.date_line);
note_line = (TextView)row.findViewById(R.id.note_line);
}
void populateFrom(Cursor c, PaymentHelper helper) {
Log.e(helper.getName(c), Integer.toString(helper.getAmount(c)));
name_line.setText(helper.getName(c));
date_line.setText(helper.getDate(c));
amount_line.setText(Integer.toString(helper.getAmount(c)));
note_line.setText(helper.getNote(c));
}
}
}
I know this is long...but help would be awesome!
I feel like the "PaymentAdapter" needs to be modified to only
read two names if there is only two names. Should I be utilizing
the "UserHelper" db helper to populate this? but when I do, it only
runs one cursor through, and gets a nullpointerexception error because
it is not moving one of the cursors. Should I be making a PaymentAdapter
within PaymentAdapter to generate use of another cursor?
The following SQL query will give you the desired result:
SELECT name, SUM(amount)
FROM trans
GROUP BY name
OK so I have a rather annoying issue. I am simply attempting to list all the songs on the device using a CursorLoader and LoaderCallbacks. My problem is simply that nothing is being displayed. I am using EXACTLY the same method as I am to load all albums, artists and playlists on the device. Using some debugging I have discovered that the problem is that newView() is only being called once within the CursorAdapter
Here is my CursorAdapter:
private class SongItemAdapter extends CursorAdapter
{
public SongItemAdapter(Context context)
{
super(context, null, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor)
{
final int albumId = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
final String songName = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
final String artistName = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
final String duration =
Utilities.milliSecondsToTimer(
cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)));
final ImageView albumCover = (ImageView) view.findViewById(R.id.all_songs_album_cover);
final TextView songNameTextView = (TextView) view.findViewById(R.id.all_songs_song_name);
final TextView artistNameTextView = (TextView) view.findViewById(R.id.all_songs_artist_name);
final TextView durationTextView = (TextView) view.findViewById(R.id.all_songs_song_duration);
ImageLoader.getInstance().displayImage(
ContentUris.withAppendedId(
sArtworkUri, albumId).toString(), albumCover);
songNameTextView.setText(songName);
artistNameTextView.setText(artistName);
durationTextView.setText(duration);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
return LayoutInflater.from(context).inflate(R.layout.song_list_item, parent, false);
}
}
Here is my LoaderCallbacks:
private final LoaderCallbacks<Cursor> mCursorCallbacks = new LoaderCallbacks<Cursor>()
{
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args)
{
return new CursorLoader(getActivity(),
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, Song.FILLED_PROJECTION, MediaStore.Audio.Media.IS_MUSIC + "!=0", null,
MediaStore.Audio.Media.TITLE + " ASC");
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data)
{
mAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader)
{
mAdapter.swapCursor(null);
}
};
And here is the initialisation of my adapter and listview and whatnot:
mAdapter = new SongItemAdapter(this.getActivity());
mListView = (ListView) rootView.findViewById(R.id.all_songs_list);
mListView.setOnItemClickListener(this);
mListView.setOnScrollListener(new PauseOnScrollListener(ImageLoader.getInstance(), false, false));
mListView.setAdapter(mAdapter);
mListView.setFastScrollEnabled(true);
mListView.setFastScrollAlwaysVisible(true);
mListView.setRecyclerListener(new RecyclerListener()
{
#Override
public void onMovedToScrapHeap(View view)
{
// Release strong reference when a view is recycled
final ImageView imageView = (ImageView) view.findViewById(R.id.all_songs_album_cover);
imageView.setImageBitmap(null);
}
});
getLoaderManager().initLoader(LOADER_CURSOR, null, mCursorCallbacks);
As I stated previously, this is exactly the method I use for loading albums, artists and playlists and those are working fine.
I have implemented an autocomplete feature in my application, but it picks up only the name of the contact instead of the number. Whenever i select a field in the autocomplete textbox, the number should be picked from the phone's contact list and placed in the text box...please help me out! :)
public class AutoMultipleContacts extends Activity {
private static final int PICK_CONTACT = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.multipleselect);
Cursor peopleCursor = getContentResolver().query(Contacts.People.CONTENT_URI, PEOPLE_PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER);
ContactListAdapter contactadapter = new ContactListAdapter(this,peopleCursor);
MultiAutoCompleteTextView textView = (MultiAutoCompleteTextView) findViewById(R.id.contacts);
textView.setAdapter(contactadapter);
textView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
}
public static class ContactListAdapter extends CursorAdapter implements Filterable {
public ContactListAdapter(Context context, Cursor c) {
super(context, c);
mContent = context.getContentResolver();
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
final TextView view = (TextView) inflater.inflate(
android.R.layout.simple_dropdown_item_1line, parent, false);
view.setText(cursor.getString(5));
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
((TextView) view).setText(cursor.getString(5));
}
#Override
public String convertToString(Cursor cursor) {
return cursor.getString(5);
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (getFilterQueryProvider() != null) {
return getFilterQueryProvider().runQuery(constraint);
}
StringBuilder buffer = null;
String[] args = null;
if (constraint != null) {
buffer = new StringBuilder();
buffer.append("UPPER(");
buffer.append(Contacts.ContactMethods.NAME);
buffer.append(") GLOB ?");
args = new String[] { constraint.toString().toUpperCase() + "*" };
}
return mContent.query(Contacts.People.CONTENT_URI, PEOPLE_PROJECTION,
buffer == null ? null : buffer.toString(), args,
Contacts.People.DEFAULT_SORT_ORDER);
}
private ContentResolver mContent;
}
private static final String[] PEOPLE_PROJECTION = new String[] {
Contacts.People._ID,
Contacts.People.PRIMARY_PHONE_ID,
Contacts.People.TYPE,
Contacts.People.NUMBER,
Contacts.People.LABEL,
Contacts.People.NAME,
};
}
Try changing
#Override
public String convertToString(Cursor cursor) {
return cursor.getString(5);
}
To
#Override
public String convertToString(Cursor cursor) {
return cursor.getString(3);
}
Append PhoneNumber to the buffer instead of Name and return cursor.getString(3) and setText(cursor.getString(3)). Also People is deprecated now. Use ContactsContracts instead.