ContentProvider Problems with Phone.DISPLAY_NAME
See code to get all contacts on phone:
public ContactInfo[] getContactList(String selection, String[] selectionargs) {
String[] projection = new String[] {
Contacts._ID,
Contacts.DISPLAY_NAME,
};
String sortOrder = Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
Cursor cursor = context.getContentResolver().query(Contacts.CONTENT_URI,
projection, selection, selectionargs, sortOrder);
ContactInfo[] contactInfoList = new ContactInfo[cursor.getCount()];
ContactInfo contactInfo;
int i=0;
while(cursor.moveToNext()) {
contactInfo = new ContactInfo(cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME)), "");
String[] projectionPhone = new String[] {
Phone.CONTACT_ID,
Phone.DISPLAY_NAME,
Phone.NUMBER,
Phone.TYPE,
};
Cursor phoneCursor = context.getContentResolver().query(Phone.CONTENT_URI,
projectionPhone, Phone.DISPLAY_NAME + "='" + contactInfo.getName() + "'", null, null);
PhoneInfo[] phoneInfoList = new PhoneInfo[phoneCursor.getCount()];
int j = 0;
while(phoneCurso开发者_如何学运维r.moveToNext()) {
int type = ContactInfo.TYPE_OTHER;
if (phoneCursor.getInt(phoneCursor.getColumnIndex(Phone.TYPE)) == Phone.TYPE_HOME)
type = ContactInfo.TYPE_HOME;
else if (phoneCursor.getInt(phoneCursor.getColumnIndex(Phone.TYPE)) == Phone.TYPE_MOBILE
|| phoneCursor.getInt(phoneCursor.getColumnIndex(Phone.TYPE)) == Phone.TYPE_WORK_MOBILE)
type = ContactInfo.TYPE_MOBILE;
else if (phoneCursor.getInt(phoneCursor.getColumnIndex(Phone.TYPE)) == Phone.TYPE_FAX_HOME
|| phoneCursor.getInt(phoneCursor.getColumnIndex(Phone.TYPE)) == Phone.TYPE_FAX_WORK)
type = ContactInfo.TYPE_FAX;
else if (phoneCursor.getInt(phoneCursor.getColumnIndex(Phone.TYPE)) == Phone.TYPE_WORK)
type = ContactInfo.TYPE_OFFICE;
phoneInfoList[j++] = contactInfo.new PhoneInfo(
FWUtil.SeparatesCharacters(phoneCursor.getString(phoneCursor.getColumnIndex(Phone.NUMBER))),
type);
}
phoneCursor.close();
String[] projectionEMail = new String[] {
Email.CONTACT_ID,
Email.DATA,
Email.TYPE
};
Cursor emailCursor = context.getContentResolver().query(Email.CONTENT_URI,
projectionEMail, Email.CONTACT_ID + "='" + contactInfo.getName() + "'", null, null);
EmailInfo[] emailInfoList = new EmailInfo[emailCursor.getCount()];
j = 0;
while(emailCursor.moveToNext()) {
int type = ContactInfo.TYPE_OTHER;
if (emailCursor.getInt(emailCursor.getColumnIndex(Email.TYPE)) == Email.TYPE_HOME)
type = ContactInfo.TYPE_HOME;
else if (emailCursor.getInt(emailCursor.getColumnIndex(Email.TYPE)) == Email.TYPE_MOBILE)
type = ContactInfo.TYPE_MOBILE;
else if (emailCursor.getInt(emailCursor.getColumnIndex(Email.TYPE)) == Email.TYPE_WORK)
type = ContactInfo.TYPE_OFFICE;
emailInfoList[j++] = contactInfo.new EmailInfo(
emailCursor.getString(emailCursor.getColumnIndex(Email.DATA)),
type);
}
emailCursor.close();
contactInfo = new ContactInfo(cursor.getString(cursor.getColumnIndex(Contacts._ID)),cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME)),
phoneInfoList, emailInfoList, new AddressInfo[0], "");
contactInfoList[i++] = contactInfo;
}
cursor.close();
return contactInfoList;
//return new ContactInfo[0];
}`
This code get all contacts, but when contact has ' on name, like: 'Jonh. Systems show an exception, I don't know how to replace this charactere, because Android set query and projection before get the data no auto replace ' by "!!!!
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): android.database.sqlite.SQLiteException: near "Jonh": syntax error: , while compiling: SELECT contact_id, display_name, data1, data2 FROM view_data_restricted data WHERE (1 AND mimetype = 'vnd.android.cursor.item/phone_v2') AND (display_name=''Jonh')
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:46)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:330)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at com.android.providers.contacts.ContactsProvider2.query(ContactsProvider2.java:7924)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at com.android.providers.contacts.ContactsProvider2.query(ContactsProvider2.java:7909)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at android.content.ContentProvider$Transport.bulkQuery(ContentProvider.java:150)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:111)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at android.os.Binder.execTransact(Binder.java:288)
09-30 08:44:19.732: ERROR/DatabaseUtils(9292): at dalvik.system.NativeStart.run(Native Method)
Thanks for help!
Use '?' in your name selection.
context.getContentResolver().query(URI, projection, Email.CONTACT_ID + "=?", new String[] { contactInfo.getName()}, null);
Have a try
The '
in the name is breaking your query-string. Use a PreparedStatement
instead.
This seams to be a classic SQL-Injection case. If you like, create a user named
';DROP TABLE [your_table];
And see what happens ;)
The query()
-method works like a PreparedStatement. Instead of using something like this:
Email.CONTACT_ID + "='" + contactInfo.getName() + "'"
you should use the parameters which are offered by the method. An example might be found here.
精彩评论