how to query the contacts content provider given a number - java

I want to query the contacts provider in android with a given number.
I have something like this
String queryString= "NUMBER='" + msgs[i].getOriginatingAddress() + "'";
Uri contacts = ContactsContract.CommonDataKinds.Phone.CONTENT_URI ;
Cursor cursor = context.getContentResolver().query(
contacts,
null, queryString, null,
null
);
then how do I go upon going to the first row? Like this?
cursor.getString(<how do i reference to the first row?>);
right?

Try this :
String strNumber= "7777777777";
String queryString= "NUMBER='" + strNumber + "'";
Uri contacts = ContactsContract.CommonDataKinds.Phone.CONTENT_URI ;
Cursor cursor = context.getContentResolver().query(
contacts,
null, queryString, null,
null
);
Hope this help!

Related

I'm getting the following error from the CursorAdapter Make sure the Cursor is initialized correctly before accessing data from it

My Binder Class
public void bindView(View view, Context context, Cursor cursor) {
mTitleText = (TextView) view.findViewById(R.id.recycle_title);
mDateAndTimeText = (TextView) view.findViewById(R.id.recycle_date_time);
mRepeatInfoText = (TextView)view.findViewById(R.id.recycle_repeat_info);
mActiveImage = (ImageView) view.findViewById(R.id.active_image);
mThumbnailImage = (ImageView) view.findViewById(R.id.thumbnail_image);
int titleColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_TITLE);
int dateColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_DATE);
int timeColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_TIME);
int repeatColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT);
int repeatNoColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_NO);
int repeatTypeColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_TYPE);
int activeColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_ACTIVE);
int locationColumnIndex= cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_LOCATION);
String title = cursor.getString(titleColumnIndex);
String date = cursor.getString(dateColumnIndex);
String time = cursor.getString(timeColumnIndex);
String repeat = cursor.getString(repeatColumnIndex);
String repeatNo = cursor.getString(repeatNoColumnIndex);
String repeatType = cursor.getString(repeatTypeColumnIndex);
String active = cursor.getString(locationColumnIndex);
String loc = cursor.getString(activeLocation);
String dateTime = date + " " + time;
Log.e("msg_fa", loc);
if (loc.equals(false)) {
setReminderTitle(title);
setReminderDateTime(dateTime);
setReminderRepeatInfo(repeat, repeatNo, repeatType);
setActiveImage(active);
} else
{
setReminderTitle(title);
setReminderDateTime("Place");
}
}
My Logcat Error
E/CursorWindow: Failed to read row 0, column 8 from a CursorWindow which has 1 rows, 8 columns.
2018-10-24 19:54:06.958 11109-11109/? E/AndroidRuntime: FATAL EXCEPTION: main
Process:PID: 11109
java.lang.IllegalStateException: Couldn't read row 0, col 8 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
I can access the till data columnIndex 7 but i cant get the index from 8
Code for My DB HELPER
public void onCreate(SQLiteDatabase sqLiteDatabase) {
// Create a String that contains the SQL statement to create the reminder table
String SQL_CREATE_ALARM_TABLE = "CREATE TABLE " + AlarmReminderContract.AlarmReminderEntry.TABLE_NAME + " ("
+ AlarmReminderContract.AlarmReminderEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ AlarmReminderContract.AlarmReminderEntry.KEY_TITLE + " TEXT NOT NULL, "
+ AlarmReminderContract.AlarmReminderEntry.KEY_DATE + " TEXT, "
+ AlarmReminderContract.AlarmReminderEntry.KEY_TIME + " TEXT, "
+ AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT + " TEXT, "
+ AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_NO + " TEXT, "
+ AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_TYPE + " TEXT, "
+ AlarmReminderContract.AlarmReminderEntry.KEY_ACTIVE + " TEXT,"
+AlarmReminderContract.AlarmReminderEntry.KEY_LOCATION + " TEXT,"
+ AlarmReminderContract.AlarmReminderEntry.latitude+" TEXT ,"
+ AlarmReminderContract.AlarmReminderEntry.longitude+" TEXT" +" );";
// Execute the SQL statement
sqLiteDatabase.execSQL(SQL_CREATE_ALARM_TABLE);
Insertion to the database works perfectly but this issue comes when i ask to fetch the data from the 8th index
The main issue which I'm facing is when I try to get the value from the index of KEY_LOCATION the app crashes and it then gives out the error which is displayed in the logcat I'm getting the value till column 7 I tried updating the database version and changing the table name and database name it didn't work as expected.
Here is my Provider Class
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
SQLiteDatabase database = mDbHelper.getReadableDatabase();
// This cursor will hold the result of the query
Cursor cursor = null;
int match = sUriMatcher.match(uri);
switch (match) {
case REMINDER:
cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
Log.i("msg","Reminder Invoked");
break;
case REMINDER_ID:
selection = AlarmReminderContract.AlarmReminderEntry._ID + "=?";
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Cannot query unknown URI " + uri);
}
The issue is that the Cursor only has 8 (offsets 0-7) of the 11 (offsets 0-10) columns in the table. Hence the message saying that it has failed to read row 0 (the first row) column 8 (the 9th column (location)).
A Cursor will only contain the columns that you specify implicitly or explicitly (SELECT * implies all columns, null as the 2nd parameter to the SQLIteDatabase query method equates to SELECT * and thus implies all columns). This irrespective of the columns in the underlying table or tables.
You issue would appear to be that the String array passed to the Provider Class's as the 2nd parameter (projection) only explicitly specifies 8 columns.
A quick fix (although the most flexible fix) would be to use null insetad of projection as the 2nd parameter when calling the SQLiteDatabase query method.
So instead of :-
database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
You could use :-
database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, null, selection, selectionArgs,
null, null, sortOrder);
As such the entire query method could be :-
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
SQLiteDatabase database = mDbHelper.getReadableDatabase();
// This cursor will hold the result of the query
Cursor cursor = null;
int match = sUriMatcher.match(uri);
switch (match) {
case REMINDER:
cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME,
null, //<<<<<<<<<< CHANGED
selection,
selectionArgs,
null, null, sortOrder);
Log.i("msg","Reminder Invoked");
break;
case REMINDER_ID:
selection = AlarmReminderContract.AlarmReminderEntry._ID + "=?";
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME,
null, //<<<<<<<<<< CHANGED
selection,
selectionArgs,
null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Cannot query unknown URI " + uri);
}
}
Note the 2nd parameter String[] projection passed to the method would be redundant.
An alternative would be to amend the call to the Provider class's query method (as above) so that the String array passed includes the extra column(s) when invoking the Provider class's query method.
e.g.
String[] projection_columns = new String[]{
AlarmReminderContract.AlarmReminderEntry._ID,
AlarmReminderContract.AlarmReminderEntry.KEY_TITLE,
AlarmReminderContract.AlarmReminderEntry.KEY_DATE,
AlarmReminderContract.AlarmReminderEntry.KEY_TIME,
AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT,
AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_NO,
AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_TYPE,
AlarmReminderContract.AlarmReminderEntry.KEY_LOCATION,
AlarmReminderContract.AlarmReminderEntry.KEY_ACTIVE,
AlarmReminderContract.AlarmReminderEntry.latitude,
AlarmReminderContract.AlarmReminderEntry.longitude
}
your_provider.query(your_uri, project_columns,your_selection, your_selectionargs, you_sortorder);

Cursor Index Out of Bounds exception

I keep getting this error message: "Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0" in my code.
I have already referenced the following links, but none of them have worked:
Android cursor out of bounds exception
Cursor index out of bounds
Cursor Index Out Of Bounds Error Android?
cursor index out of bounds exception
public Product getProduct(int id) {
db = this.getReadableDatabase();
Cursor cursor = db.query(
TABLE_NAME,
null,
COLUMN_ID + " = ?",
new String[] { Integer.toString(id)},
null, null, null, null);
Product product = new Product();
cursor.moveToFirst();
if (cursor != null) {
product.setID(cursor.getInt(0));
product.setName(cursor.getString(1));
product.setSize(cursor.getDouble(2));
product.setHp(cursor.getDouble(3));
product.setCategory(cursor.getString(4));
product.setPowerType(cursor.getString(5));
product.setExplosionProof(cursor.getInt(6));
product.setRPM(cursor.getInt(7));
product.setBypassPSI(cursor.getInt(8));
product.setGPM(cursor.getInt(9));
product.setPrice(cursor.getDouble(10));
cursor.close();
}
db.close();
return product;
}
And here are my constants:
private static final String TABLE_NAME = "Products";
private static final String COLUMN_ID = "'_id'";
I would greatly appreciate any help.
Now, it won't go into the if-loop. I got that query model straight from another stack overflow question.
It is very likely that the cursor is empty, as such you need to ascertain why. It could be that there is no underlying data or it could be that the cursor where clause is excluding all data. From what you have provided it is impossible to determine why.
I would suggest removing the where clause to see if this changes matters.
i.e. instead of
Cursor cursor = db.query(
TABLE_NAME,
null,
COLUMN_ID + " = ?",
new String[] { Integer.toString(id)},
null, null, null, null);
use :-
Cursor cursor = db.query(
TABLE_NAME,
null,
null,
null,
null, null, null, null);
This would return all rows from the cursor, if this works then the issue is with the where clause (3rd and 4th parameters passed to db.query). If it doesn't resolve the issue then it is likely that the table itself has no rows.
You could circumvent the CursorIndexOutOfBoundsException by using :-
if (cursor.getCount() > 0) {
cursor.moveToFirst();
product.setID(cursor.getInt(0));
product.setName(cursor.getString(1));
product.setSize(cursor.getDouble(2));
product.setHp(cursor.getDouble(3));
product.setCategory(cursor.getString(4));
product.setPowerType(cursor.getString(5));
product.setExplosionProof(cursor.getInt(6));
product.setRPM(cursor.getInt(7));
product.setBypassPSI(cursor.getInt(8));
product.setGPM(cursor.getInt(9));
product.setPrice(cursor.getDouble(10));
} else {
// setup to return a product not found
}
cursor.close();
However, this won't fix the underlying issue that the cursor is not returning any rows.
You could use something like the following to get more information regarding the cursor (running with the cursor selecting all rows as per change above). This should work for any cursor :-
int rowcount = cursor.getCount();
String colnames = "";
for (String columns : cursor.getColumnNames()) {
colnames = colnames +
"Column Index=" +
Integer.toString(cursor.getColumnIndex(columns)) +
" Name=>" +
columns +
"< ";
}
Log.d("DBCHK","Table has " + Integer.toString(rowcount) + " rows. With columns:- " + colnames);
String values;
while (cursor.moveToNext()) {
values = "";
for (int i = 0; i < cursor.getColumnCount(); i++) {
values = values +
"Column = " +
cursor.getColumnName(i) +
" Index=" +
Integer.toString(i) +
" Value=" + cursor.getString(i) + ": ";
}
Log.d("DBCHK",values);
}
This would write data to the log along the lines of :-
D/DBCHK: Table has 2 rows. With columns:- Column Index=0 Name=>_id< Column Index=1 Name=>myfloat<
D/DBCHK: Column = _id Index=0 Value=null: Column = myfloat Index=1 Value=56.7897:
D/DBCHK: Column = _id Index=0 Value=null: Column = myfloat Index=1 Value=87.7655:
There will be a line per row, these preceded with a line listing the number of rows and what the columns are.

How to check whether there is a record satisfying some condition in a sqlite table

I have the following code
public int getIngCount(String id,String ingrediant) {
String countQuery = "SELECT * FROM " + TABLE_CONTACTS2 + " WHERE id = "+id+ " AND ingrediant = "+ingrediant;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
// return count
return cursor.getCount();
}
But when there is no records satisfying the condition, it causing an exception (no such column) instead of returning 0.
pls help me to find a solution. Thanks in advance.
ingrediant should be treated as a string literal and not as an identifier such as a column name. In SQL you use single quotes for string literals. It's a better idea to use ? placeholders for binding literal values, though:
String countQuery = "SELECT * FROM " + TABLE_CONTACTS2 + " WHERE id = "+id+ " AND ingrediant = ?";
Cursor cursor = db.rawQuery(countQuery, new String[] { ingrediant });
Also, don't call any cursor methods after closing it.

Android SQLite SELECT Query

I have taken String value from a EditText and set it inside SELECT QUERY after WHERE condition
As
TextView tv = (TextView) findViewById(R.id.textView3);
EditTextet2 et = (EditText) findViewById(R.id.editText1);
String name = et.getText().toString();
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE name = '"+name+"'", null);
c.moveToNext();
tv.setText(c.getString(c.getColumnIndex("email")));
But it doesn't work. Any suggestions?
Try trimming the string to make sure there is no extra white space:
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE TRIM(name) = '"+name.trim()+"'", null);
Also use c.moveToFirst() like #thinksteep mentioned.
This is a complete code for select statements.
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("SELECT column1,column2,column3 FROM table ", null);
if (c.moveToFirst()){
do {
// Passing values
String column1 = c.getString(0);
String column2 = c.getString(1);
String column3 = c.getString(2);
// Do something Here with values
} while(c.moveToNext());
}
c.close();
db.close();
Try using the following statement:
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE name = ?", new String[] {name});
Android requires that WHERE clauses compare to a ?, and you then specify an equal number of ? in the second parameter of the query (where you currently have null).
And as Nambari mentioned, you should use c.moveToFirst() rather than c.moveToNext()
Also, could there be quotations in name? That could screw things up as well.
Here is the below code.
String areaTyp = "SELECT " +AREA_TYPE + " FROM "
+ AREA_TYPE_TABLE + " where `" + TYPE + "`="
+ id;
where id is the condition on which result will be displayed.
public User searchUser(String name) {
User u = new User();
SQLiteDatabase db = this.getWritableDatabase(); //get the database that was created in this instance
Cursor c = db.rawQuery("select * from " + TABLE_NAME_User+" where username =?", new String[]{name});
if (c.moveToLast()) {
u.setUsername(c.getString(1));
u.setEmail(c.getString(1));
u.setImgUrl(c.getString(2));
u.setScoreEng(c.getString(3));
u.setScoreFr(c.getString(4));
u.setScoreSpan(c.getString(5));
u.setScoreGer(c.getString(6));
u.setLevelFr(c.getString(7));
u.setLevelEng(c.getString(8));
u.setLevelSpan(c.getString(9));
u.setLevelGer(c.getString(10));
return u;
}else {
Log.e("error not found", "user can't be found or database empty");
return u;
}
}
this is my code to select one user and one only
so you initiate an empty object of your class then
you call your writable Database
use a cursor in case there many and you need one
here you have a choice Use : 1-
if (c.moveToLast()) { } //it return the last element in that cursor
or Use : 2-
if(c.moveToFirst()) { } //return the first object in the cursor
and don't forget in case the database is empty you'll have to deal with that in my case i just return an empty object
Good Luck
Detailed answer:
String[] selectionArgs = new String[]{name};
Cursor c = db.rawQuery(
"SELECT * FROM " + tabl1 +
" WHERE " + name + " = ? ", selectionArgs
);
selectionArgs : this takes the 'name' you desire to compare with, as argrument.
Here note "A Cursor object, which is positioned before the first entry of the table you refer to".
So,to move to first entry :
c.moveToFirst();
getColumnIndex(String ColumnName) : this returns the zero-based column index for the given column name.
tv.setText(c.getString(c.getColumnIndex("email")));
In case, you want to go searching through multiple rows for a given name under 'name' column then use loop as below:
if (cursor.moveToFirst()){
do{
////go traversing through loops
}while(cursor.moveToNext());
}
This should solve the problem.

Can get ID from received phone number, but not group

I have succeded in getting the ID and name from a phone number that is calling in. What I would like to to is to see which groups this ID belongs to. I have tried the following:
//Search for the information about the phone number, save the goupID(s)
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(aNumber));
ContentResolver cr = mService.getContentResolver();
Cursor myCursor = cr.query(uri, new String[]{PhoneLookup._ID, PhoneLookup.DISPLAY_NAME},null, null, null);
myCursor.moveToFirst();
//String contactID = myCursor.getString(myCursor.getColumnIndex(PhoneLookup._ID));
String contactID = myCursor.getString(myCursor.getColumnIndex(ContactsContract.Contacts._ID));
myCursor.close();
//Use the cursor to query for group with help of ID from the Phone look up
myCursor = cr.query(ContactsContract.Groups.CONTENT_URI,
new String[]{ContactsContract.Groups._ID},
ContactsContract.Groups._ID + " = ?",
new String[]{contactID},
null);
//Contact may be in more than one group
nbrOfGroups = myCursor.getCount();
groupName = new String [nbrOfGroups];
The problem is tha second query, where I would like to use the contactID that i found in the phone lookup, to see which groups that contacID belongs to. The result is no group, although the contact is added to a group in my contacs.
Any ideas? :)
Groups._ID is not same as Contact ID, instead it is the index for the table storing all the group information. After you get the contact ID you should get all the group membership for that contact from the data table by using the Group membership mimetype.
After getting the group ids you can query the Groups table to get the TITLE for all the groups
try with this code
//Search for the information about the phone number, save the goupID(s)
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode("123123"));
ContentResolver cr = this.getContentResolver();
Cursor myCursor = cr.query(uri, new String[]{PhoneLookup._ID, PhoneLookup.DISPLAY_NAME},null, null, null);
myCursor.moveToFirst();
//String contactID = myCursor.getString(myCursor.getColumnIndex(PhoneLookup._ID));
String contactID = myCursor.getString(myCursor.getColumnIndex(ContactsContract.Contacts._ID));
myCursor.close();
//Use the cursor to query for group with help of contact ID from the Phone look up
myCursor = cr.query(ContactsContract.Data.CONTENT_URI,
new String[]{ContactsContract.Data.CONTACT_ID,
ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID},
ContactsContract.Data.CONTACT_ID + " = ? " +
Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE + "'",
new String[]{contactID},
null);
//Contact may be in more than one group
int nbrOfGroups = myCursor.getCount();
int[] groupIds = new int[nbrOfGroups];
int index = 0;
// unfortunately group names are stored in Groups table
// so we need to query again
if (myCursor.moveToFirst()) {
do {
groupIds[index] = myCursor.getInt(1); // Group_row_id column
} while (myCursor.moveToNext());
}
myCursor.close();
// construct the selection
StringBuffer sb = new StringBuffer();
for (int i = 0; i < nbrOfGroups; i++) {
if (i != 0) {
sb.append(",");
}
sb.append(groupIds[i]);
}
String[] groupName = new String [nbrOfGroups];
myCursor = cr.query(ContactsContract.Groups.CONTENT_URI,
new String[]{ContactsContract.Groups.TITLE},
ContactsContract.Groups._ID + " IN (" + sb.toString() + ")",
null, null);
// finally got the names
if (myCursor.moveToFirst()) {
do {
groupName[index] = myCursor.getString(0); // Group_row_id column
} while (myCursor.moveToNext());
}
myCursor.close();

Categories

Resources