This question already has answers here:
Using String[] selectionArgs in SQLiteDatabase.query()
(2 answers)
Closed 6 years ago.
I am new to SQLite in Android. I have successfully created the database with this schema:
public final class BookDbSchema {
private BookDbSchema() {
}
public static final class BookEntry implements BaseColumns{
public static final String NAME = "bookItems";
public static final String ID = "id";
public static final String URL = "url";
public static final String TITLE = "title";
}
}
The problem I am having is searching the database for a particular string.
I want to search the id column if 1993 exists. Please how do I do that?
I have read the documentation but I don’t know where to input "1993" for in the query method.
i belive you are looking for this
Context context;
BookDbSchema mDbHelper;
public BookDbSchema (Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
...
ArrayList<String> urls = new ArrayList<>();
ArrayList<String> titles = new ArrayList<>();
ArrayList<String> ids= new ArrayList<>();
mDbHelper = new BookDbSchema(context);
SQLiteDatabase db = mDbHelper.getReadableDatabase();
String[] projection = {
FeedEntry.ID,
FeedEntry.URL,
FeedEntry.TITLE
};
String selection = FeedEntry.ID + " LIKE ? "; //WHERE
String[] selectionArgs = {"1993"}; //VALUE
Cursor c = db.query(
FeedEntry.NAME, // Your Table Name
projection,
selection,
selectionArgs,
null,
null,
null
);
if(c.getCount() != 0) {
c.moveToFirst();
for(int i = 0; i<c.getCount(); i++) {
urls.add(c.getString(c.getColumnIndex(FeedEntry.URL)));
titles.add(c.getString(c.getColumnIndex(FeedEntry.TITLE)));
ids.add(c.getString(c.getColumnIndex(FeedEntry.ID)));
c.moveToNext();
}
String firstUrl = urls.get(0); //Returns the first url found
String firstID = ids.get(0); //Returns the first id found
int urlSize = urls.size(); // returns the count of urls found
}else{
//Nothing found
}
c.close();
db.close();
You can use the below method :
Cursor query (String table,
String[] columns,
String selection,
String[] selectionArgs,
String groupBy,
String having,
String orderBy,
String limit)
query(NAME, new String[]{ID, URL, TITLE}, ID + "=?", new String[]{"1993"}, null, null, null, null);
Related
following is the code that i am trying out to get the details of the application name (KEY_NAME), application_category (KEY_CATEGORY) and application_permissions(KEY_PERM)
but really what i want is with the application name and category to display the number of permissions(count) how can i do that i display it in the list view
handler
public Cursor queueAll() {
String[] columns = new String[] { KEY_ID, KEY_NAME, KEY_CATEGORY,
"count" + KEY_PERM };
Cursor cursor = sqlitedb.query(MYDATABASE_TABLE, columns, null, null,
KEY_NAME, null, null);
return cursor;
}
main activity
mySQLiteAdapter = new Handle(this);
mySQLiteAdapter.openToWrite();
cursor = mySQLiteAdapter.queueAll();
String[] from = new String[] { Handle.KEY_NAME, Handle.KEY_PERM,
Handle.KEY_CATEGORY };
int[] to = new int[] { R.id.appname, R.id.numbpermcount, R.id.category };
cursorAdapter = new SimpleCursorAdapter(this,
R.layout.activity_main_row, cursor, from, to);
listContent.setAdapter(cursorAdapter);
thank you in advance.
i tried to do it again as this.
Handler
public static final String KEY_ID = "_id";
public static final String KEY_NAME = "application_name";
public static final String KEY_PACK = "application_package";
public static final String KEY_PERM = "application_permission";
public static final String KEY_LEVEL = "application_level";
public static final String KEY_CATEGORY = "application_category";
public Cursor queueAll() {
String[] columns = new String[] { KEY_ID, KEY_NAME, KEY_CATEGORY,
"count(" + KEY_PERM +")" };
Cursor cursor = sqlitedb.query(MYDATABASE_TABLE, columns, null, null,
KEY_NAME, null, null);
return cursor;
}
Main Activity
is as the same as above...
ERROR
02-19 22:51:04.049: E/AndroidRuntime(1192): java.lang.RuntimeException: Unable to start activity ComponentInfo{db.database/db.database.MainActivity}: java.lang.IllegalArgumentException: column 'application_permission' does not exist
I think what you're trying to do is a little beyond what can be done with the builtin query method. Instead, you'll need rawquery, to which you can pass arbitrary SQL. It sounds like you need
public static final String KEY_ID = "_id";
public static final String KEY_NAME = "application_name";
public static final String KEY_PACK = "application_package";
public static final String KEY_PERM = "application_permission";
public static final String KEY_LEVEL = "application_level";
public static final String KEY_CATEGORY = "application_category";
public static final String KEY_PERM_COUNT = "application_permission_COUNT";
public Cursor queueAll() {
Cursor cursor = sqlitedb.rawquery(
"SELECT "+KEY_ID+", "+KEY_NAME+", "+KEY_CATEGORY
+", count("+KEY_PERM+") AS "+KEY_PERM_COUNT
+" FROM "+MYDATABASE_TABLE
+" GROUP BY "+KEY_ID+", "+KEY_NAME+", "+KEY_CATEGORY
);
return cursor;
}
And then set up your adapter to also read the Handle.KEY_PERM_COUNT.
I have a SQLite Database with 45 different entries, each with:
public static final String TABLE = "Table";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_HOUR = "hour";
public static final String COLUMN_WEEK = "week";
public static final String COLUMN_DAY = "day";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_COLOUR = "colour";
public static final String COLUMN_ROOM = "room";
now I want to read out all. I Do this with following:
public Cursor fetchAllSubject(){
Cursor mCursor = database.query(true, TABLE, new String[] {
COLUMN_ID, COLUMN_HOUR, COLUMN_WEEK, COLUMN_DAY, COLUMN_NAME, COLUMN_DESCRIPTION, COLUMN_COLOUR, COLUMN_ROOM},null
, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
In a other class I have this code to read all out:
dao = new DAO(this);
Cursor subjectList = dao.fetchAllSubject();
Now I want to have for each entry an array with ID, Hour, week, ... but I have no idea how to do that.
My first try was following:
ArrayList<String> mo1h = new ArrayList<String>();
subjectList.moveToFirst();
while(!subjectList.isAfterLast()) {
mo1h.add(subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_ID)));
mo1h.add(subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_HOUR)));
mo1h.add(subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_WEEK)));
mo1h.add(subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_DAY)));
mo1h.add(subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_NAME)));
mo1h.add(subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_DESCRIPTION)));
mo1h.add(subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_COLOUR)));
mo1h.add(subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_ROOM)));
subjectList.moveToNext();
}
But everything is in mo1h, and I dont know how to devide it.
The best would be to have a String[] for each. Has anybody an Idea?
Thanks!
You can create on Bean class and then create one ArrayList (Collection class)
public class Bean
{
public Bean();
String id, hour, week, day, name, description, color, room;
}
now create list of Bean
ArrayList<Bean> mo1h = new ArrayList<Bean>();
subjectList.moveToFirst();
while(!subjectList.isAfterLast()) {
Bean b = new Bean();
b.id = subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_ID));
b.hour =subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_HOUR));
...
...
// all your column
mo1h.add(b);
}
Why not continue with your strategy, but instead use an ArrayList of String[]:
ArrayList<String[]> mo1h = new ArrayList<String[]>();
subjectList.moveToFirst();
while(!subjectList.isAfterLast()) {
String[] toUse = new String[8];
toUse[0] = subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_ID));
toUse[1] = subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_HOUR));
toUse[2] = subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_WEEK));
toUse[3] = subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_DAY));
toUse[4] = subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_NAME));
toUse[5] = subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_DESCRIPTION));
toUse[6] = subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_COLOUR));
toUse[7] = subjectList.getString(subjectList.getColumnIndex(dao.COLUMN_ROOM));
mo1h.add(toUse);
subjectList.moveToNext();
}
I am looking for a way to get the contacts in the favorites list inside service from phone number or from name it dose not matter. Can any one help me with this?
It's not important to use any code related to this code
I found in the developer.android.com something like this (IN_VISIBLE_GROUP).
How to use this variable in my case?
case (PICK_CONTACT):
if (resultCode == Activity.RESULT_OK) {
Uri contactData = data.getData();
Cursor c = managedQuery(contactData, null, null, null, null);
ContentResolver cr = getContentResolver();
if (c.moveToFirst()) {
String name = c.getString(c.getColumnIndexOrThrow(People.NAME));
String id =c.getString(c.getColumnIndexOrThrow(People._ID));
Cursor phones = cr.query(Phone.CONTENT_URI, null,
Phone.CONTACT_ID + " = " + id, null, null);
}
Lets assume that you are searching a contact by name..
If you want to get Favourite value of all the possible contacts , drop the selection parameter in the given code.
//First get the contact ID from a display name as:-
String displayName = "Albert Einstein";
Uri contacts = ContactsContract.Contacts.CONTENT_URI;
cur = cr.query(contacts, null, ContactsContract.Contacts.DISPLAY_NAME +"="+displayName,null, null);
int contactIdIndex = cur.getColumnIndex(ContactsContract.PhoneLookup._ID);
int contactId = cur.getInt(contactIdIndex);
//Make a query to get the Starred value:-
Cursor starred = cr.query(ContactsContract.Contacts.CONTENT_URI,
new String[] { ContactsContract.Contacts.STARRED },
ContactsContract.Contacts._ID + " = " + contactId,
null, null);
if (starred != null && starred.moveToFirst())
{
int fav = starred.getInt(0);
}
if (starred != null)
starred.close();
}
You can drop the step of getting Contact ID and then querying for Starred value and directly query based on Display name
Something like this?
final private static class DataQuery {
public static final int COLUMN_MIMETYPE = 1;
public static final int COLUMN_PHONE = 2;
public static final int COLUMN_RAWCONTACT_ID = 3;
public static final int COLUMN_PHONE_NUMBER = COLUMN_DATA1;
public static final String[] PROJECTION = new String[] { Data._ID, Data.MIMETYPE, Data.DATA1, Data.RAW_CONTACT_ID };
public static final String SELECTION_PHONE = Data.DATA1 + "=?";
}
long findContact(Context context, String number) {
long rawContactId = -1;
final Cursor cursor = context.getContentResolver().query(Data.CONTENT_URI, DataQuery.PROJECTION, DataQuery.SELECTION_PHONE, new String[] { number }, null);
try {
if (cursor.moveToFirst()) {
rawContactId = cursor.getLong(DataQuery.COLUMN_RAWCONTACT_ID);
}
} finally {
if (cursor != null)
cursor.close();
}
return rawContactId;
}
Ok let's try with this...
private static final Uri DATAGROUP_CONTENT_URI = ContactsContract.Data.CONTENT_URI.buildUpon().appendQueryParameter(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE).build();
public static void querytGroups(Context context) {
final ContentResolver resolver = context.getContentResolver();
long groupid=getGroupId(resolver, "Family");
final Cursor c = resolver.query(DATAGROUP_CONTENT_URI, DataQueryForContactsInGroup.PROJECTION, DataQueryForContactsInGroup.SELECTION, new String[] {ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE, String.valueOf(groupid)}, null);
try {
while (c.moveToNext()) {
final long rawContactId = c.getLong(DataQueryForContactsInGroup.RAW_CONTACT_ID);
//do something
}
}finally {
c.close();
}
}
private static long getGroupId(final ContentResolver resolver, String groupName) {
long groupid = -1;
Cursor cur = null;
try {
cur = resolver.query(Groups.CONTENT_URI, DataQueryForGroup.PROJECTION, DataQueryForGroup.SELECTION, new String[]{"%"+groupName+"%"}, null);
while (cur.moveToNext()) {
return groupid= cur.getLong(DataQueryForGroup.GROUP_ID);
}
}finally {
if (cur!=null) cur.close();
}
return groupid;
}
private interface DataQueryForGroup {
public final static String[] PROJECTION = new String[] {Groups._ID};
public static final String SELECTION = Groups.TITLE+" LIKE ?";
public final static int GROUP_ID = 0;
}
private interface DataQueryForContactsInGroup {
public final static String[] PROJECTION = new String[] { Data.RAW_CONTACT_ID };
public static final String SELECTION = "("+Data.MIMETYPE + "=?) and ("+ ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID+ "=?)";
public final static int RAW_CONTACT_ID = 0;
}
Please consider that if your google account is not English you need to look for the proper group's name
I've spent a lot of hours searching and reading similar posts, but none of them seem to truly reflect my problem and thus I haven't found anything that works for me.
I've got a database, on which I perform a query, the results of which are stored in a cursor. There's two things to that:
-the query is performed everytime a certain button is pressed (thus the query is inside the OnClickListener for that Button)
-the query returns two different columns with String values, which must be treated separately (one column stores the names which must be shown in the ListView, the other stores the paths to the image associated toa row)
My problem is, I try to create a String[] which I need to pass to the ArrayAdapter creator for the ListView, but trying to assign it a size of Cursor getCount() crashes my activity. I hope the code will be more of an explanation:
OnClickListener searchListener = new OnClickListener() {
public void onClick(View v) {
CardDatabaseOpenHelper helper = new
CardDatabaseOpenHelper(DeckEditorScreen1.this);
SQLiteDatabase db = helper.getReadableDatabase();
String columns[] = {"name","number","path"};
Cursor c = db.query("cards", columns, null, null, null, null, "number");
int count = c.getCount();
String[] resultNameStrings;
if (count != 0) resultNameStrings = new String[count];
else {resultNameStrings = new String[1]; resultNameStrings[1] = "No results";}
// This is the offending code
//Note that if I assign fixed values to resutNameStrings, the code works just
//fine
for (int i = 0; i < count; ++i) {
c.moveToNext();
int col = c.getColumnIndex("name");
String s = c.getString(col);
//Ideally here I would to something like:
//resultNameStrings[i] = s;
col = c.getColumnIndex("number");
int conv = c.getInt(col);
col = c.getColumnIndex("path");
String s2 = c.getString(col);
}
db.close();
ArrayAdapter<?> searchResultItemAdapter = new ArrayAdapter<String>
(DBScreen.this,
R.layout.search_result_item,
resultNameStrings);
ListView searchResultList = (ListView)
DBScreen.this.findViewById(R.id.search_result_list);
searchResultList.setAdapter(searchResultItemAdapter);
}
};
Button search_button = (Button) findViewById(R.id.search_button);
search_button.setOnClickListener(searchListener);
EDITED twice :)
do it in "Android Way" ...
first use CursorAdapter (fx.: SimpleCursorAdapter with overrided
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
Cursor cursor = managedQuery(MobileTraderProvider.CONTENT_URI,
null, null, new String[] { constraint.toString() }, null);
return cursor;
}
then
customAdapter.getFilter().filter(filterText)
// it will call runQueryOnBackgroundThread
second use ContentProvider(it will manage curosors for you ... it will even requery if data changed)
EDIT:
first really use my advice
second before
for (int i = 0; i < count; ++i) {
c.moveToNext();
//...
add c.moveToFirst();
thrid: use
if(c.moveToNext())
{
int col = c.getColumnIndex("name");
//..... rest goes here
}
SECOND EDIT:
MyProvider.java
public class MyProvider extends ContentProvider {
static final String LTAG = "MyAppName";
public static final Uri CONTENT_URI = Uri.parse("content://my.app.Content");
static final int CARDS = 1;
static final int CARD = 2;
public static final String CARDS_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/Cards";
public static final String CARD_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/Cards";
static final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
static final HashMap<String, String> map = new HashMap<String, String>();
static {
//static "Constructor"
matcher.addURI(Constants.AUTHORITY, "Cards", LISTS);
matcher.addURI(Constants.AUTHORITY, "Cards/*", LIST);
map.put(BaseColumns._ID, "ROWID AS _id");
map.put(Tables.Cards.C_NAME, Tables.Cards.C_NAME);
map.put(Tables.Cards.C_NUMBER, Tables.Cards.C_NUMBER);
map.put(Tables.Cards.C_PATH, Tables.Cards.C_PATH);
}
private CardDatabaseOpenHelper mDB;
#Override
public boolean onCreate() {
try {
mDB = new CardDatabaseOpenHelper(getContext());
} catch (Exception e) {
Log.e(LTAG, e.getLocalizedMessage());
}
return true;
}
public int delete(Uri uri, String selection, String[] selectionArgs) {
String table = null;
switch (matcher.match(uri)) {
case CARD:
//overriding selection and selectionArgs
selection = "ROWID=?";
selectionArgs = new String[] { uri.getPathSegments().get(1) };
table = uri.getPathSegments().get(0);
break;
case CARDS:
//this version will delete all rows if you dont provide selection and selectionargs
table = uri.getPathSegments().get(0);
break;
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
int ret = mDB.getWritableDatabase().delete(table, selection, selectionArgs);
getContext().getContentResolver().notifyChange(Uri.withAppendedPath(CONTENT_URI, table), null);
return ret;
}
#Override
public String getType(Uri uri) {
switch (matcher.match(uri)) {
case CARDS:
return CARDS_MIME_TYPE;
case CARD:
return CARD_MIME_TYPE;
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
}
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
String table, rowid;
switch (matcher.match(uri)) {
case CARD:
//overriding selection and selectionArgs
selection = "ROWID=?";
selectionArgs = new String[] { uri.getPathSegments().get(1) };
table = uri.getPathSegments().get(0);
break;
case CARDS:
//this version will update all rows if you dont provide selection and selectionargs
table = uri.getPathSegments().get(0);
break;
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
int ret = mDB.getWritableDatabase().update(table, values, selection, selectionArgs);
getContext().getContentResolver().notifyChange(Uri.withAppendedPath(CONTENT_URI, table), null);
return ret;
}
public Uri insert(Uri uri, ContentValues values) {
String table = null;
switch (matcher.match(uri)) {
case CARDS:
table = uri.getPathSegments().get(0);
break;
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
mDB.getWritableDatabase().insert(table, null, values);
getContext().getContentResolver().notifyChange(Uri.withAppendedPath(CONTENT_URI, table), null);
return null;
}
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
switch (matcher.match(uri)) {
case CARDS:
builder.setTables(uri.getPathSegments().get(0));
break;
case CARD:
builder.setTables(uri.getPathSegments().get(0));
selection = "ROWID=?";
selectionArgs = new String[] { uri.getPathSegments().get(1) };
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
builder.setProjectionMap(map);
Cursor cursor = builder.query(mDB.getReadableDatabase(), projection, selection, selectionArgs, null, null, sortOrder);
if (cursor == null) {
return null;
}
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
}
CardCursorAdapter.java
class CardCursorAdapter extends SimpleCursorAdapter {
public MyCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
//search in cards.name
String selection = Tables.Cards.C_NAME + " LIKE ?";
String[] selectionArgs = new String[] {"%" + constraint.toString() + "%"};
Cursor cursor = managedQuery(Uri.withAppendedPath(MyProvider.CONTENT_URI, Tables.Cards.Name),
getCursor().getColumnNames(), selection, selectionArgs, null);
return cursor;
}
}
Tables.java
public static class Tables {
//table definition
public static interface Cards {
public static final String NAME = "cards";
public static final String C_NAME = "name";
public static final String C_NUMBER = "number";
public static final String C_PATH = "path";
}
//other tables go here
}
AndroidManifest.xml
</manifest>
</application>
<!-- ....... other stuff ....... -->
<provider android:name="MyProvider" android:authorities="my.app.Content" />
</application>
</manifest>
then in activity
onCreate(...){
listView.setAdapter(new CardCursorAdapter(this, R.layout.listrow,
managedQuery(Uri.withAppendedPath(MyProvider.CONTENT_URI, Tables.Cards.NAME),
new String[] { BaseColumns._ID, Tables.Cards.C_NAME, Tables.Cards.C_NUMBER, Tables.Cards.C_PATH },
null,null, number),
new String[] { Tables.Cards.C_NAME, Tables.Cards.C_NUMBER, Tables.Cards.C_PATH },
new int[] { R.id.tName, R.id.tNumber, R.id.tPath }));
}
OnClickListener searchListener = new OnClickListener() {
public void onClick(View v) {
DeckEditorScreen1.this.listView.getAdapter().getFilter().filter("text for search in name column of card table set me to empty for all rows");
}
}
Ok, I've done some testing and I think I know what was the problem. Java allows constructs like:
String[] whatever;
if (something) whatever = new String[avalue];
else whatever = new String[anothervalue];
The crash occurs if you don't assign a concrete value to each and every field whatever[i]. The rest of the code is now just fine, though I've added Selvin's correction
if (c.moveToNext) ...
c.moveToFirst() is not correctly used in my case, as the for iterates count times. If you perform a moveToFirst first, you're always missing the first element pointed by the cursor.
Cursor cursor = resolver.query(
Data.CONTENT_URI,
DataQuery.PROJECTION,
DataQuery.SELECTION,
new String[] {String.valueOf(rawContactId)},
null);
With PROJECTION being:
public static final String[] PROJECTION = new String[] {
Data._ID,
Data.MIMETYPE,
Data.DATA1,
Data.DATA2,
Data.DATA3};
and SELECTION being:
public static final String SELECTION = Data.RAW_CONTACT_ID + "=?";
The rawcontactId does return values, I've made logs to check. To give it some context I'm working with Account sync. The goal here is for it to find the data columns for existing contacts and writing over them with any new data. I'm working from the following sample code provided by android: http://developer.android.com/resources/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.html
To summarize my problem, I have two contacts via this synced account which are added without any problems, but are not being able to be updated. Anyone have experience with this? Thanks.
EDIT: Here is my rawContact returning method
private static long lookupRawContact(ContentResolver resolver, String username) {
Log.e("Looking up Raw Contact", username);
long authorId = 0;
Cursor cursor = resolver.query(
Data.CONTENT_URI,
UserIdQuery.PROJECTION,
UserIdQuery.SELECTION,
new String[] {username},
null);
try {
if(cursor != null && cursor.moveToFirst()) {
authorId = cursor.getLong(UserIdQuery.COLUMN_ID);
}
} finally {
if(cursor != null) {
cursor.close();
}
}
return authorId;
}
The numbers I get back are like 3061. Here is the UserIdQuery class:
final private static class UserIdQuery {
private UserIdQuery() {
}
public final static String[] PROJECTION = new String[] {RawContacts._ID};
public final static int COLUMN_ID = 0;
public static final String SELECTION = RawContacts.ACCOUNT_TYPE + "='" +
"com.tagapp.android" + "' AND " + RawContacts.SOURCE_ID + "=?";
}
And here is my constructor for a ContactSyncOperations class being used to add a new contact. The source id here is a username, the same as I call in my SELECTION argument.
public ContactSyncOperations(Context context, String username,
String accountName, BatchOperationForSync batchOperation) {
this(context, batchOperation);
mBackReference = mBatchOperation.size();
mIsNewContact = true;
mValues.put(RawContacts.SOURCE_ID, username);
mValues.put(RawContacts.ACCOUNT_TYPE, "com.tagapp.android");
mValues.put(RawContacts.ACCOUNT_NAME, accountName);
mBuilder = newInsertCpo(RawContacts.CONTENT_URI, true).withValues(mValues);
mBatchOperation.add(mBuilder.build());
}
Thanks!
There was an error in the lookupRawContactId method, the rawcontactId long I was getting wasn't the right one. It should have looked like this:
private static long lookupRawContact(ContentResolver resolver, String username) {
Log.e("Looking up Raw Contact", username);
long authorId = 0;
Cursor cursor = resolver.query(
RawContacts.CONTENT_URI,
UserIdQuery.PROJECTION,
UserIdQuery.SELECTION,
new String[] {username},
null);
try {
if(cursor != null && cursor.moveToFirst()) {
authorId = cursor.getLong(UserIdQuery.COLUMN_ID);
}
} finally {
if(cursor != null) {
cursor.close();
}
}
return authorId;
}
There are a few issues that i could locate with the following query:
Cursor cursor = resolver.query(Data.CONTENT_URI,
UserIdQuery.PROJECTION,
UserIdQuery.SELECTION,
new String[] {username}, null);
If all the columns are pointing out at RawContacts table then you should use RawContacts.CONTENT_URI instead of Data.CONTENT_URI.
Here the value of RawContacts.SOURCE_ID is compared with username
public static final String SELECTION = RawContacts.ACCOUNT_TYPE + "='" +
"com.tagapp.android" + "' AND " + RawContacts.SOURCE_ID + "=?";
new String[] {username}