How to get Group ID of contacts Number (Android) - java

How to get Group ID knowing contact's Number
I guess it have to be another query inside this one, but I have not ANY idea how to do it
Here what I've tried:
String[] projection = new String[]{ ContactsContract.Groups._ID };
Cursor cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection,
ContactsContract.CommonDataKinds.Phone.NUMBER +" = "+ number,
null,
null);
cursor.moveToNext();
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Groups._ID));
(Query returns nothing)
Thanks for help!

Your query returns nothing, because there is no such column Groups._ID within dataset CommonDataKinds.Phone.
Try something like this:
String sPhoneNumber = "+48123456789";
Cursor cursor = getApplicationContext().getContentResolver().query(
Data.CONTENT_URI, new String[] {CommonDataKinds.GroupMembership._ID},
ContactsContract.CommonDataKinds.Phone.NUMBER+"='"+sPhoneNumber+"'", null, null);
where sPhoneNumber is String with desired phone number. Keep in mind, that your cursor may still return 0 depending on:
how your phone number is formatted, i.e. you wish to find group ID
for contact of given number +49123456789 while number is formatted
like this +49 123 456 789. Whitespaces are making this completely
different String.
your contact does not belong to any group.
Also cursor can still return more results, mostly in cases when your contact belongs to more than one group.

Related

Android SQLite rawQuery - How to select multiple rows of a table

I'm trying to use rawQuery to return a cursor with a few different rows of data to be passed into it. When there is only 1 argument it works. When there is more than 1 argument it displays the empty ListView state. I believe the issue lies here:
// Query for items from the database and get a cursor back. Edited code for clarity:
recipeCursor = db.rawQuery("SELECT course, name, _id " +
" FROM recipes WHERE _id = ?",
selectedRecipesSQL);
When the code works the selectedRecipesSQL would look something like:
String[] selectedRecipesSQL;
selectedRecipesSQL = new String[]{"2"};
And when it doesn't work it would be something like
String[] selectedRecipesSQL;
selectedRecipesSQL = new String[]{"2 OR 5"};
So, to be clear, I can display a single row of the table in my ListView, but if I try to display more than one row of the table then it won't display anything.
One ugly solution which has crossed my mind (but I haven't pursued) is that I need to edit the rawQuery selection statement to read something like:
recipeCursor = db.rawQuery("SELECT course, name, _id " +
" FROM recipes WHERE _id = ? OR _id = ? OR _id = ?",
selectedRecipesSQL);
I'd probably use a for loop to generate the correct amount of WHERE "_id = ?" and then use a string array:
selectedRecipesSQL = new String[]{"2", "5"};
One way of doing it is by passing the possible values of _id as 1 string which is a comma separated list like this:
selectedRecipesSQL = new String[]{"1,2,3"};
and in your query use the operator LIKE:
recipeCursor = db.rawQuery(
"SELECT course, name, _id FROM recipes WHERE ',' || ? || ',' LIKE '%,' || _id || ',%'",
selectedRecipesSQL
);
This works also for just 1 value.
static String multiply__concat_string(String text,String joiner_,int multiple_)
{
String output="";
for(int i=0;i<multiple_;i++)
{
output+=(text+joiner_);
}
if(output.length()>0)
{
output=output.substring(0,output.length()-1);
}
return output;
}
Use it like this :
selectedRecipesSQL = new String[]{"2", "5"};
db.rawQuery("SELECT course, name, _id " +
" FROM recipes WHERE _id IN("+multiply_concat_string("?",",",selectedRecipesSQL.length)+")",
selectedRecipesSQL);

Android : phone contacts query takes long time to return the result

I'm working on Voip app ,So i have to show all contacts for user to call it .
So i used the following function :
public void GetContactsIntoArrayList(){
int i = 0 ;
cursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
HashSet<String> tempHash = new HashSet<String >();
while (cursor.moveToNext()) {
Person per = new Person();
Bitmap bit_thumb ;
name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
phonenumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contactId = cursor.getColumnIndex(ContactsContract.Contacts._ID);
per.setName(name);
per.setNumber(phonenumber);
//
if(tempHash.add(name) ){
i++ ;
StoreContacts.add(per );
}
}
Toast.makeText( getActivity()," "+i , Toast.LENGTH_LONG).show();
cursor.close();
adapter = new ContactListViewAdapter(getContext() , StoreContacts) ;
contactsListView.setAdapter(adapter);
}
Everything was good when my contacts count was less than 5000 contact .
But now i have 20000 contact on my phone it takes about 13 second to retrieve the result it so much .
can anyone help me to improve .
Assume that you've 100,000 contacts in your phone and it takes one minute for the cursor to load, and this much loading time is irritating in respect to user.
One solution is to fetch contacts using a limit, like
SELECT * FROM TABLE LIMIT 0,30
and then populate the listview(RecyclerView).
This way is much meaningful than fetching
SELECT * FROM TABLE
because we can't show 100,000 contacts at the same time,
while the user starts scrolling and reaches the bottom of first limit of elements, fetch the next limit of contacts and update the listview.
Since in our case we are not dealing with SQL Tables ,
To set limit in ContentProvider;
Cursor c = resolver.query(
MyTable.CONTENT_URI,
MyTable.PROJECTION,
null,
null,
" limit 1 offset 2");
I solved my problem by separate the cursor variables initialization
It was look like this :
cursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
And I replace it with following code :
String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};
String orderBy = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME;
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
cursor = getActivity().getContentResolver().query( uri, projection, null, null, orderBy) ;
And now its works 20,000 contact takes 1 second

How to get only contacts with birthdays in upcoming ascending order in android?

I am trying to fetch only those contacts for which birthday or anniversary information is available. However, I only found way to get contacts with phone number, but my app needs only contacts with birthday/anniversary information available and sorted in their upcoming birthdays order.
I am showing the results in ListView.
I need proper query to get around this problem, I tried googling and stackoverflow but found no solution.
Here is the code I'm using to get the information about contacts:
Uri contactsUri = ContactsContract.Contacts.CONTENT_URI;
String SORT_ORDER = ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY + " ASC ";
// Querying the table ContactsContract.Contacts to retrieve all the contacts
Cursor contactsCursor = getContentResolver().query(contactsUri,
null,
ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1",
null,
ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
if (contactsCursor.moveToFirst()) {
do {
long contactId = contactsCursor.getLong(contactsCursor.getColumnIndex("_ID"));
Uri dataUri = ContactsContract.Data.CONTENT_URI;
String[] projection1 ={
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Event.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.DATA2,
ContactsContract.Contacts.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Phone.DATA1,
ContactsContract.CommonDataKinds.Phone.DATA15
};
// Querying the table ContactsContract.Data to retrieve individual items like
// home phone, mobile phone, work email etc corresponding to each contact
String selection =
ContactsContract.Data.CONTACT_ID + "=" + contactId;
Cursor dataCursor = getContentResolver().query(
dataUri,
projection1, //projection
selection, //selection
null,
null);
////some code here
} while (dataCursor.moveToNext());
////some more code
// Adding id, display name, path to photo and other details to cursor
mMatrixCursor.addRow(new Object[]{Long.toString(contactId), displayName, photoPath, details});
}
} while (contactsCursor.moveToNext());
}
return mMatrixCursor;
}
I am getting all the required information correctly and having no problem with that, however I'm struggling in finding proper query to show only contacts with birthdays and sorting them in proper order as birthdays are not always stored in proper format. Thanks in advance !

Fetching single value from SQLite in android

I'm developing my firs app for android right now, I am using multiple tables to get and insert data. during the development and found myself fetching data from the table with has only two columns STATS(_id, stat_name). What my problem is? I have an activity with 10 buttons, and every button correlates with one stat_name. When users presses one of the buttons application is "going" to STATS table to get correct _id and then is inputting this _id to another table GAME_STATS(_id, PlayerId (fk), GameId(fk), StatsId(fk)(andmore)) on STATS._id = GAME_STATS.StatsId and I basicly have to do similar operation for PlayerId.
Right now, I'm doing it this way:
public String getStatId(String statName){
String statId = "Error";
Cursor c = mDb.query(STAT_TABLE, new String[] {AbstractDbAdapter.STAT_ID, AbstractDbAdapter.STAT_NAME}, AbstractDbAdapter.STAT_NAME+ " = " +statName, null, null, null, null);
int count = c.getCount();
if(count == 1){
c.moveToFirst();
statId = c.getString(c.getColumnIndex(AbstractDbAdapter.STAT_ID));
}
c.close();
mDb.close();
Log.d("FootballApp","StatId =" +statId);
return statId;
}
What my problem is, that I know that there SHOULD be only one value returned, and I still have to use Cursor, to do so. Also, in my opinion, it looks way to complicated and time consuming wo write all that code just to get one id from one table. I have 9 tables in my application, and I will have to write similar method every time I need _id from different table when I have, for example, only name.
Can someone tell me if there is easier way to do all that? Please :)
thanks! :)
I think it doesn't get much simpler than that. However you can make the method more generic so you can reuse the code:
public String getFromDb(String tableName, String select, String selectBy, String selectName){
String selection = "Error";
Cursor c = mDb.query(tableName, new String[] {select}, selectBy + "=" + selectName, null, null, null, null);
if(c.getCount() == 1){
c.moveToFirst();
selection = c.getString(c.getColumnIndex(select));
}
c.close();
mDb.close();
Log.d("FootballApp", select + "=" + selection);
return id;
}
Example usage:
int statID = getFromDb(STAT_TABLE, AbstractDbAdapter.STAT_ID, AbstractDbAdapter.STAT_NAME, statName);
That is about as simple as it gets, but Cursor.moveToFirst() returns false if the cursor is empty so you can cut out the c.getCount() call and just say if(c.moveToFirst()) instead. That will save you a little bit of typing :)

How to get DISTINCT values from the database?

I would like to get values from the database in this format
1 Audi
3 Nissan
But I am getting like this as of now. I don't need to get to include the _id in the output.But I couldn't eliminate as it throws a NullPointerException when I remove it.
id MAKE
=========
1 Audi
2 Audi
3 Nissan
4 Audi
this is my query I have used in
cursor = db.rawQuery(
"SELECT DISTINCT _id,MAKE FROM "+SQLiteAdapter.MYDATABASE_TABLE+
" WHERE MAKE || ' ' || MODEL LIKE ?", new String[]{"%" + "" + "%"}
);
Do have I to change the sequence entirely to get the output or make changes on the above code.Thanks.
my code
cursor = db.rawQuery("SELECT DISTINCT SERIES FROM "+SQLiteAdapter.MYDATABASE_TABLE+" WHERE YEAR=2012 AND MAKE='Audi' AND MODEL=?", new String[]{"A6"});
adapter = new SimpleCursorAdapter(this, R.layout.employee_list_item, cursor, new String[] {"series"}, new int[] {R.id.firstName});
employeeList.setAdapter(adapter);
try:
select min(id), min(make) from cars group by make
you can use SQLiteQueryBuilder's buildQueryString method:
buildQueryString (boolean distinct, String tables, String[] columns, String where, String groupBy, String having, String orderBy, String limit)

Categories

Resources