I wonder if someone could show me the error of my ways--I've been struggling with this issue for two days, and realize it must be a fundamental error of initializing variables, but...that reflects the level of my java knowledge.
I'm getting a database result on a delimited string wherein each of the segments has "null" appended to it. It seems that no matter how I change the initialization...well, two days!
I'm declaring the following in the class heading area:
private String strListContent;
private SQLiteDatabase database;
private DatabaseHelper helper2 = new DatabaseHelper(this);
private static final String fields[] = { "_id", "listTitle", "listType",
"listContent", "dateCreated", "dateModified" };
private ArrayList<String> textArray = new ArrayList<String>();
private ArrayList<Integer> imageArray = new ArrayList<Integer>();
Then concatenating my items in
final ImageButton addItem = (ImageButton) findViewById(R.id.btnToAddItem);
addItem.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
itemEdit = (EditText) findViewById(R.id.editTextItem);
if (itemEdit.getText().toString().equals("")) {
showToastMessage("Please enter an item to add...");
} else {
String newListItem = itemEdit.getText().toString();
strListContent += newListItem + "|~|";
...
}}}
I'm using the following bare-bones SQLiteOpenHelper:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String KEY_ID = "_id";
public DatabaseHelper(Context context) {
super(context, "Cursor", null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS list_data ("
+ KEY_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, listTitle TEXT, listType TEXT, listContent TEXT, dateCreated TEXT, dateModified TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Steps to upgrade the database for the new version ...
}
}
To insert the values as so:
ImageButton saveAndBack = (ImageButton) findViewById(R.id.btnSaveBack);
saveAndBack.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String title = null;
String listContent = null;
Calendar javaCalendar = null;
title = titleEdit.getText().toString();
title = (title=="" || title==null)?"Untitled List":title;
strListContent = (strListContent=="" || strListContent==null)?"No Items|~|":strListContent;
listContent = strListContent;
String type = "R"; //"Regular List"
javaCalendar = Calendar.getInstance();
String currentDate = javaCalendar.get(Calendar.MONTH) + "/" + (javaCalendar.get(Calendar.DATE) + 1) + "/" + javaCalendar.get(Calendar.YEAR);
database = helper2.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("listTitle", title);
values.put("listType", type);
values.put("listContent", listContent);
values.put("dateCreated", currentDate);
values.put("dateModified", currentDate);
database.insert("list_data", null, values);
Intent i = new Intent(RegularList.this, ActivityMain.class);
startActivity(i);
}
});
}
//
//End of OnCreate(){}
//
Then, when I retrieve from another activity:
DatabaseHelper helper = new DatabaseHelper(this);
database = helper.getWritableDatabase();
Cursor data = database.query("list_data", fields, null, null, null,
null, null);
Integer tindex = data.getColumnIndex("listTitle");
Integer iindex = data.getColumnIndex("listType");
Integer cindex = data.getColumnIndex("listContent");
itemCount = 0;
for (data.moveToFirst(); !data.isAfterLast(); data.moveToNext()) {
showToastMessage(data.getString(cindex));
titleArrayList.add(data.getString(tindex));
if (data.getString(iindex) == "R") {
imageArrayList.add(R.drawable.listview_regular);
} else if (data.getString(iindex) == "L") {
imageArrayList.add(R.drawable.listview_location);
} else {
imageArrayList.add(R.drawable.listview_regular);
}
itemCount++;
}
data.close();
...
I can see in the toast message that each item from the delimited string has "null" appended to the front of it...the other values are fine. I hope this hasn't been too verbose, but...any recommendations? Thanks!
To me it looks like you may have simply not initialised the String strListContent before you first append to it with:
strListContent += newListItem + "|~|";
When you do that, you'll get a "null" prefixed in front of the value you are trying to append, just as you observe.
Perhaps you can just initialise in the declaration:
private String strListContent = "";
Related
How I can get a different values from a column with the same name (like the photo)?
In the photo, "test" have a 3 differents values, how I can load them to a ListView or a Spinner?
I have this code, works, but don't get the 3 values, only first value:
MainActivity
public void lookupProduct (View view) {
DatabaseHandler dbHandler = new DatabaseHandler(getApplicationContext());
Name name = dbHandler.findProduct(spinner.getSelectedItem().toString());
Toast.makeText(this, spinner.getSelectedItem().toString(), Toast.LENGTH_LONG).show();
Intent j = new Intent(view.getContext(), SubActivity.class);
Bundle dados = new Bundle();
if (name != null) {
inputLabel.setText(String.valueOf(name.getName()));
values.setText(String.valueOf(name.getValue()));
// Passar para SubActivity
dados.putString("name", String.valueOf(name.getName()));
dados.putString("value", String.valueOf(name.getValue()));
} else {
inputLabel.setText("No Match Found");
dados.putString("name","No Match Found" );
dados.putString("value", "No Match Found");
}
j.putExtras(dados);
startActivity(j);
}
DatabaseHelper
public Name findProduct(String name) {
String query = "Select * FROM " + TABLE_LABELS + " WHERE " + KEY_NAME + " = \"" + name + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
Name names = new Name();
if (cursor.moveToFirst()) {
cursor.moveToFirst();
names.setID(Integer.parseInt(cursor.getString(0)));
names.setName(cursor.getString(1));
names.setValue(cursor.getString(2));
cursor.close();
} else {
names = null;
}
db.close();
return names;
}
NameClass
public class Name {
private int _id;
private String _name;
private String _value;
public Name() {
}
public Name(int id, String name, String value) {
this._id = id;
this._name = name;
this._value = value;
}
public Name(String name, String value) {
this._name = name;
this._value = value;
}public String getName() {
return this._name;
}
public String getValue() {
return this._value;
}
Try this
Name names = new Name();
ArrayList<Name > listaName= new ArrayList<>();//create an arraylist of your
custom objects
if (cursor.moveToFirst()) {
do {
names.setID(Integer.parseInt(cursor.getString(0)));
names.setName(cursor.getString(1));
names.setValue(cursor.getString(2));
listaName.add(names);//add your object to arraylist(you were overriding the object.)
} while (cursor.moveToNext());
cursor.close();
//AND ALSO CLOSE DB:
db.close
EDIT 2: Try this and change your --> String Query = "Select * from "+TABLE_NAME;
for ( int i= 1; i< listaName.size(); i++ ) {
System.out.println(listaName.get(i).getName());
}
Your problem:
public Name findProduct(String name) {
String query = "Select * FROM " + TABLE_LABELS + " WHERE " + KEY_NAME + " = \"" + name + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
Name names = new Name();
if (cursor.moveToFirst()) {
cursor.moveToFirst(); // this is not necessary because on the top line,
you put it in that position
names.setID(Integer.parseInt(cursor.getString(0)));
names.setName(cursor.getString(1));
names.setValue(cursor.getString(2));
cursor.close(); // You should not close until it is
completely used
} else {
names = null;
}
db.close();
return names;
}
And to read all the cursor is necessary to use a do-while method
If you have any problems, you can ask me again
Though not yet tested, you can try this:
// fetch data from DB
public ArrayList<Name> findProduct(String name) {
String query = "Select * FROM " + TABLE_LABELS + " WHERE " + KEY_NAME + " = \"" + name + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
ArrayList<Name> listOfNames= new ArrayList<>();
if (cursor.moveToFirst()) {
do {
listOfNames.add(new Name(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2)));
} while (cursor.moveToNext());
cursor.close();
db.close
return listOfNames;
}
// add data on spinner
public void addItemsOnSpinner() {
Spinner mSpinner = (Spinner) findViewById(R.id.mSpinner);
ArrayList<String> list = new ArrayList<String>();
for(Name name: findProduct("test")){
list.add(name.getValue());
}
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(dataAdapter);
}
I am using sqlitedatabase,and i am able to insert data properly,but issue is when i am trying to display inserted data,my app got crash and giving nullpointer exception,can any one tell the what is the issue with my code,following is my snippet code,
Error in this line
if (c1 != null & c1.getCount() != 0) {
MAinActivity.java
public class MainActivity extends Activity {
private ListView upcominglist;
private ListView todays;
private ListView eventhistory;
private ImageView addnewevent;
public ArrayList<ContactListItems> contactList;
public ContactListItems contactListItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
upcominglist=(ListView)findViewById(R.id.listview_upcoming);
todays=(ListView)findViewById(R.id.listview_todays);
eventhistory=(ListView)findViewById(R.id.listview_eventhistory);
addnewevent=(ImageView)findViewById(R.id.addneweventbutton);
addnewevent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddNewEvent.class);
startActivity(intent);
}
});
contactList = new ArrayList<ContactListItems>();
contactList.clear();
String query = "SELECT * FROM PHONE_CONTACTS ";
Cursor c1 = SqlHandler.selectQuery(query);
if (c1 != null & c1.getCount() != 0) {
if (c1.moveToNext()) {
do {
contactListItems = new ContactListItems();
contactListItems.setSlno(c1.getString(c1.getColumnIndex("slno")));
contactListItems.setNameofevent(c1.getString(c1.getColumnIndex("nameofevent")));
contactListItems.setDtofevent(c1.getString(c1.getColumnIndex("dtofevent")));
contactListItems.setTimeofevent(c1.getString(c1.getColumnIndex("timeofevent")));
contactListItems.setDuration(c1.getString(c1.getColumnIndex("duration")));
contactList.add(contactListItems);
} while (c1.moveToNext());
}
}
else
{
c1.close();
}
c1.close();
String first=contactListItems.getSlno();
System.out.println("First" + first);
String second=contactListItems.getNameofevent();
System.out.println("SEcond"+second);
String third=contactListItems.getDtofevent();
System.out.println("Third"+third);
String fourth=contactListItems.getTimeofevent();
System.out.println("Fourth"+fourth);
String fifth=contactListItems.getDuration();
System.out.println("Fifth"+fifth);
}
Addnewevent.java
public class AddNewEvent extends Activity {
private int year;
private int month;
private int day;
static final int DATE_PICKER_ID = 1111;
static final int TIME_PICKER_ID = 11111;
int flag = 0;
private ImageView addnewdata;
private LinearLayout lnr;
private Button submit;
private EditText edtnmofevent;
private EditText edtdtofevent;
private EditText edttmofevent;
private EditText edtdurationofevent;
SqlHandler sqlHandler;
private ImageView datepicks;
private ImageView timepicks;
private Calendar cal;
private int hour;
private int min;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_new_event);
sqlHandler = new SqlHandler(getApplicationContext());
addnewdata = (ImageView) findViewById(R.id.addnewdata);
submit = (Button) findViewById(R.id.btnsubmit);
edtnmofevent = (EditText) findViewById(R.id.edtnameofevent);
edtdtofevent = (EditText) findViewById(R.id.edtdateofevent);
edttmofevent = (EditText) findViewById(R.id.edttimeofevent);
edtdurationofevent = (EditText) findViewById(R.id.edtdurationofevent);
datepicks = (ImageView) findViewById(R.id.calndrdat);
timepicks = (ImageView) findViewById(R.id.timepickrs);
cal = Calendar.getInstance();
hour = cal.get(Calendar.HOUR_OF_DAY);
min = cal.get(Calendar.MINUTE);
timepicks.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showDialog(TIME_PICKER_ID);
}
});
final Calendar c = Calendar.getInstance();
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH);
day = c.get(Calendar.DAY_OF_MONTH);
StringBuilder dateValue1 = new StringBuilder().append(day).append("-").append(month + 1).append("-")
.append(year).append(" ");
// for Converting Correct Date format Save into Database
SimpleDateFormat sdf123 = new SimpleDateFormat("dd-MM-yyyy");
String abs1 = dateValue1.toString();
Date testDate1 = null;
try {
try {
testDate1 = sdf123.parse(abs1);
} catch (java.text.ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (ParseException e) {
e.printStackTrace();
}
SimpleDateFormat formatter1 = new SimpleDateFormat("dd-MM-yyyy");
String DateFormat = formatter1.format(testDate1);
edtdtofevent.setText(DateFormat);
edtdtofevent.setFocusable(false);
edtdtofevent.setInputType(InputType.TYPE_NULL);
datepicks.setOnClickListener(new View.OnClickListener() {
#SuppressWarnings("deprecation")
#Override
public void onClick(View v) {
showDialog(DATE_PICKER_ID);
}
});
addnewdata.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LayoutInflater li = LayoutInflater.from(AddNewEvent.this);
View promptsView = li.inflate(R.layout.prompts, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
AddNewEvent.this);
// set prompts.xml to alertdialog builder
alertDialogBuilder.setView(promptsView);
final EditText userInput = (EditText) promptsView
.findViewById(R.id.editTextDialogUserInput);
alertDialogBuilder
.setCancelable(false)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
lnr = (LinearLayout) findViewById(R.id.addnewlinear);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(25, 0, 0, 0);
TextView valueTV = new TextView(AddNewEvent.this);
// valueTV.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
valueTV.setText(userInput.getText());
valueTV.setLayoutParams(lp);
valueTV.setTextSize(18);
valueTV.setTextColor(Color.parseColor("#2d6cae"));
LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
lp1.setMargins(25, 0, 25, 0);
lp1.height = 50;
EditText edtvalues = new EditText(AddNewEvent.this);
edtvalues.setBackgroundResource(R.drawable.rect_edt);
edtvalues.setLayoutParams(lp1);
lnr.addView(valueTV);
lnr.addView(edtvalues);
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
});
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(AddNewEvent.this, EventDetails.class);
startActivity(intent);
String nameofevent = edtnmofevent.getText().toString();
String dtofevent = edtdtofevent.getText().toString();
String timeofevent = edttmofevent.getText().toString();
String duration = edtdurationofevent.getText().toString();
String query = "INSERT INTO PHONE_CONTACTS(nameofevent,dtofevent,timeofevent,duration) values ('"
+ nameofevent + "','" + dtofevent + "','" + timeofevent + "','" + duration + "')";
sqlHandler.executeQuery(query);
System.out.println("Querys" + query);
}
});
}
SQL
public class SqlDbHelper extends SQLiteOpenHelper {
public static final String DATABASE_TABLE = "PHONE_CONTACTS";
public static final String COLUMN1 = "slno";
public static final String COLUMN2 = "nameofevent";
public static final String COLUMN3 = "dtofevent";
public static final String COLUMN4 = "timeofevent";
public static final String COLUMN5 = "duration";
/* public static final String COLUMN6 = "dlabl";
public static final String COLUMN7 = "dedt";*/
private static final String SCRIPT_CREATE_DATABASE = "create table "
+ DATABASE_TABLE + " (" + COLUMN1
+ " integer primary key autoincrement, " + COLUMN2
+ " text not null, " + COLUMN3 + " text not null, " + COLUMN4 + " text not null, " + COLUMN5 + " text not null);";
public SqlDbHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(SCRIPT_CREATE_DATABASE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
The problem is in your SqlHandler.selectQuery() that returns a null, and another problem here checking the result:
if (c1 != null & c1.getCount() != 0)
You're using bitwise and & and not the short-circuiting logical and &&. Without short circuiting the complete expression including c1.getCount() on a null reference is evaluated.
There is too much here to explain it all, so I will give you the flaws causing a null pointer exception.
I can see your method of programming is coming from worrying too much about closing things and clearing up
resources to a point, it's causing problems.
contactList = new ArrayList<ContactListItems>();
// You are clearing your list, it should be empty, you have just created it.
contactList.clear();
String query = "SELECT * FROM PHONE_CONTACTS ";
Cursor c1 = SqlHandler.selectQuery(query);
// As mentioned by the other answer. You need && not &
// if (c1 != null & c1.getCount() != 0) {
if (c1 != null && c1.getCount() != 0) {
// Move to the first entry.
c1.moveToFirst();
//if (c1.moveToNext()) {
// do {
// Continue while it has not passed the last entry.
while (!cursor.isAfterLast())
contactListItems = new ContactListItems();
contactListItems.setSlno(c1.getString(c1.getColumnIndex("slno")));
contactListItems.setNameofevent(c1.getString(c1.getColumnIndex("nameofevent")));
contactListItems.setDtofevent(c1.getString(c1.getColumnIndex("dtofevent")));
contactListItems.setTimeofevent(c1.getString(c1.getColumnIndex("timeofevent")));
contactListItems.setDuration(c1.getString(c1.getColumnIndex("duration")));
contactList.add(contactListItems);
// Move the cursor along to the next entry.
cursor.moveToNext();
}
}
// Close cursor after while and within if (so you know it is not null).
c1.close();
}
else
{
// You can't close c1 if it is Null. This will throw and error. Lose the else.
c1.close();
}
// Move this to within your if statment.
c1.close();
From your code you provided in the chat.
Don't open and close your database continuously, just close each cursor you use when you're done. Just open it at the beginning and end of your program run.
public static Cursor selectQuery(String query) {
Cursor c1 = null;
try {
if (sqlDatabase.isOpen()) {
// You are closing the database.
sqlDatabase.close();
}
sqlDatabase = dbHelper.getWritableDatabase();
c1 = sqlDatabase.rawQuery(query, null);
} catch (Exception e) {
System.out.println("DATABASE ERROR " + e);
}
return c1;
}
There are many other flaws in your project. Like the structure and how and when you are calling things. You need to modularise it out, create methods for particular tasks and call those methods, rather than have a great lump of code in oncreate.
I am sure you will have many questions about this. But currently this question is addressing your null pointer exception and that is all I will discuss here. For questions about this not relating to this exception, please ask a new question. Hope this helps.
This is my MainActivity.
public class MainActivity extends Activity {
EditText etName, etEmail;
DatabaseHelper dbHelper;
Button save;
// declare view
ListView lvEmployees;
// declare adapter
CustomizedAdapter adapter;
// datasource
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etName = (EditText) findViewById(R.id.etName);
etEmail = (EditText) findViewById(R.id.etEmail);
save = (Button) findViewById(R.id.btnSave);
lvEmployees = (ListView) findViewById(R.id.lvEmployees);
dbHelper = new DatabaseHelper(this);
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
save(v);
}
});
}
public void save(View v) {
String name = etName.getText().toString();
String email = etEmail.getText().toString();
Employee employee = new Employee(name, email);
Toast.makeText(getApplicationContext(), employee.toString(),
Toast.LENGTH_LONG).show();
long inserted = dbHelper.insertEmployee(employee);
if (inserted >= 0) {
Toast.makeText(getApplicationContext(), "Data inserted",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Data insertion failed...",
Toast.LENGTH_LONG).show();
}
ArrayList<Employee> employees = dbHelper.getAllEmployees();
if (employees != null && employees.size() > 0) {
adapter = new CustomizedAdapter(this, employees);
lvEmployees.setAdapter(adapter);
}
}
}
This is my DataBaseHelper.
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DB_NAME = "task_management";
public static final int DB_VERSION = 1;
public static final String EMPLOYEE_TABLE = "employee";
public static final String ID_FIELD = "_id";
public static final String NAME_FIELD = "name";
public static final String EMAIL_FIELD = "email";
public static final String EMPLOYEE_TABLE_SQL = "CREATE TABLE "
+ EMPLOYEE_TABLE + " (" + ID_FIELD + " INTEGER PRIMARY KEY, "
+ NAME_FIELD + " TEXT, " + EMAIL_FIELD + " DATETIME);";
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// create tables
db.execSQL(EMPLOYEE_TABLE_SQL);
Log.e("TABLE CREATE", EMPLOYEE_TABLE_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// upgrade logic
}
// insert
public long insertEmployee(Employee emp) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(NAME_FIELD, emp.getName());
values.put(EMAIL_FIELD, emp.getEmail());
long inserted = db.insert(EMPLOYEE_TABLE, null, values);
db.close();
return inserted;
}
// query
public ArrayList<Employee> getAllEmployees() {
ArrayList<Employee> allEmployees = new ArrayList<Employee>();
SQLiteDatabase db = this.getReadableDatabase();
// String[] columns={NAME_FIELD, EMAIL_FIELD, PHONE_FIELD};
// SELECT * FROM EMPLOYEE;
Cursor cursor = db.query(EMPLOYEE_TABLE, null, null, null, null, null,
null);
// Cursor cursor = db.rawQuery("SELECT * FROM EMPLOYEE", null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
for (int i = 0; i < cursor.getCount(); i++) {
//
int id = cursor.getInt(cursor.getColumnIndex(ID_FIELD));
String name = cursor.getString(cursor
.getColumnIndex(NAME_FIELD));
String email = cursor.getString(cursor
.getColumnIndex(EMAIL_FIELD));
Employee e = new Employee(id, name, email);
allEmployees.add(e);
cursor.moveToNext();
}
}
cursor.close();
db.close();
return allEmployees;
}
}
When i put data and pressed the save button then my data is saved and show in my ListView.
But when i close the apps and open it then i don't see any data in my ListView.
After putting data and pressed save button my new and existing data show in my ListView.
So how can i show my existing data in ListView after open my apps and without press the save button.
If you want to show data each time app starts, you would need to move your list populating code in onCreate
Move this code to onCreate instead of Save button's onClick
ArrayList<Employee> employees = dbHelper.getAllEmployees();
if (employees != null && employees.size() > 0) {
adapter = new CustomizedAdapter(this, employees);
lvEmployees.setAdapter(adapter);
}
Hope it helps.
P.S: If you need to repopulate list after Save button's click, make a separate function which contains this code. And call tha function in onCreate as well as in Save button's onClick
You are setting the adapter for the list view in your save method that is called only when you actually press the save button. Here's the part where you do it.
ArrayList<Employee> employees = dbHelper.getAllEmployees();
if (employees != null && employees.size() > 0) {
adapter = new CustomizedAdapter(this, employees);
lvEmployees.setAdapter(adapter);
}
Thats why there is no data in the listview when you open the app.
You should do this in your onCreate method, and in your save you should do something like this:
1. declare the the arraylist of employees along with listview;
ArrayList<Employee> employees;
in your oncreate call this code that you should remove from the save method
employees = dbHelper.getAllEmployees();
if (employees != null && employees.size() > 0) {
adapter = new CustomizedAdapter(this, employees);
lvEmployees.setAdapter(adapter);
}
in save method just add one more item to the list, and notify adapter that there has been a change in the data it's displaying.
employees.add(employee);
adapter.notifyDataSetChanged();
I am populating contact list details to list view successfully.
My code:
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor curLog = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null,order);
How can I avoid the duplicate data In List view as the contact details is repeating if its joined contact i.e. joined with both phone and Google?. The screen is like
I want to select programmatically only 1 name not the both? Any Idea how I can select?
I have used a rough way to avoid this problem which helped me so much and working nicely.
i.e
Use local database (SQLite) to avoid duplicate data by make phone number to unique.
I have made one SQLite DB to handle this problem:
ContactMerger.java:
public class ContactMerger {
private static final String CONTACT_TABLE = "_contact_table";
private static final String CONTACT_ID = "_contactId";
private static final String CONTACT_NAME = "_contactName";
private static final String CONTACT_MOBILE_NUMBER = "_contactNumber";
private static final String CONTACT_DATE = "_contactDate";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "DB_Contact";
private final Context context;
private SQLiteDatabase ourDatabase;
private DbHelper ourHelper;
private class DbHelper extends SQLiteOpenHelper {
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String contactQuery = "CREATE TABLE " + CONTACT_TABLE + " ("
+ CONTACT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ CONTACT_NAME + " TEXT NOT NULL, " + CONTACT_DATE
+ " TEXT NOT NULL, " + CONTACT_MOBILE_NUMBER
+ " TEXT NOT NULL UNIQUE);";
db.execSQL(contactQuery);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + CONTACT_TABLE);
onCreate(db);
}
}
public ContactMerger(Context context) {
this.context = context;
}
public ContactMerger open() throws SQLException {
ourHelper = new DbHelper(context);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public void close() {
ourHelper.close();
}
// Insert Data to Contact Table
public long insertContacts(String name, String number, String date) throws SQLException {
ContentValues cv = new ContentValues();
cv.put(CONTACT_NAME, name);
cv.put(CONTACT_DATE, date);
cv.put(CONTACT_MOBILE_NUMBER, number);
Log.d("Insert Data", cv.toString());
return ourDatabase.insert(CONTACT_TABLE, null, cv);
}
//Get Contact details from Contact Table
public ArrayList<ContactHolder> getContactDetails() throws Exception{
ArrayList<ContactHolder> contactDetails = new ArrayList<ContactHolder>();
String[] columns = new String[] { CONTACT_ID, CONTACT_NAME, CONTACT_DATE, CONTACT_MOBILE_NUMBER };
Cursor c = ourDatabase.query(CONTACT_TABLE, columns, null, null, null,null, null);
int iContactName = c.getColumnIndex(CONTACT_NAME);
int iContactDate = c.getColumnIndex(CONTACT_DATE);
int iContactMobileNumber = c.getColumnIndex(CONTACT_MOBILE_NUMBER);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
ContactHolder data = new ContactHolder();
data.setName(c.getString(iContactName));
data.setDate(c.getString(iContactDate));
data.setNumber(c.getString(iContactMobileNumber));
contactDetails.add(data);
}
return contactDetails;
}
}
Here ContactHolder is just a getter/setter class to handle contact entities.
First I inserted all Contact information once in my MainActivity by the help of a background thread. It prevents to insert the contact info multiple times.
Something like:
private ArrayList<ContactHolder> contactHolder;
private void setCallLogs(Cursor managedCursor) {
contactHolder = new ArrayList<ContactHolder>();
int _number = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int _name = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int _id = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);
while (managedCursor.moveToNext()) {
ContactHolder holder = new ContactHolder();
holder.setNumber(managedCursor.getString(_number));
holder.setName(managedCursor.getString(_name));
holder.setDate(managedCursor.getString(_id));
contactHolder.add(holder);
}
Thread t = new Thread(new Runnable() {
#Override
public void run() {
for(int i=0; i<contactHolder.size(); i++){
try{
ContactMerger merger = new ContactMerger(HomeActivity.this);
merger.open();
merger.insertContacts(contactHolder.get(i).getName(),
contactHolder.get(i).getNumber(),
contactHolder.get(i).getdate());
merger.close();
} catch(Exception e){
e.printStackTrace();
}
}
}
});
t.start();
}
At last I gtt all contact information inside an Asynctask(doInbackground()) and put in adapter/listview in its onPostExecute() method in the class I want to show.
Here:
#Override
protected ArrayList<ContactHolder> doInBackground(String... parameters) {
ArrayList<ContactHolder> filterContacts = new ArrayList<ContactHolder>();
ContactMerger merger = new ContactMerger(Aaja_Contact.this);
merger.open();
try {
filterContacts = merger.getContactDetails();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
merger.close();
return filterContacts;
}
I believe this may happen if the contact number is stored in two different ways/formats: for example in your case the number for Akshay may be saved as 982-0123456 and 9820123456
Did you try displaying the number along with the Name by including the Number as well in the list view?
You need to retrieve the data from the Cursor to HashSet (which don't allows duplicate itmes) and then pass the HashSet object to your ListView's Adapter
This is a dump solution but it will help you:
ListView listView;
Set<String> listItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
listItems = new HashSet<String>();
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor curLog = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null,order);
if(curLog != null) {
while(curLog.moveToNext()) {
String str = curLog.getString(curLog.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY));
listItems.add(str);
}
}
String listString = listItems.toString();
listString = listString.substring(1,listString.length()-1);
String[] newList = listString.split(", ");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, newList);
listView.setAdapter(adapter);
}
Good luck..
Since you're querying Phone.CONTENT_URI, I'm assuming you're looking for contacts with phone number.. then you can use ContactsContract.Contacts.CONTENT_URI
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor curLog = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
ContactsContract.Contacts.HAS_PHONE_NUMBER + "=?", new String[] { "1" }, order);
Its because the listview is showing both normal contacts as well as whatsapp( or like this) linked contacts. Best is to store all the contacts in a Database and then retrieve the contacts using "select distinct..." command of SQL.
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, order);
String temp_name="";
while (phones.moveToNext())
{
String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
if (name.equals(temp_name))
continue;
temp_name=name;
//add name to your list or adapter here`enter code here`
}
phones.close();
When you loop through your contacts, here's something you can do in the looping statement while you add your next object to avoid creating a duplicate contact:
UserList object=new UserList(name,number);
if(arrayList.size()==0)
{
arrayList.add(object);
}
if(arrayList.size()>0) {
position = arrayList.size();
if (!(arrayList.get(arrayList.position - 1).getName().equals(number) ||
arrayList.get(position - 1).getNumber().equals(number)))
{
arrayList.add(object); }
}
Here, in my object of 'UserList' class, the name and number would repeat from the contact list, so this code just checks if the previous object has the same name or number before adding in the new one.
Old question but still relevant. I could not find suitable query to skip dupes with contentresolver but it's possible to compare all contacts for duplicates by phone number.
With com.googlecode.libphonenumber library it's really simple. Method public MatchType isNumberMatch(CharSequence firstNumber, CharSequence secondNumber) compares number, coutry code, mask and return one of MatchType enum value.
I'm trying to get certain book data from my Inventory table based on the ISBN.
However, I'm getting an error: "attempt to re-open an already-closed object". The error only occurs when I click a listView object, go to a different screen, go back to this page via "finish()", and then try to click on another listView object. I moved the String searchEntries[] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery, isbn[position]); from the onClickListener to the previous for loop before the onClickListener and now it works.
Why does it not work if I try to getInventoryEntriesByISBN after returning to this activity from another activity via "finish()"?
The error occurs at SearchResultsScreen:
String searchEntries[] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery, isbn[position]);
and by extension, occurs at InventoryAdapter:
Cursor cursor = db.rawQuery(query, new String[] {ISBN});
SearchResultsScreen.java
// Set up search array
for(int i = 0; i < isbn.length; i++)
{
searchArray.add(new InventoryItem(isbn[i], InventoryAdapter.getTitleAndAuthorByISBN(isbn[i])));
}
Toast.makeText(getApplicationContext(), "searchArray.size()="+searchArray.size(), Toast.LENGTH_LONG).show();
// add data in custom adapter
adapter = new CustomAdapter(this, R.layout.list, searchArray);
ListView dataList = (ListView) findViewById(R.id.list);
dataList.setAdapter(adapter);
// On Click ========================================================
dataList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String searchEntries[] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery, isbn[position]);
InventoryAdapter.java (Most relevant parts)
public String[] getInventoryEntriesByISBN(String search, String ISBN)
{
String[] searchEntry = new String [9];
//Query
String query = "select * from INVENTORY where ISBN = ?";
Cursor cursor = db.rawQuery(query, new String[] {ISBN});
if(cursor.getCount()<1) // title Not Exist
{
cursor.close();
for(int i = 0; i < 9; i++)
searchEntry[i] = "Not Found";
return searchEntry;
}
cursor.moveToFirst();
//put data into respective variable
int publish = cursor.getInt(cursor.getColumnIndex("PUBLISH_DATE"));
String publishdate = ((Integer)publish).toString();
String title = cursor.getString(cursor.getColumnIndex("TITLE"));
String author = cursor.getString(cursor.getColumnIndex("AUTHOR"));
String callNumber = cursor.getString(cursor.getColumnIndex("CALL_NUMBER"));
int available = cursor.getInt(cursor.getColumnIndex("AVAILABLE_COUNT"));
String availablecount = ((Integer)available).toString();
int inventory = cursor.getInt(cursor.getColumnIndex("INVENTORY_COUNT"));
String inventorycount = ((Integer)inventory).toString();
int due = cursor.getInt(cursor.getColumnIndex("DUE_PERIOD"));
String dueperiod = ((Integer)due).toString();
int checkoutcount = cursor.getInt(cursor.getColumnIndex("COUNT"));
String count = ((Integer)checkoutcount).toString();
//combine variables into one array
searchEntry[0] = ISBN;
searchEntry[1] = title;
searchEntry[2] = author;
searchEntry[3] = publishdate;
searchEntry[4] = callNumber;
searchEntry[5] = availablecount;
searchEntry[6] = inventorycount;
searchEntry[7] = dueperiod;
searchEntry[8] = count;
cursor.close();
return searchEntry;
}
public String getTitleAndAuthorByISBN(String ISBN)
{
int entriesFound = getNumSearchEntries(ISBN);
if(entriesFound==0)
entriesFound = 1;
String searchEntry;
//Query
String query = "select * from INVENTORY where ISBN = ?";
Cursor cursor = db.rawQuery(query, new String[] {ISBN});
if(cursor.getCount()<1) // title Not Exist
{
cursor.close();
searchEntry = "Not Found";
return searchEntry;
}
cursor.moveToFirst();
//put data into respective variable
String title = cursor.getString(cursor.getColumnIndex("TITLE"));
String author = cursor.getString(cursor.getColumnIndex("AUTHOR"));
//combine variables into one String
searchEntry = title + " / " + author;
//close cursor and return
cursor.close();
return searchEntry;
}
DataBaseHelper.java
public class DataBaseHelper extends SQLiteOpenHelper
{
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "database.db";
// ============================ End Variables ===========================
public DataBaseHelper(Context context, String name, CursorFactory factory, int version)
{
super(context, name, factory, version);
}
public DataBaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Called when no database exists in disk and the helper class needs
// to create a new one.
#Override
public void onCreate(SQLiteDatabase _db)
{
_db.execSQL(LoginDataBaseAdapter.USER_TABLE_CREATE);
_db.execSQL(CheckOutDataBaseAdapter.CHECKOUT_TABLE_CREATE);
_db.execSQL(InventoryAdapter.INVENTORY_TABLE_CREATE);
_db.execSQL(StatisticsAdapter.STATISTICS_TABLE_CREATE);
}
// Called when there is a database version mismatch meaning that the version
// of the database on disk needs to be upgraded to the current version.
#Override
public void onUpgrade(SQLiteDatabase _db, int _oldVersion, int _newVersion)
{
// Log the version upgrade.
Log.w("TaskDBAdapter", "Upgrading from version " +_oldVersion + " to " +_newVersion + ", which will destroy all old data");
// Upgrade the existing database to conform to the new version. Multiple
// previous versions can be handled by comparing _oldVersion and _newVersion
// values.
// on upgrade drop older tables
_db.execSQL("DROP TABLE IF EXISTS " + LoginDataBaseAdapter.USER_TABLE_CREATE);
_db.execSQL("DROP TABLE IF EXISTS " + CheckOutDataBaseAdapter.CHECKOUT_TABLE_CREATE);
_db.execSQL("DROP TABLE IF EXISTS " + InventoryAdapter.INVENTORY_TABLE_CREATE);
_db.execSQL("DROP TABLE IF EXISTS " + StatisticsAdapter.STATISTICS_TABLE_CREATE);
// Create a new one.
onCreate(_db);
}
}
Check Database Connection before executing query:
if (!dbHelper.db.isOpen())
dbHelper.open();
you can also use cursor.requery(); for again same query.
and in last you have to close the cursor and database also.
cursor.close();
db.close();
Edited:
I have created DBHelper class which extends SQLiteOpenHelper, this class is inner class of DatabaseHelper class and that class have following methods.
/** For OPEN database **/
public synchronized DatabaseHelper open() throws SQLiteException {
dbHelper = new DBHelper(context);
db = dbHelper.getWritableDatabase();
return this;
}
/** For CLOSE database **/
public void close() {
dbHelper.close();
}
If you have still doubt then feel free to ping me. Thank you.
The error only occurs when I click an item, go to a different screen, go back to this page via "finish()", and then try to click on another listView object.
I moved the String searchEntries[] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery, isbn[position]); from the onClickListener to the previous for loop before the onClickListener and now it works.
The correct SearchResultsScreen is below:
SearchResultsScreen.java
// Set up search array
final String Entries[][] = new String[isbn.length][9];
for(int i = 0; i < isbn.length; i++)
{
searchArray.add(new InventoryItem(isbn[i], InventoryAdapter.getTitleAndAuthorByISBN(isbn[i])));
Entries[i] = InventoryAdapter.getInventoryEntriesByISBN(searchQuery, isbn[i]);
}
Toast.makeText(getApplicationContext(), "searchArray.size()="+searchArray.size(), Toast.LENGTH_LONG).show();
// add data in custom adapter
adapter = new CustomAdapter(this, R.layout.list, searchArray);
ListView dataList = (ListView) findViewById(R.id.list);
dataList.setAdapter(adapter);
// On Click ========================================================
dataList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String searchEntries[] = Entries[position];
This is your problem
if(cursor.getCount()<1) // title Not Exist
{
cursor.close();
for(int i = 0; i < 9; i++)
searchEntry[i] = "Not Found";
return searchEntry;
}
cursor.moveToFirst();
cursor.close();
Change to
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
{
String title = cursor.getString(cursor.getColumnIndex("TITLE"));
String author = cursor.getString(cursor.getColumnIndex("AUTHOR"));
//combine variables into one String
searchEntry = title + " / " + author;
}
public String[] getInventoryEntriesByISBN(String search, String ISBN)
{
String[] searchEntry = new String [9];
//Query
String query = "select * from INVENTORY where ISBN = ?";
Cursor cursor = db.rawQuery(query, new String[] {ISBN});
Add SQLiteDatabase db = this.getWritableDatabase(); in this code before executing the raw Query