Update item ID when deleting - android

I have 5 empty TextViews where I add the names. After adding a name, it is stored in a database. The database consist on 2 columns, the item ID and the item NAME. This is an example of what I'm doing:
- Mark1 //ID=1, NAME= Mark1
- Mark2 //ID=2, NAME= Mark2
- Mark3 //ID=3, NAME= Mark3
- Empty
- Empty
I add and edit perfectly the textViews, but I'm facing a problem when deleting. This has something to do with the way I'm getting the values from the database, I'll explain:
Every time the app starts, or I edit, add or delete one element, what I do is get the items from the database, get them into a Map, and copy them into the textviews (whose at a first time are invisible) making visible just the ones that have a name setted.
This is the code I use to do that:
public void getTravelers() {
/*Create map where store items*/
Map<Integer, String> nameList = new HashMap<Integer, String>();
/*Lon in providers query() method to get database's items and save them into the map*/
Cursor c = getContentResolver().query(TravelersProvider.CONTENT_URI, PROJECTION, null, null, null);
if (c.moveToFirst()) {
do {
nameList.put(Integer.parseInt(c.getString(c.getColumnIndex(Travelers._ID))), c.getString(c.getColumnIndex(Travelers.NAME)));
}while(c.moveToNext());
}
if (c != null && !c.isClosed()) {
c.close();
}
/*Check size*/
int size = nameList.size();
if (size >= 1) {
/*Save items in TextViews*/
//TODO: This is the code I should fix
for (int i = 0; i <= size; i++) {
if (i==1) {
traveler1.setText(nameList.get(i).toString());
traveler1.setVisibility(View.VISIBLE);
}
if (i==2) {
traveler2.setText(nameList.get(i).toString());
traveler2.setVisibility(View.VISIBLE);
}
if (i==3) {
traveler3.setText(nameList.get(i).toString());
traveler3.setVisibility(View.VISIBLE);
}
if (i==4) {
traveler4.setText(nameList.get(i).toString());
traveler4.setVisibility(View.VISIBLE);
}
if (i==5) {
traveler5.setText(nameList.get(i).toString());
traveler5.setVisibility(View.VISIBLE);
}
}
}
}
The problem comes in the for loop. Let's supposse that from the items named above, I want to delete Mark2 with ID=2, so then the size of the new Map would be 2, and it would enter to (i == 1) and (i == 2). But when entering to this last one, it would do traveler2.setText(nameList.get(2).toString()); and as seen, there is no element existing with the ID=2 because that is the one that I've deleted and it throws a NPE.
So my question is, what would be the right way to do this without facing this problem?

You should go for switch case other than for loop. Than code will not be in loop.

Finally I get what I need just changing the Key value of the Map that was the same as the ID of the database:
if (c.moveToFirst()) {
int key = 0;
do {
key++;
nameList.put(key, c.getString(c.getColumnIndex(Travelers.NAME)));
}while(c.moveToNext());
}
if (c != null && !c.isClosed()) {
c.close();
}
Basically this way I don't need to change nothing more as now the key value of the Map will match with the Textview position

Related

Android cursor's row value

I want check cursor's row value. If cursor's row value is null I set "" my array's value, if cursor's row value not null i set "1" my array's value. How can i check my cursor's value ?
Cursor okunanlar = v3.GetAllRows();
okunanlar.moveToLast();
for(int i=0;i<10;i++)
{
if("How can i check my cursor's row value in here")
{
kayitlar[i]="";
}
else
{
kayitlar[i]="1";
}
okunanlar.moveToPrevious();
}
Solve problem!
Cursor okunanlar = v3.GetAllRows();
if (okunanlar.getCount() > 0) {
okunanlar.moveToLast();
for (int i = 0; i < (okunanlar.getCount()%10); i++) {
if (okunanlar.isNull(okunanlar.getColumnIndexOrThrow("name"))) {
kayitlar[i] = "";
okunanlar.moveToPrevious();
} else {
kayitlar[i] = okunanlar.getString(okunanlar
.getColumnIndex("name"));
okunanlar.moveToPrevious();
}
}
veriAdaptoru = new ArrayAdapter<String>(TabBar.this,
android.R.layout.simple_expandable_list_item_1,
android.R.id.text1, kayitlar);
Tab3.liste.setAdapter(veriAdaptoru);
}
}
Assuming that you want to check ONE field in your row you can use the following:
if(cursor.isNull(cursor.getColumnIndexOrThrow("column_index") || cursor.getString(cursor.getColumnIndexOrThrow("column_index")).equals("")) to check if it is null or empty.
Where "column_index" is the name of the column in your database
Edit: If what you want is the ROW position just use cursor.getPosition() to get the row position in your cursor.

android loop through database with cursor speed

I have read several posts here on speed issues when looping through a cursor and tried the answers given in these posts such as e.g. do not use getcolumnindex in the loop call this once etc.
However with a database having around 2400 records it takes around 3 to 5 minutes to finish.
The loop is running in an async task method so that it does not hang up the device and the database is handled via a database adapter.
The loop code is as follows :
while (!exportrec.isAfterLast()) {
if ( exportrec.moveToNext() ) {
fulldate = exportnumberformatter(exportrec.getInt(daye))
+"/"+exportnumberformatter(exportrec.getInt(monthe))+"/"
+String.valueOf(exportrec.getInt(yeare));
fulltime = exportnumberformatter(exportrec.getInt(houre))+":"
+exportnumberformatter(exportrec.getInt(mine))+":"
+exportnumberformatter(exportrec.getInt(sece));
noiseid = exportrec.getInt(typee);
exportedinfo += exporttypes[id] +","+exportrec.getString(notee)+","+
fulldate+","+fulltime+" \n" ;
}
}
The exportnumberformatter does the following :
public String exportnumberformatter(int i) {
String result = Integer.toString(i);
if (result.length() >1 ) {
return Integer.toString(i);
}
String zeroprefix = "";
zeroprefix = "0"+result;
return zeroprefix ;
}
The cursor is called as follows before the loop to get the data :
exportrec = MD.GetAllLogs(2, "date_sort");
exportrec.moveToFirst();
The MD is the database adapter and the GetAllLogs Method (this has been played with to try and speed things up and so the date_sort that is used is really ignored here):
public Cursor GetAllLogs(Integer i,String sortfield)
{
String sorted = "";
if (i == 1 ) {
sorted = "DESC";
} else if (i == 2) {
sorted = "ASC";
}
return mDB.query(DB_TABLE, new String[] {COL_ID, COL_TYPE,COL_IMAGE, COL_INFO,COL_IMAGE,COL_HOUR,COL_SEC,COL_MIN,COL_DAY,COL_MON,COL_YEAR,COL_SORT_DATE},
null, null, null, null, COL_ID+" "+sorted);
}
When I created the table in the database it had no indexes so I created these via the upgrade method. However they did not error or appear to fail when I did this but what I do not know is A) does the database/table need rebuilding after an index is created and B) how to tell if they have been created ? the two indexes were based on the ID as the first and a field that holds the year month day hour minute second all in on Long Integer.
I am concerned that the loop appears to be taking this long to read through that many records.
Update:
rtsai2000's and the suggestion from CL answer has improved the speed from minutes to seconds
Your exportedInfo String is growing and growing. Save the results in an array and Stringify later (such as with StringBuilder).
You are not closing your cursor after reading the records.
List<String> exportedInfo = new ArrayList<String>();
Cursor exportrec = GetAllLogs();
try {
while (exportrec.moveToNext()) {
String info = String.format("%s, %s, %02d/%02d/%02d, %02d:%02d:%02d",
exporttypes[id],
exportrec.getString(notee),
exportrec.getInt(daye),
exportrec.getInt(monthe),
exportrec.getInt(yeare),
exportrec.getInt(houre),
exportrec.getInt(mine),
exportrec.getInt(sece));
exportedInfo.add(info);
}
} finally {
exportrec.close();
}
return exportedInfo;

how to ignore null values from the database in comparing values entered by the user in android

I'm trying to save user information in my application. I have Employee number editText and Company EditText. My employee number is not a required field so that means my table can have null values. My problem is when I am comparing if the employee number entered by the user already exist in my database, it also reads the null values when the user do not enter anything on the employee number editText. Can anyone help me do this please?
This is my code where I save all the employee number in an arraylist and remove all the null values
ArrayList<String> employeenumber = databaseAdapter.getEmployeeNumber();
employeenumber.removeAll(Collections.singleton(null));
employeenumber.removeAll(Collections.singleton(""));
What I wanna do is, if the user enter employee number, it will check if the arraylist contains it and if yes, it will all check the company corresponds to it. I need to trap duplicate entry. For example the employee number is 1234 and the company is ABCD, the program must not accept it. Thanks for anyone who could help me.
First check whether the user enter something on employee number editText. Then use int flag to compare it. Try the code below in your main activity:
int flag1 = 0;
if (!Emp.equals(""))
{
ArrayList<String> CompanyandEmp = new ArrayList<String>();
CompanyandEmp = databaseAdapter.getCompanyEmp(Emp);
CompanyandEmp.removeAll(Collections.singleton(""));
for(int i=0;i< CompanyandEmp.size();i++)
{
String cmpemp = CompanyandEmp.get(i).toString();
if(cmpemp.equalsIgnoreCase(companyName))
{
flag1 = 1;
}
}
}
if (flag1 == 0)
{
//as per your requirement
}else{
Toast.makeText(RegistrationActivity.this, "Account info already exist.", Toast.LENGTH_LONG).show();
}
Then in your databaseAdapter:
public ArrayList<String> getCompanyEmp(String emp) {
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<String> companyemp = new ArrayList<String>();
try {
Cursor c = db.query("select CompName FROM projsitemast where Emp='"+emp+"'", null);
if (c != null) {
c.moveToFirst();
for (int j = 0; j < c.getCount(); j++) {
companyemp.add(c.getString(0));
c.moveToNext();
}
c.close();
}
return companyemp;
} catch (Exception e) {
e.printStackTrace();
}
return companyemp;
}

Receiving unknown count of results from SQLite db

Basically this is not a problem in itself, my code works so far.
What I have is a App, that lets a user log in and depending on his ID in the db, he gets displayed his saved notes. For this view I have this part of code:
title = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
MyDbHandler dbh = new MyDbHandler(this);
for(int i = 0; i < 999; i++) {
content = dbh.getNoteTitle(id, i); //getNoteTitle(int, int) returns String
if(content != null && content != "0")
title.add(content);
else
break;
}
list.setAdapter(title);
As I said, this works so far.
Thing is - I am very unhappy with the use of ' break; ' here, as I learned during education, this shouldn't be used.
Is there a smoother way to approach this issue?
Also ' content != "0" ' should be ' ! content.equals("0") ' normally, right? But that one doesn't work then... Why is this?
I am not sure what are you trying to do. First of all you should use "equal" method for Strings. The condition "content != "0" will always be true, because you are comparing 2 different objects. The condition "! content.equals("0")" should return true most of the time (when the value is not "0") and probably you should use the debugger to see exactly what is the value of content.
Second if you want to take all the notes from the database and show them to the user you should have first a method in the SQLiteOpenHelper similar to (it is not efficient to interrogate the database for each item, plus the separation of concerns):
public ArrayList<String> getNotesList (int userID){
SQLiteDatabase db = getWritableDatabase();
Cursor c = db.query(TABLE_NAME, new String[] {MyDbHandler.COLUMN_NOTE_TITLE}, MyDbHandler.userID + "=" + userID,null, null, null, null);
ArrayList<String> list = null;
String noteTitle;
if (c != null && c.moveToFirst())
{
list = new ArrayList<String>(c.getCount());
for (int i = 0; i < c.getCount(); i++)
{
noteTitle = c.getString(c.getColumnIndex(MyDbHandler.COLUMN_SESSION_PATH));
list.add(noteTitle);
c.moveToNext();
}
}
c.close();
db.close();
return list;
I think you should not save notes that you don't want to use (e.g. null or "0"), so instead of checking here, I would check in the addNote method.
For the list initialization you have:
MyDbHandler dbh = new MyDbHandler(this);
ArrayList listData = dbh.getNotesList(id)
if (listData != null && listData.length != 0){
title = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
listData.setAdapter(title);
}
I didn't test the code, but I hope it helps you. Good luck!

Random entries from sqlite database in list view?

I've got a wierd bug. I have created a listview with headings using another listview using this http://jsharkey.org/blog/2008/08/18/separating-lists-with-headers-in-android-09/. Ive populated the headings list with a straight array (there aren't that many) and populated the items listview from a preexisting database.
Both listviews show up fine and the items click through to the relevent selections ok, but there are entries on the list from outside the search parameters.
This is from the class that returns the lists:
private Cursor getBeginnersCursor()
{
this.cursor = null;
try{
this.getmDB();
if(this.mDB == null)
{
System.out.println("mDB = null");
}
this.cursor = mDB.query(TABLE_NAME,new String[]{KEY_ID,GAME_NAME}, "_id > 11 AND _id < 35",
null,null,null,null);
if(this.cursor != null)
{
this.cursor.moveToNext();
}
mDB.close();
return this.cursor;
}catch(SQLException e){
throw e;
}
}
private List<String> getBeginnersArrayList()
{
this.getmDB();
this.cursor = this.getBeginnersCursor();
String result;
for(this.cursor.moveToFirst(); !this.cursor.isAfterLast();this.cursor.moveToNext())
{
result = this.cursor.getString(1) + "\n";
this.beginnersArrayList.add(result);
}
this.cursor.close();
return beginnersArrayList;
}
Many thanks in advance.
Ok I worked it out. SQLite doesnt seem to treat text integer values the same as Integer values, so it was mixing the id 1 in between id's 9 and 10 and so on. Ive created another column to define the sections instead.

Categories

Resources