From my table I want to get the number of each row. For example, if I have 5 rows, I want to get 1,2,3,4,5.
I have this method, but I get only the number 1:
private void listaAvvio() {
SQLiteDatabase db = new DatabaseHelper(getActivity()).getReadableDatabase();
final List<Dettaglio1> dettagli1 = new ArrayList<Dettaglio1>();
String tabella_op = "SELECT .....";
Cursor cur = db.rawQuery(tabella_op, null);
while (cur.moveToNext()) {
Dettaglio1 d1 = new Dettaglio1();
d1.id = cur.getString(0);
d1.FIELD1= cur.getString(1);
d1.FIELD2= cur.getString(2);
d1.FIELD3= cur.getString(3);
d1.NUMBER_OF_SINGLE_ROW++;
dettagli1.add(d1);
}
cur.close();
db.close();
...
}
You are creating a new Dettaglio1 object in every loop iteration, so the NUMBER_OF_SINGLE_ROW in that object is always the same.
You have to use a separate variable to remember the row number:
int row_no = 0;
while (cur.moveToNext()) {
Dettaglio1 d1 = new Dettaglio1();
d1.id = cur.getString(0);
...
row_no++;
d1.NUMBER_OF_SINGLE_ROW = row_no;
dettagli1.add(d1);
}
Related
I have the following function in android studio, which is supposed to return a sqlite cursor.
The problem comes in the selectionArgs argument. Whenever I am passing more than one value to it, it returns a cursor with 0 records.
public Cursor getCursor(String strListWhere, String strTable, String strCols) {
String strColsToReturn = mySqliteHandler.getWhereColNamesFromJsonString(strListWhere);
String strArgs = mySqliteHandler.getWhereColArgsFromJsonString(strListWhere);
Log.d(TAG, "qqqq9: " + strArgs);
String strTableName = strTable;
String[] strColumnsToReturn = { strCols };
String strSelectWhere = strColsToReturn ;
String[] strSelectArgs = { strArgs };
Cursor csrResult = sqLiteDatabase.query(true, strTableName, strColumnsToReturn, strSelectWhere, strSelectArgs, null, null, null, null);
Log.d(TAG, "qqqq9: " + csrResult.getCount());
return csrResult;
}
The value in strColsToReturn is animal_class = ? and province_name = ?
The value in strArgs is Bird, KwaZulu-Natal
So I want it to be animal_class = 'Bird' and province_name = 'KwaZulu-natal'
When I only pass one value it works, for example
The value in strColsToReturn is animal_class = ?
The value in strArgs is Bird
Can anyone assist?
EDIT: the following code works:
public Cursor getCursor(String strListWhere, String strTable, String strCols) {
String strColsToReturn = mySqliteHandler.getWhereColNamesFromJsonString(strListWhere);
List<String> arrWhere = new ArrayList<String>();
arrWhere = mySqliteHandler.getWhereArray(strListWhere);
String[] finalValue = new String[ arrWhere.size() ];
arrWhere.toArray( finalValue );
String strTableName = strTable;
String[] strColumnsToReturn = { strCols };
String strSelectWhere = strColsToReturn ;
Cursor csrResult = sqLiteDatabase.query(true, strTableName, strColumnsToReturn, strSelectWhere, finalValue, null, null, null, null);
return csrResult;
}
The value for strColumnsToReturn should be an array with the names of the columns that you want returned, like:
new String[] {column1, column2, column3}
where column1, column2, column3 are strings.
The value for strSelectWhere should be the string:
"animal_class = ? and province_name = ?"
and the value of strSelectArgs should be a string array with the parameters that you pass to each of the ? placeholders of strSelectWhere:
new String {"Bird", "KwaZulu-Natal"}
You can find more here
Hi i had fetched all datas from the database and now i have to filter the data by matching its email id and display the filtered data in the listview but i am facing problem as i am getting the first value repeated again and again. please help me i am new in android and i am stuck on this.
I am also sending my code.
for(int i = 0;i<C_parts.size();i++){
if(C_parts.get(i).email.toString().equals(Global.useremailid.toString()))
Cursor cursor = db.query(TABLE_ACCOUNT, new String[] { ACCT_NAME,
ACCT_HEAD_NAME, OPEN_BAL, EMAIL }, EMAIL + "=?",
new String[] { String.valueOf(Global.useremailid) }, null, null, null,
null);
System.out.println("value of cursor:->"+cursor);
if (cursor != null)
cursor.moveToNext();
String acc_name = cursor.getString(0);
String acc_head_name = cursor.getString(1);
String openbal = cursor.getString(2);
String amail=cursor.getString(3);
System.out.println("bfr accountid:->"+acc_name);
System.out.println("bfr accountname:->"+acc_head_name);
System.out.println("bfr headname:->"+openbal);
C_parts1.add(new Account(acc_name,acc_head_name,openbal, amail));
}
}
c_adapter = new CustomAdapter(this, R.layout.list_item, C_parts1);
if (list1 == null)
list1 = (ListView) findViewById(R.id.lv1);
list1.setAdapter(c_adapter);
registerForContextMenu(list1);
list1.invalidate();
}
Change
for(int i = 0;i<C_parts.size();i++){
if(C_parts.get(i).email.toString().equals(Global.useremailid.toString()))
to
for(int i = 0;i<C_parts.size();i++){
if(C_parts.get(i).email.toString().equals(Global.useremailid.toString())) {
Your Cursor code will be executed only if equals, but the other code will be always executed and since the cursor is the same of the previous iteration it will repeat the same data.
It's because if you don't add { } after a if only the first line will be part of the if.
Same here
if (cursor != null)
cursor.moveToNext();
String acc_name = cursor.getString(0);
String acc_head_name = cursor.getString(1);
String openbal = cursor.getString(2);
String amail=cursor.getString(3);
System.out.println("bfr accountid:->"+acc_name);
System.out.println("bfr accountname:->"+acc_head_name);
System.out.println("bfr headname:->"+openbal);
C_parts1.add(new Account(acc_name,acc_head_name,openbal, amail));
}
add a { after if (cursor != null) and make sure every {} are OK.
while(cursor.moveToNext()){
String acc_name = cursor.getString(0);
String acc_head_name = cursor.getString(1);
String openbal = cursor.getString(2);
String amail=cursor.getString(3);
System.out.println("bfr accountid:->"+acc_name);
System.out.println("bfr accountname:->"+acc_head_name);
System.out.println("bfr headname:->"+openbal);
System.out.println("bfr email:->"+amail);
C_parts1.add(new Account(acc_name,acc_head_name,openbal, amail));
System.out.println("value of c_parts1 on for loop:->"+C_parts1.toString());
}
I had this problem a couple of months before and now it is time to get back to it.
I query the phone's calllog into a database, but it takes around 30 seconds to populate the table. It looks like querying takes around 1 sec, but the population takes forever, although the phone stores only the last 500 calls. Why is it so slow? Am I doing something wrong?
I test it only on my phone, since I have only 8 items in the emulator's calllog.
final String[] projection = null;
HotOrNot infoA = new HotOrNot(Charts.this);
infoA.open();
infoA.createtable_Calls();
infoA.deleteAllEntries_Calls();
infoA.close();
final Context context = getApplicationContext();
final String selection = null;
final String sortOrder = android.provider.CallLog.Calls.DATE + " DESC";
Cursor c = context.getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI, projection, selection, null, sortOrder);
while (c.moveToNext()) {
String callLogID = c.getString(c.getColumnIndex(android.provider.CallLog.Calls._ID));
int numberColumn = c.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
int dateColumn = c.getColumnIndex(android.provider.CallLog.Calls.DATE);
int typeColumn = c.getColumnIndex(android.provider.CallLog.Calls.TYPE);
int durationColumn = c.getColumnIndex(android.provider.CallLog.Calls.DURATION);
int person = c.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
String number = c.getString(numberColumn);
int duration = c.getInt(durationColumn);
String personname = c.getString(person);
long callDate = c.getLong(dateColumn);
int callType = c.getInt(typeColumn);
if (duration >= 0)
{
switch (callType) {
case 1:
duration_in = duration;
duration_out = 0;
break;
case 2:
duration_out = duration;
duration_in = 0;
break;
case 3:
duration_in = 0;
duration_out = 0;
break;
}
}
//Here comes the slow part
HotOrNot info = new HotOrNot(Charts.this);
info.open();
info.pop
ulate_Calls(personname, number, String.valueOf(callType), Integer.toString(duration), Long.toString(callDate), callLogID);
info.close();
}
This is the populating function:
public long populate_Calls(String name, String phone, String type, String duration, String date, String contactid) {
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, name);
cv.put(KEY_PHONE, phone);
cv.put(KEY_TYPE, type);
cv.put(KEY_DURATION, duration);
cv.put(KEY_DATE, date);
cv.put(KEY_CONTACTID, contactid);
return ourDatabase.insert(DATABASE_TABLE, null, cv);
}
EDIT:
To Andreas Ka's and twaddington's answers I modified the population method in the SQLiteOpenHelper class, but unfortunately it did not make a difference:
public long populate_Calls(String name, String phone, String type, String duration, String date, String contactid) {
ContentValues cv = new ContentValues();
try {
ourDatabase.beginTransaction();
cv.put(KEY_NAME, name);
cv.put(KEY_PHONE, phone);
cv.put(KEY_TYPE, type);
cv.put(KEY_DURATION, duration);
cv.put(KEY_DATE, date);
cv.put(KEY_CONTACTID, contactid);
ourDatabase.yieldIfContendedSafely();
ourDatabase.setTransactionSuccessful();
} finally {
ourDatabase.endTransaction();
}
return ourDatabase.insert(DATABASE_TABLE, null, cv);
}
EDIT2:
Posting the whole code based on Babibu and twaddington's answers. By the way the temp_ arrays are now LinkedLists, but that does not make a difference in time.
final String[] projection = null;
final Context context = getApplicationContext();
final String selection = null;
final String sortOrder = android.provider.CallLog.Calls.DATE + " DESC";
lv1 = (ListView) findViewById(R.id.ListView02);
HotOrNot infoA = new HotOrNot(Calllogs.this);
infoA.open();
infoA.createtable_Calls();
infoA.deleteAllEntries_Calls();
infoA.close();
pd = ProgressDialog.show(Calllogs.this, "Please wait..", "Loading data, it may take a few" +
" seconds based on the number of data.", false, true);
Cursor c = context.getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI, projection, selection, null, sortOrder);
while (c.moveToNext()) {
String callLogID = c.getString(c.getColumnIndex(android.provider.CallLog.Calls._ID));
int numberColumn = c.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
int dateColumn = c.getColumnIndex(android.provider.CallLog.Calls.DATE);
int typeColumn = c.getColumnIndex(android.provider.CallLog.Calls.TYPE);
int durationColumn = c.getColumnIndex(android.provider.CallLog.Calls.DURATION);
int person = c.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
String number = c.getString(numberColumn);
int duration = c.getInt(durationColumn);
String personname = c.getString(person);
long callDate = c.getLong(dateColumn);
int callType = c.getInt(typeColumn);
if (duration >= 0)
{
switch (callType) {
case 1:
duration_in = duration;
duration_out = 0;
break;
case 2:
duration_out = duration;
duration_in = 0;
break;
case 3:
duration_in = 0;
duration_out = 0;
break;
}
}
temp_name.add(personname);
temp_num.add(number);
temp_type.add(String.valueOf(callType));
temp_dur.add(Integer.toString(duration));
temp_date.add(String.valueOf(callDate));
temp_id.add(callLogID);
} //end of while loop
HotOrNot infotemp = new HotOrNot(Calllogs.this);
infotemp.open();
for (int i=0; i<temp_name.size(); i++)
{
infotemp.populate_Calls(temp_name.get(i), temp_num.get(i), temp_type.get(i), temp_dur.get(i), temp_date.get(i), temp_type.get(i));
}
infotemp.close();
SOLUTION
I am posting twaddington's solution, which reduced the time from 8 seconds to less than 2:
HotOrNot infotemp = new HotOrNot(Calllogs.this);
infotemp.open();
// Get our database. You can do this however you wish, but
// it seems like since the database is contained in your `HotOrNot`
// object, it would be best to simply add a getter method to
// the class.
SQLiteDatabase db = infotemp.getDatabase();
try {
// Begin our transaction
db.beginTransaction();
// Loop over the array of calls and
// perform a db insert for each.
for (int i=0; i<temp_name.size(); i++) {
// Yield the database lock if requested. This will
// temporarily suspend our loop, but it should
// continue when the lock is opened.
db.yieldIfContendedSafely();
infotemp.populate_Calls(temp_name.get(i), temp_num.get(i),
temp_type.get(i), temp_dur.get(i), temp_date.get(i), temp_type.get(i));
}
// Mark our transaction as successful!
db.setTransactionSuccessful();
} finally {
// Always end the transaction!
db.endTransaction();
}
infotemp.close();
For each change that you make to the SQLite database a series of complicated
steps occur, including the creation of a journal file to rollback the
change if an error occurs. You can wrap your series of updates in a database
transaction to force SQLite to treat the entire series as a single operation.
This will be much more efficient.
try {
db.beginTransaction();
while (c.moveToNext()) {
// Yield the database lock if requested
db.yieldIfContendedSafely();
// Add your code here!
// ...
// Perform the database insert
populate_Calls(...);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
Try to use a single transaction for the whole method:
http://notes.theorbis.net/2010/02/batch-insert-to-sqlite-on-android.html
You are inserting while browsing, this makes locks on your database. You need first finish your while loop and and only then insert it in your database. Just keep the data in same temporary linked List(better then array in your case, coz it got fast inserts)
I have a database name "CUED" (sqlite Android)it have a table HELLO which contain a column NAME I can get the value to String from that column.
Let me show you my code section
myDB =hello.this.openOrCreateDatabase("CUED", MODE_PRIVATE, null);
Cursor crs = myDB.rawQuery("SELECT * FROM HELLO", null);
while(crs.moveToNext())
{
String uname = crs.getString(crs.getColumnIndex("NAME"));
System.out.println(uname);
}
It will print the value one by one. Now what I need is that I want to get the column values from database and so that I can store it in a String Array.
You already did the hard part... the array stuff is pretty simple:
String[] array = new String[crs.getCount()];
int i = 0;
while(crs.moveToNext()){
String uname = crs.getString(crs.getColumnIndex("NAME"));
array[i] = uname;
i++;
}
Whatever, I always recommend to use collections in cases like this:
List<String> array = new ArrayList<String>();
while(crs.moveToNext()){
String uname = crs.getString(crs.getColumnIndex("NAME"));
array.add(uname);
}
In order to compare the arrays, you can do things like this:
boolean same = true;
for(int i = 0; i < array.length; i++){
if(!array[i].equals(ha[i])){
same = false;
break;
}
}
// same will be false if the arrays do not have the same elements
String[] str= new String[crs.getCount()];
crs.movetoFirst();
for(int i=0;i<str.length();i++)
{
str[i] = crs.getString(crs.getColumnIndex("NAME"));
System.out.println(uname);
crs.movetoNext();
}
Enjoy it
This is my code that returns arraylist contains afield value:
public ArrayList<String> getAllPlayers() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cur = db.rawQuery("SELECT " + serailnumber + " as _id, " + title
+ " from " + table, new String[] {});
ArrayList<String> array = new ArrayList<String>();
while (cur.moveToNext()) {
String uname = cur.getString(cur.getColumnIndex(title));
array.add(uname);
}
return array;
}
I have an application where I want to use the values returned from an SQL query against a database in my application. I want to use attach these values to a uri that links to a script on remote host. I am doing a call to the method to retrieve the values, after which I will now extract them. The issue is that I am facing a challenge in going about this. I know a bit of php and what I want in android is done like this in php:
....(preceding code)...$row['email'];
and I can now assign a variable e.g. $email=$row['email'];
How can I do this in android?
I don't want a cursor returned, just the values of the columns as strings.
Below is my code (I will need help to retrieve the password column)
public String[] selectAll()
{
Cursor cursor = db.query(DB_TABLE_NAME, new String[] { "email","password"},null, null, null, null,null);
if(cursor.getCount() >0)
{
String[] str = new String[cursor.getCount()];
int i = 0;
while (cursor.moveToNext())
{
str[i] = cursor.getString(cursor.getColumnIndex("email"));
i++;
}
return str;
}
else
{
return new String[] {};
}
}
I need help on inserting the "password" column so that it will be returned with the email.
try this way
String[][] str = new String[cursor.getCount()][cursor.getColumnCount()];
while (cursor.moveToNext())
{
for(int j=0;j<cursor.getColumnCount();j++)
str[i][j] = cursor.getString(j); /// may be this column start with the 1 not with the 0
i++;
}
you need to store this in two dimenstion array for row wise and column wise
but if this will give only one result everytime
String[] str = new String[cursor.getColumnCount()]; // here you have pass the total column value
while (cursor.moveToNext())
{
str[0] = cursor.getString(cursor.getColumnIndex("email"));
str[1] = cursor.getString(cursor.getColumnIndex("password"));
}
You should change your design like this
public Cursor selectAll() {
Cursor cursor = db.query(DB_TABLE_NAME, new String[] { "email","password"},null, null, null, null,null);
return cursor;
}
and use the selectAll function like this
Cursor cursor=selectAll();
String[] mail = new String[cursor.getCount()];
String[] pass = new String[cursor.getCount()];
int i=0;
while (cursor.moveToNext())
{
mail[i] = cursor.getString(cursor.getColumnIndex("email"));
pass[i] = cursor.getString(cursor.getColumnIndex("password"));
i++;
}