I am building an SQLite DB. One of the tables consists of 2 columns - term and definition.
My question is : How can I query the DB, in order the pair term-definition to be returned in order to be able to insert the data in the activity after that (the term and data are in ExpandableListView, the term is the Key, the data - the value).
Here is the code of the data source so far:
public class TermDataSource extends DAO {
//constants
public static final String TABLE_NAME = "terms";
public static final String TERM = "term";
public static final String DEFINITION = "definition";
//columns in the table
public static final int FIELD_ID_ID = 0;
public static final int FIELD_ID_TERM = 1;
public static final int FIELD_ID_DEFINITION = 2;
public TermDataSource (Context context){
super(context);
}
private String [] selectFields = {_ID, TERM, DEFINITION};
public Cursor getTermsData(){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, selectFields, null, null, null, null, null);
return cursor;
}
public List<Term> getTerms(){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, selectFields, null, null, null, null, null);
List<Term> terms = new ArrayList<Term>();
if(cursor!=null){
Term term = null;
while(cursor.moveToNext()){
term = getTermFromCursor(cursor);
terms.add(term);
}
cursor.close();
}
db.close();
return terms;
}
private Term getTermFromCursor (Cursor cursor){
Term term = new Term();
term.setTermId(cursor.getInt(FIELD_ID_ID));
term.setTerm(cursor.getString(FIELD_ID_TERM));
term.setDefinition(cursor.getString(FIELD_ID_DEFINITION));
return term;
}
}
Create a folder res>raw and put youfile.csv in that folder.
Use this method to insert data in Your Database from CSV file.
public void insertCSVData(Activity activity, InputStream is, String tableName) {
String colunmNames = null, str1 = null;
open();
try {
BufferedReader buffer = new BufferedReader(new InputStreamReader(is));
String line = "";
String str2 = ");";
db.beginTransaction();
int i = 0;
while ((line = buffer.readLine()) != null) {
i++;
if (i == 1) {
colunmNames = line;
str1 = "INSERT INTO " + tableName + " (" + colunmNames + ") values (";
} else {
StringBuilder sb = new StringBuilder(str1);
String[] str = line.split(",");
for (int h = 0; h < str.length; h++) {
if (h == str.length - 1) {
sb.append("'" + str[h] + "'");
} else {
sb.append("'" + str[h] + "',");
}
}
sb.append(str2);
db.execSQL(sb.toString());
}
}
db.setTransactionSuccessful();
db.endTransaction();
} catch (Exception e) {
close();
e.printStackTrace();
}
close();
}
Call this method by the below code :
insertCSVData(Activity.this, getResources().openRawResource(R.raw.yourfile),"Your Table Name");
I want to return all values of dbManagement.ORIGINATING_ADDRESS from this function but it just gives me last one value to blockedNumber. I know it'll give last one value but how can i get all value. kindly help
public String selectBlockedNumbers() {
Cursor cursor = dbManagement.selectBlockedNumbers();
String blockedNumber = null;
cursor.moveToFirst();
for(int i = 0; i < cursor.getCount(); i++) {
blockedNumber = cursor.getString(cursor.getColumnIndex(dbManagement.ORIGINATING_ADDRESS));
cursor.moveToNext();
}
Toast.makeText(this, blockedNumber, Toast.LENGTH_LONG).show();
return blockedNumber;
}
In
Cursor cursor = dbManagement.selectBlockedNumbers();
the function selectBlockedNumbers() consist of following query:
cursor = db.rawQuery("SELECT " + ORIGINATING_ADDRESS + " FROM " + TABLE_BLOCK_LIST, null);
When the for-loop runs for the last time, blockedNumbers will contain the last number retrieved. So, instead of returning a String, rather returns a List<String>. In that case your code should change into
public List<String> selectBlockedNumbers() {
Cursor cursor = dbManagement.selectBlockedNumbers();
List<String> blockedNumbers = new ArrayList<String>();
cursor.moveToFirst();
for(int i = 0; i < cursor.getCount(); i++) {
String blockedNumber = cursor.getString(cursor.getColumnIndex(dbManagement.ORIGINATING_ADDRESS));
blockedNumbers.add(blockedNumber);
cursor.moveToNext();
}
Toast.makeText(this, blockedNumber, Toast.LENGTH_LONG).show();
return blockedNumbers;
}
In my project getting contacts is taking a long time to load.
What are ways to reduce the time of getting contacts
Assume there are 1000 contacts in my phone.
Right now it is taking more than 2 minutes to load all the contacts
How can I reduce the time to load contacts ?
Any Thoughts?
I referred to the the following link when programming the initial method.
http://www.coderzheaven.com/2011/06/13/get-all-details-from-contacts-in-android/
BETTER SOLUTION HERE.....
private static final String[] PROJECTION = new String[] {
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
.
.
.
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null);
if (cursor != null) {
try {
final int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
final int numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String name, number;
while (cursor.moveToNext()) {
name = cursor.getString(nameIndex);
number = cursor.getString(numberIndex);
}
} finally {
cursor.close();
}
}
CHEERS...:)
Total time will depend upon what fields you are trying to access from the Contacts table.
Accessing less field means less looping , less processing and hence faster results.
Also to speed up your contacts fetch operation you can use the ContentProvideClient instead of calling query on ContentResolver every time. This will make you query the specific table rather than querying first for the required ContentProvider and then to table.
Create an instance of ContentProviderClient
ContentResolver cResolver=context.getContextResolver();
ContentProviderClient mCProviderClient = cResolver.acquireContentProviderClient(ContactsContract.Contacts.CONTENT_URI);
Then reuse this mCProviderClient to get Contacts(data from any ContentProvider) data on your call.
For example in following method, I am accessing only one field.
private ArrayList<String> fetchContactsCProviderClient()
{
ArrayList<String> mContactList = null;
try
{
Cursor mCursor = mCProviderClient.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (mCursor != null && mCursor.getCount() > 0)
{
mContactList = new ArrayList<String>();
mCursor.moveToFirst();
while (!mCursor.isLast())
{
String displayName = mCursor.getString(mCursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
mContactList.add(displayName);
mCursor.moveToNext();
}
if (mCursor.isLast())
{
String displayName = mCursor.getString(mCursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
mContactList.add(displayName);
}
}
mCursor.close();
}
catch (RemoteException e)
{
e.printStackTrace();
mContactList = null;
}
catch (Exception e)
{
e.printStackTrace();
mContactList = null;
}
return mContactList;
}
Load Contact faster like other apps doing.
I have tested this code with multiple contacts its working fine and faster like other apps within 500 ms (within half second or less) I am able to load 1000+ contacts.
Total time will depend upon what fields you are trying to access from the Contacts table.
Mange your query according to your requirement do not access unwanted fields. Accessing less field means less looping , less processing and hence faster results.
Accessing right table in contact it also help to reduce contact loading time.
Query Optimization to load contact more faster use projection
String[] projection = {
ContactsContract.Data.MIMETYPE,
ContactsContract.Data.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.PHOTO_URI,
ContactsContract.Contacts.STARRED,
ContactsContract.RawContacts.ACCOUNT_TYPE,
ContactsContract.CommonDataKinds.Contactables.DATA,
ContactsContract.CommonDataKinds.Contactables.TYPE
};
Selection and selection argument
String selection = ContactsContract.Data.MIMETYPE + " in (?, ?)" + " AND " /*+ ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + 1 + "' AND "*/ +
ContactsContract.Data.HAS_PHONE_NUMBER + " = '" + 1 + "'";
String[] selectionArgs = {
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
};
To order contacts alphabetically use following code
try {
Collections.sort(listview_address, new Comparator<ContactBook>() {
#Override
public int compare(ContactBook lhs, ContactBook rhs) {
return lhs.name.toUpperCase().compareTo(rhs.name.toUpperCase());
}
});
} catch (Exception e) {
e.printStackTrace();
}
Following is complete source code
public void initeContacts() {
List<ContactBook> listview_address = new LinkedList<ContactBook>();
SparseArray<ContactBook> addressbook_array = null;
{
addressbook_array = new SparseArray<ContactBook>();
long start = System.currentTimeMillis();
String[] projection = {
ContactsContract.Data.MIMETYPE,
ContactsContract.Data.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.PHOTO_URI,
ContactsContract.Contacts.STARRED,
ContactsContract.RawContacts.ACCOUNT_TYPE,
ContactsContract.CommonDataKinds.Contactables.DATA,
ContactsContract.CommonDataKinds.Contactables.TYPE
};
String selection = ContactsContract.Data.MIMETYPE + " in (?, ?)" + " AND " /*+ ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + 1 + "' AND "*/ +
ContactsContract.Data.HAS_PHONE_NUMBER + " = '" + 1 + "'";
String[] selectionArgs = {
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
};
String sortOrder = ContactsContract.Contacts.SORT_KEY_ALTERNATIVE;
Uri uri = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
uri = ContactsContract.CommonDataKinds.Contactables.CONTENT_URI;
} else {
uri = ContactsContract.Data.CONTENT_URI;
}
// we could also use Uri uri = ContactsContract.Data.CONTENT_URI;
// we could also use Uri uri = ContactsContract.Contact.CONTENT_URI;
Cursor cursor = getActivity().getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
final int mimeTypeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE);
final int idIdx = cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID);
final int nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
final int dataIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.DATA);
final int photo = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.PHOTO_URI);
final int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.TYPE);
final int account_type = cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE);
while (cursor.moveToNext()) {
int contact_id = cursor.getInt(idIdx);
String photo_uri = cursor.getString(photo);
String contact_name = cursor.getString(nameIdx);
String contact_acc_type = cursor.getString(account_type);
int contact_type = cursor.getInt(typeIdx);
String contact_data = cursor.getString(dataIdx);
ContactBook contactBook = addressbook_array.get(contact_id);
/* if (contactBook == null) {
//list contact add to avoid duplication
//load All contacts fro device
//to add contacts number with name add one extra veriable in ContactBook as number and pass contact_data this give number to you (contact_data is PHONE NUMBER)
contactBook = new ContactBook(contact_id, contact_name, getResources(), photo_uri, contact_acc_type, "phone number");
addressbook_array.put(contact_id, contactBook);
listview_address.add(contactBook);
}*/
String Contact_mimeType = cursor.getString(mimeTypeIdx);
//here am checking Contact_mimeType to get mobile number asociated with perticular contact and email adderess asociated
if (Contact_mimeType.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
if (contactBook != null) {
contactBook.addEmail(contact_type, contact_data);
}
} else {
if (contactBook == null) {
//list contact add to avoid duplication
//load All contacts fro device
//to add contacts number with name add one extra veriable in ContactBook as number and pass contact_data this give number to you (contact_data is PHONE NUMBER)
contactBook = new ContactBook(contact_id, contact_name, getResources(), photo_uri, contact_acc_type, "phone number");
addressbook_array.put(contact_id, contactBook);
listview_address.add(contactBook);
}
// contactBook.addPhone(contact_type, contact_data);
}
}
cursor.close();
try {
Collections.sort(listview_address, new Comparator<ContactBook>() {
#Override
public int compare(ContactBook lhs, ContactBook rhs) {
return lhs.name.toUpperCase().compareTo(rhs.name.toUpperCase());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
You can use following code in above code that I have commented .It club the the single contact with its multiple number.To get all number associated with single contact use array in Object class.
if (contactBook == null) {
//irst contact add to avoid duplication
//load All contacts fro device
contactBook = new ContactBook(contact_id, contact_name, getResources(), photo_uri, contact_acc_type, "");
addressbook_array.put(contact_id, contactBook);
listview_address.add(contactBook);
}
String Contact_mimeType = cursor.getString(mimeTypeIdx);
//here am checking Contact_mimeType to get mobile number asociated with perticular contact and email adderess asociated
if (Contact_mimeType.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
contactBook.addEmail(contact_type, contact_data);
} else {
contactBook.addPhone(contact_type, contact_data);
}
Object class
public class ContactBook {
public int id;
public Resources res;
public String name;
public String photo;
public String contact_acc_type;
public SparseArray<String> emails;
public SparseArray<String> phones;
/* public LongSparseArray<String> emails;
public LongSparseArray<String> phones;*/
public String header = "";
public ContactBook(int id, String name, Resources res, String photo, String contact_acc_type, String header) {
this.id = id;
this.name = name;
this.res = res;
this.photo = photo;
this.contact_acc_type = contact_acc_type;
this.header = header;
}
#Override
public String toString() {
return toString(false);
}
public String toString(boolean rich) {
//testing method to check ddata
SpannableStringBuilder builder = new SpannableStringBuilder();
if (rich) {
builder.append("id: ").append(Long.toString(id))
.append(", name: ").append("\u001b[1m").append(name).append("\u001b[0m");
} else {
builder.append(name);
}
if (phones != null) {
builder.append("\n\tphones: ");
for (int i = 0; i < phones.size(); i++) {
int type = (int) phones.keyAt(i);
builder.append(ContactsContract.CommonDataKinds.Phone.getTypeLabel(res, type, ""))
.append(": ")
.append(phones.valueAt(i));
if (i + 1 < phones.size()) {
builder.append(", ");
}
}
}
if (emails != null) {
builder.append("\n\temails: ");
for (int i = 0; i < emails.size(); i++) {
int type = (int) emails.keyAt(i);
builder.append(ContactsContract.CommonDataKinds.Email.getTypeLabel(res, type, ""))
.append(": ")
.append(emails.valueAt(i));
if (i + 1 < emails.size()) {
builder.append(", ");
}
}
}
return builder.toString();
}
public void addEmail(int type, String address) {
//this is the array in object class where i am storing contact all emails of perticular contact (single)
if (emails == null) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
emails = new SparseArray<String>();
emails.put(type, address);
/*} else {
//add emails to array below Jelly bean //use single array list
}*/
}
}
public void addPhone(int type, String number) {
//this is the array in object class where i am storing contact numbers of perticular contact
if (phones == null) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
phones = new SparseArray<String>();
phones.put(type, number);
/* } else {
//add emails to array below Jelly bean //use single array list
}*/
}
}}
For loading the contacts with mininum time the optimum solution is to use the concept of projection and selection argument while querying the cursor for contacts.
this can be done in following way
void getAllContacts() {
long startnow;
long endnow;
startnow = android.os.SystemClock.uptimeMillis();
ArrayList arrContacts = new ArrayList();
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Cursor cursor = ctx.getContentResolver().query(uri, new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.Contacts._ID}, selection, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
cursor.moveToFirst();
while (cursor.isAfterLast() == false) {
String contactNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
int phoneContactID = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID));
int contactID = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Log.d("con ", "name " + contactName + " " + " PhoeContactID " + phoneContactID + " ContactID " + contactID)
cursor.moveToNext();
}
cursor.close();
cursor = null;
endnow = android.os.SystemClock.uptimeMillis();
Log.d("END", "TimeForContacts " + (endnow - startnow) + " ms");
}
With above method it took 400ms(less than second) to load contacts where as in normall way it was taking 10-12 sec.
For details imformation this post might help as i took help from it
http://www.blazin.in/2016/02/loading-contacts-fast-from-android.html
If your time increases with your data, then you are probably running a new query to fetch phones/emails for every contact. If you query for the phone/email field using ContactsContract.CommonDataKinds.Phone.NUMBER, then you will just retrieve 1 phone per contact.
The solution is to project the fields and join them by contact id.
Here is my solution in Kotlin (extracting id, name, all phones and emails):
val projection = arrayOf(
ContactsContract.Data.MIMETYPE,
ContactsContract.Data.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Contactables.DATA
)
val selection = "${ContactsContract.Data.MIMETYPE} in (?, ?)"
val selectionArgs = arrayOf(
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
val contacts = applicationContext
.contentResolver
.query(ContactsContract.Data.CONTENT_URI, projection, selection, selectionArgs, null)
.run {
if (this == null) {
throw IllegalStateException("Cursor null")
}
val contactsById = mutableMapOf<String, LocalContact>()
val mimeTypeField = getColumnIndex(ContactsContract.Data.MIMETYPE)
val idField = getColumnIndex(ContactsContract.Data.CONTACT_ID)
val nameField = getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)
val dataField = getColumnIndex(ContactsContract.CommonDataKinds.Contactables.DATA)
while (moveToNext()) {
val mimeType = getString(mimeTypeField)
val id = getString(idField)
var contact = contactsById[id]
if (contact == null) {
val name = getString(nameField)
contact = LocalContact(id = id, fullName = name, phoneNumbers = listOf(), emailAddresses = listOf())
}
val data = getString(dataField)
when(getString(mimeTypeField)) {
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE ->
contact = contact.copy(emailAddresses = contact.emailAddresses + data)
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE ->
contact = contact.copy(phoneNumbers = contact.phoneNumbers + data)
}
contactsById[id] = contact
}
close()
contactsById.values.toList()
}
And for reference, my LocalContact model:
data class LocalContact(
val id: String,
val fullName: String?,
val phoneNumbers: List<String>,
val emailAddresses: List<String>
)
I think this is a better solution:
public ContentValues getAllContacts() {
ContentValues contacts = new ContentValues();
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cur != null && cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (cur.getInt(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
if (pCur != null) {
while (pCur.moveToNext()) {
String phoneNo = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contacts.put(phoneNo, name);
}
pCur.close();
}
}
}
cur.close();
}
return contacts;
}
for use it you need to call this lines once:
ContentValues contacts = new ContentValues();
contacts = getAllContacts();
and when you want to get contact name by number, just use:
String number = "12345";
String name = (String) G.contacts.get(number);
this algorithm is a bit faster...
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 tried to load a list of values from a table, but the cursor doesn't find the columns?
The Code which is buggy:
public final AccessToken[] fetchAccessTokenByServerId(final long serverId) {
final Cursor c = db.query(
ACCESS_TOKEN_TABLE,
new String[] { ACCESS_TOKEN_COL_ID, ACCESS_TOKEN_COL_VALUE },
ACCESS_TOKEN_COL_SERVER_ID + "=?",
new String[] { Long.toString(serverId) },
null,
null,
null);
AccessToken[] result = new AccessToken[c.getCount()];
for (int i = 0; i < result.length; i++) {
long id = c.getLong(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_ID));
String value = c.getString(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_VALUE));
result[i] = new AccessToken(value, id, serverId);
c.moveToNext();
}
return result;
}
public static final String COL_ID = "_id";
public static final String ACCESS_TOKEN_TABLE = "accesstoken";
public static final String ACCESS_TOKEN_COL_ID = COL_ID;
public static final String ACCESS_TOKEN_COL_SERVER_ID = "server_id";
public static final String ACCESS_TOKEN_COL_VALUE = "value";
But the first two statements in the for-loop fails:
Index -1 is requested, with a size of
1
The table exists with the columns: _id (= int), server_id (= int) and value (= string)
There is one entry: 1, 1, test
The parameter of the function is 1.
Sincerely
xZise
Just after initializing your cursor, do this:
c.moveToFirst();
In this part of the code I recommend it this way
Original:
AccessToken[] result = new AccessToken[c.getCount()];
for (int i = 0; i < result.length; i++) {
long id = c.getLong(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_ID));
String value = c.getString(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_VALUE));
result[i] = new AccessToken(value, id, serverId);
c.moveToNext();
}
Modified:
if (c.moveToFirst()){
int rowCount = c.getCount();
AccessToken[] result = new AccessToken(rowCount);
int recCount = 0;
while (!c.isAfterLast()){
long id = c.getLong(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_ID));
String value = c.getString(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_VALUE));
result[recCount++] = new AccessToken(value, id, serverId);
c.moveToNext();
}
c.close(); // <-- IMPORTANT!!!!
}