У меня есть приложение для выбора контактов в моем приложении, которое возвращает контакт, и из этого я храню несколько бит информации в sharedPreferences. В общих предпочтениях я использую ключ поиска для хранения данных (как показывают документы Android)
Эта часть все кажется прекрасной, и я получаю и сохраняю ключ поиска.
Моя проблема в том, что я пришел, чтобы вернуть контакты, которые ищут контакт через ключ поиска, иногда кажется, что он возвращает null
Нижеследующие сведения взяты из панели выбора контактов
Contact lookup key from the contact picker: 850i%2bw7vj56otre6eqa9b9t7wa%3d%3d
Contact id: 2958
Затем я пытаюсь найти контакт на основе ключа поиска, используя следующий код для получения идентификатора контакта:
Uri lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, Uri.encode("850i%2bw7vj56otre6eqa9b9t7wa%3d%3d"));
Uri res = ContactsContract.Contacts.lookupContact(context.getContentResolver(), lookupUri);
После этого "res" имеет значение null, даже если я знаю, что идентификатор действителен, поскольку он исходит из набора контактов.
При вводе некоторых журналов res uri в поиске:
content://com.android.contacts/contacts/lookup/850i%252bw7vj56otre6eqa9b9t7wa%253d%253d
Которая (некогда закодированная) является тем, что, как я думал, должно быть. Может ли кто-нибудь определить, что я делаю неправильно?
Дело в том, что это работает для большинства людей (включая меня), но некоторые люди сталкиваются с этим.
Используйте .Uri.decode()
вместо Uri.encode()
Редактировать:
Согласно документации:
Ключ поиска должен быть добавлен незакодированным - он сохраняется в закодированной форме, готовой для использования в URI.
Поэтому вы не должны кодировать или декодировать URI. Передайте это, как есть.
Как сказал Dheeraj VS, вы не должны ни кодировать, ни расшифровывать lookupkey, он все кодирован, поэтому повторное кодирование может иметь странные результаты. Теперь я думаю, что ваш подход создает проблемы с контактами, которые изменили свой идентификатор. Если это так, тогда вы должны попытаться добавить последний известный ключ контакта в свой urid поиска и посмотреть, что произойдет.
Что-то вроде:
Uri lookupUri = ContentUris.withAppendedId(Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupkey), contactid);
Я думаю, что андроид нуждается в контакте, чтобы определить, изменилось ли оно, хотя в документах указано, что он является необязательным.
Надеюсь это поможет.
decode()
заключается в том, что ключ уже был закодирован URI (судя по наличию%
). Кроме того,%2b
в ключе+
в шестнадцатеричном виде; и%3d
=
. Наличие==
в конце означает, что сам ключ закодирован в base64 (это не имеет значения). В любом случае, если вы снова URI закодируете ключ,%
char сам закодируется в его шестнадцатеричной форме как%25
, что, как мне показалось, не правильно. Поэтому я предложил расшифровать вместо этого. Возможно, есть больше чем одна проблема.