Ошибка при поиске контакта с символом апостроф (')
Приложение для отправки смс. Можно выбрать контакт из телефонной книги и отправить смс. Но если в поле поиска контакта ввести апостроф, то приложение падает с ошибкой android.database.sqlite.SQLiteException: near "'%'": syntax error (code 1). Буду благодарен всем за помощь. Вот данный метод:
void requestDatabase(String s) {
String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " like'%" + s + "%' " +
" or " + ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER + " like'%" + s + "%'";
String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone.NAME_RAW_CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,
ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI};
Cursor cursor = getApplicationContext().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, selection, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY);
if (cursor != null) {
List<ContactHintItem> list = new ArrayList<>();
while (cursor.moveToNext()) {
list.add(new ContactHintItem(cursor));
}
if (isStringDigit(s))
list.add(new ContactHintItem(null, s, s, null));
cursor.close();
adapter.update(list);
}
}
Ответы (3 шт):
У вас одинарный апостроф воспринимается как окончание строки в поисковом запросе. То есть, надо как то поменять апостроф на то, что не разрывает строку. Это называется экранированием.
Экранирование апострофов при вставке или в select-запросе в sqlite делается дублированием этих апострофов: ссылка
API андройда предлагает использовать DatabaseUtils.sqlEscapeString(String value) для того чтобы заескейпить все символы, которые необходимо эскейпить в запросах.
Данная проблема была решена! Можно использовать:
if (s.contains("'")) {
s = s.replaceAll("'", "''");
}
Но я не хотел использовать костыль, и искал как правильно параметризировать запрос. Вот работающий метод с параметрами в запросе:
void requestDatabase(String s) {
String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " like ?" + " or " + ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER + " like ?";
String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone.NAME_RAW_CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,
ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI};
Cursor cursor = getApplicationContext().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, selection, new String[]{"%"+s+"%", "%"+s+"%"}, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY);
...
}