Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
Grafity
59 / 4 / 1
Регистрация: 31.07.2013
Сообщений: 42
#1

Список контактов с аватарками - Android

19.08.2013, 12:23. Просмотров 1282. Ответов 2
Метки нет (Все метки)

Собственно, есть у меня в программе список контактов. Сейчас появилась необходимость выводить аватарки.

За основу вывода картинок в ListView я взял пример, прилагающийся к Universal ImageLoader. Соответственно, его я и использовал. Адаптер сейчас у меня выглядит так:

Кликните здесь для просмотра всего текста

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    class ContactAdapter extends BaseAdapter{
        
        private class ViewHolder {
            public TextView name;
            public TextView telephone;
            public ImageView image;
        }
 
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return userContacts.size();
        }
 
        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return userContacts.get(position);
        }
 
        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }
 
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            
            View view = convertView;
            final Contact p = getContact(position);
            
            listener = new OnTouchListener() {
                 
                @Override
                public boolean onTouch(View v, MotionEvent event) {
 
                    ...
 
            };
            
            final ViewHolder holder;
            
            if (convertView == null) {
                view = getLayoutInflater().inflate(R.layout.item, parent, false);
                holder = new ViewHolder();
                holder.name = (TextView) view.findViewById(R.id.name_tv);
                holder.telephone = (TextView) view.findViewById(R.id.tel_tv);
                holder.image = (ImageView) view.findViewById(R.id.contact_icon);
                view.setTag(holder);
            }
            else{
                holder = (ViewHolder) view.getTag();
            }
            
            if (view != convertView) {
                view.setOnTouchListener(listener);
            }
            
            holder.name.setText(p.name);
            holder.telephone.setText(p.tel);
            
            final Uri uri = getPhotoUri(p.id);
            
            Log.i("log_tag", p.id + " " + p.name + " " + p.tel + " URI = " + uri);
 
            ImageLoader.getInstance().displayImage(uri != null?
                        uri.toString(): null, holder.image, options);
            
            return view;
        }
        
        Contact getContact(int position) {
            return ((Contact) getItem(position));
          }
        
        public Uri getPhotoUri(long contactId) {
            Uri person = ContentUris.withAppendedId(
                    ContactsContract.Contacts.CONTENT_URI, contactId);
            return Uri.withAppendedPath(person,
                    ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
        }


Инициализация ImageLoader

Кликните здесь для просмотра всего текста

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
options = new DisplayImageOptions.Builder()
        .showStubImage(R.drawable.standart_contact)
        .showImageForEmptyUri(R.drawable.standart_contact)
        .showImageOnFail(R.drawable.standart_contact)
        .cacheInMemory()
        .cacheOnDisc()
        //.displayer(new RoundedBitmapDisplayer(20))
        .build();
        
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
        .threadPriority(Thread.NORM_PRIORITY - 2)
        .denyCacheImageMultipleSizesInMemory()
        //.discCacheFileNameGenerator(new Md5FileNameGenerator())
        //.tasksProcessingOrder(QueueProcessingType.LIFO)
        .enableLogging()
        .build();
        
        ImageLoader.getInstance().init(config);


Получается следующее:

На моем телефоне, где около 80 телефонов, выводит аватарку от контакта с id = 1111 на контакт с id=237. Больше ни одной аватарки в списке.

Лог на один из тестовых контактов, созданных у меня на телефоне:

Кликните здесь для просмотра всего текста

08-19 12:04:01.983: I/getView(8572): 1105 Собакен 1235 URI = content://com.android.contacts/contacts/1105/photo
08-19 12:04:01.983: I/ImageLoader(8572): Start display image task [content://com.android.contacts/contacts/1105/photo_480x800]
08-19 12:04:01.983: I/ImageLoader(8572): Load image from network [content://com.android.contacts/contacts/1105/photo_480x800]
08-19 12:04:01.983: I/ImageLoader(8572): Cache image on disc [content://com.android.contacts/contacts/1105/photo_480x800]
08-19 12:04:01.993: E/ImageLoader(8572): content://com.android.contacts/contacts/1105/photo
08-19 12:04:01.993: E/ImageLoader(8572): java.io.FileNotFoundException: content://com.android.contacts/contacts/1105/photo
08-19 12:04:01.993: E/ImageLoader(8572): at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:149)
08-19 12:04:01.993: E/ImageLoader(8572): at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:617)
08-19 12:04:01.993: E/ImageLoader(8572): at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:717)
08-19 12:04:01.993: E/ImageLoader(8572): at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:614)
08-19 12:04:01.993: E/ImageLoader(8572): at android.content.ContentResolver.openInputStream(ContentResolver.java:449)
08-19 12:04:01.993: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStreamFromContent(BaseImageDownloader.java:164)
08-19 12:04:01.993: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStream(BaseImageDownloader.java:88)
08-19 12:04:01.993: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.downloadImage(LoadAndDisplayImageTask.java:347)
08-19 12:04:01.993: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryCacheImageOnDisc(LoadAndDisplayImageTask.java:314)
08-19 12:04:01.993: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:254)
08-19 12:04:01.993: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:134)
08-19 12:04:01.993: E/ImageLoader(8572): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
08-19 12:04:01.993: E/ImageLoader(8572): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
08-19 12:04:01.993: E/ImageLoader(8572): at java.lang.Thread.run(Thread.java:856)
08-19 12:04:02.003: E/ImageLoader(8572): content://com.android.contacts/contacts/1105/photo
08-19 12:04:02.003: E/ImageLoader(8572): java.io.FileNotFoundException: content://com.android.contacts/contacts/1105/photo
08-19 12:04:02.003: E/ImageLoader(8572): at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:149)
08-19 12:04:02.003: E/ImageLoader(8572): at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:617)
08-19 12:04:02.003: E/ImageLoader(8572): at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:717)
08-19 12:04:02.003: E/ImageLoader(8572): at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:614)
08-19 12:04:02.003: E/ImageLoader(8572): at android.content.ContentResolver.openInputStream(ContentResolver.java:449)
08-19 12:04:02.003: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStreamFromContent(BaseImageDownloader.java:164)
08-19 12:04:02.003: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStream(BaseImageDownloader.java:88)
08-19 12:04:02.003: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.getImageStream(BaseImageDecoder.java:84)
08-19 12:04:02.003: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decode(BaseImageDecoder.java:70)
08-19 12:04:02.003: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:297)
08-19 12:04:02.003: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:256)
08-19 12:04:02.003: E/ImageLoader(8572): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:134)
08-19 12:04:02.003: E/ImageLoader(8572): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
08-19 12:04:02.003: E/ImageLoader(8572): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
08-19 12:04:02.003: E/ImageLoader(8572): at java.lang.Thread.run(Thread.java:856)



У этого контакта есть аватарка и она отображается в стандартном контакт листе.

В чем косяк?

З.Ы. По логам выяснил, что после вывода той единственной косячной иконки getView() почему-то начинает заново перебирать элементы списка, которые видны на самой верхней позиции.

Добавлено через 16 минут
Сейчас убрал из параметров ImageLoader все "заглушки" и получился довольно интересный результат:
При первой прокрутке списка, аватарок ни у кого нет - просто пустые ImageView. Когда я долистал до той единственной аватарки, то при пролистывании в любую сторону, как только эта аватарка исчезает за экраном, то у первого появившегося контакта будет эта-же аватарка. Так-же будет и с этой аватаркой. Если много раз пролистать список от начала до конца, то постепенно заполняется весь список этой аватаркой.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.08.2013, 12:23     Список контактов с аватарками
Посмотрите здесь:

Android Ошибка добавления списка контактов в ListView
Сортировка контактов в ListView Android
Формат даты дней рождения контактов гугл Android
Получить полный список контактов Android
Android Гуру, проконсультируйте по изменению списка контактов
Не выводит список Android
Как можно сделать выборку последних контактов? Android
Кастомизировать список Android
Выбор контактов для отправки смс Android
Android Список контактов с использованием RecyclerView и SQLite
Android Передача контактов стандартному приложению "Контакты"
Android Не срабатывает разрешение на чтение контактов

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Digetix
104 / 104 / 1
Регистрация: 09.04.2012
Сообщений: 647
19.08.2013, 14:22     Список контактов с аватарками #2
Кастомизация списков http://www.coderzheaven.com/2011/07/...er-in-android/
Grafity
59 / 4 / 1
Регистрация: 31.07.2013
Сообщений: 42
20.08.2013, 17:03  [ТС]     Список контактов с аватарками #3
Сдается мне, что аватарки имеют свои ID, которые не совпадают с ID контакта. У меня так получилось, что ID одной из аватарок случайно совпало с одним из контактов.

Добавлено через 17 часов 59 минут
Взял метод, предоставленный гуглем - та же фигня. Ничего не помогает.
Во всех случаях получаю иконку от контакта #1111 на контакте #237

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public InputStream openPhoto(long contactId) {
     Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
     Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
     Cursor cursor = getContentResolver().query(photoUri,
          new String[] {Contacts.Photo.PHOTO}, null, null, null);
     if (cursor == null) {
         return null;
     }
     try {
         if (cursor.moveToFirst()) {
             byte[] data = cursor.getBlob(0);
             if (data != null) {
                 return new ByteArrayInputStream(data);
             }
         }
     } finally {
         cursor.close();
     }
     return null;
 }
Добавлено через 8 часов 11 минут
Вопрос решен!

Решил так:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private Bitmap queryContactImage(int imageDataRow) {
            Cursor c = getContentResolver().query(ContactsContract.Data.CONTENT_URI, new String[] {
                ContactsContract.CommonDataKinds.Photo.PHOTO
            }, ContactsContract.Data._ID + "=?", new String[] {
                Integer.toString(imageDataRow)
            }, null);
            byte[] imageBytes = null;
            if (c != null) {
                if (c.moveToFirst()) {
                    imageBytes = c.getBlob(0);
                }
                c.close();
            }
            if (imageBytes != null) {
                return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); 
            } else {
                return null;
            }
        }
На вход подается Photo.PHOTO_ID.
Yandex
Объявления
20.08.2013, 17:03     Список контактов с аватарками
Ответ Создать тему
Опции темы

Текущее время: 05:00. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru