How to put this cursor data in ArrayLists - AndroidStudio - android

I have a cursorLoader which returns a cursor with this data:
0 {
email=bogdan#gmail.com
about=Party
}
1 {
email=bogdan1#gmail.com
about=Paaarty
}
2 {
email=bogdan2#gmail.com
about=activity 2
}
3 {
email=bogdan3#gmail.com
about=activity 3
}
4 {
email=bogdan4#gmail.com
about=activity 5
}
How can I save the emails in an ArrayList called emails and the about in an ArrayList called about. I've been trying different things with the cursor but most of the time I just get outOfBounds.
Edit: This is the line that prints it like that:
Log.v("Cursor Object", DatabaseUtils.dumpCursorToString(cursor));

If you want to do it your way maybe this method would help (provided that you supply two empty ArrayList) ?
private void populateLists(Cursor cursor, List<String> emails,
List<String> about) throws IllegalArgumentException {
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
do {
emails.add(cursor.getString(cursor
.getColumnIndexOrThrow("email")));
about.add(cursor.getString(cursor
.getColumnIndexOrThrow("about")));
} while (cursor.moveToNext());
}
}

Related

Cursor variable reuse

I'm using a cursor in a while loop to execute multiple queries on my database, so each time Content Resolver returns new cursor object instance. I am uncertain about proper way I should reuse the cursor during each iteration of the loop:
Close it once, after all operations being performed
Cursor c;
try {
while(condition) {
c = Context.getContentResolver().query(...);
// fetching values
}
} finally {
if (c != null) {
c.close()
}
}
Close it at the end of each iteration
Cursor c;
try {
while(condition) {
c = Context.getContentResolver().query(...);
// fetching values
if (c != null) {
c.close()
}
}
} finally {
if (c != null) {
c.close()
}
}
Create new cursor variable inside while loop
while(condition) {
Cursor c = Context.getContentResolver().query(...);
try {
// fetching values
} finally {
if (c != null) {
c.close()
}
}
}
?
Case 1 is bad since you're assigning a new cursor in your loop and you only get to close the last assigned cursor.
Case 2 and 3 are very similar but I prefer case 3 because with case 2 you can break out of your loop unexpectedly but with case 3 you keep the cursor in the loop scope and the loop can keep running.
In your examples the third variant is most useful because you open-close the same Cursor object in each loop. You lost nothing: niether memory leaks no app+db crashes.

Update item ID when deleting

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

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;

problems with cursor and getting data?

I have created a table and trying to fetch data from it using a cursor as follow:
public Cursor getcontent() {
Cursor d = database.query(DatabaseHandler.Table_Name2,allColumns,selection, null, null,null,null);
return d;
}
Cursor r = X.getcontent();
if (r.getCount() > 0) {
r.moveToFirst();
do {
String id = r.getString(r.getColumnIndex("content_id"));
al.add(id);
MainActivity.tt1.append("\n");
MainActivity.tt1.append(id);
} while (r.moveToNext()==true);
r.close();
} else {
Log.i("TAG"," No value found");
}
}
I am showing the result in the TextView to see what data it is fetched. My problem is when I run this code sometimes it shows the data in the TextView, whatever it has fetched and sometimes it doesn't. Its a 50:50 ratio, according to me it should show fetched values every time as data is fetched every time I don't know what is wrong here, can someone tell me what's the issue here?
Check Whether Cursor you are getting is Null or not . and if yes then What is the Count of Cursor. you can Do it by Below Way.
Cursor r = X.getcontent();
if ((r != null) && (r.getCount() > 0)) {
r.moveToFirst();
do {
String id = r.getString(r.getColumnIndex("content_id"));
al.add(id);
MainActivity.tt1.append("\n");
MainActivity.tt1.append(id);
} while (r.moveToNext());
r.close();
} else {
Log.i("TAG"," No value found inside Cursor");
}
try like this
Cursor r = X.getcontent();
try {
if (r.moveToFirst()) {
do {
String id = r.getString(r.getColumnIndex("content_id"));
al.add(id);
MainActivity.tt1.append("\n");
MainActivity.tt1.append(id);
} while (r.moveToNext());
}
} finally {
if(r!=null) {
r.close();
}
}

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