【问题标题】:Contact's photo uri's are wrong联系人的照片 uri 错误
【发布时间】:2016-09-30 11:27:59
【问题描述】:

我想获取联系人列表(姓名和照片)并显示 它在 RecyclerView 中。

我使用了几种方法,但他们只有一种 常见问题:联系人的照片和姓名 - 不匹配

即每个联系人的照片 uri 都是错误的和混淆的。

我尝试使用这些方法:

这是最重要的:

模型类

public class ContactModel {

  private String name;
  private String photoUri;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getPhotoUri() {
    return photoUri;
  }

  public void setPhotoUri(String photoUri) {
    this.photoUri = photoUri;
  }
}

XML 项

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
  >

    <data>

        <variable
            name="contact"
            type="xyz.letscoder.testcontacts.model.ContactModel" />
    </data>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/item_contact_icon"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_marginBottom="16dp"
            app:icon="@{contact.photoUri}"
            android:layout_marginTop="16dp" />

        <TextView
            android:id="@+id/item_contact_name"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:layout_marginLeft="16dp"
            android:layout_marginStart="16dp"
            android:gravity="center"
            android:text="@{contact.name}" />

    </LinearLayout>
</layout>

适配器代码

public class ContactItemAdapter
    extends RecyclerView.Adapter<ContactItemAdapter.ContactItemViewHolder> {

  private List<ContactModel> contacts;

  public ContactItemAdapter(List<ContactModel> contacts) {
    this.contacts = contacts;
  }

  @Override
  public ContactItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    ItemContactBinding binding = ItemContactBinding.inflate(inflater, parent, false);
    return new ContactItemViewHolder(binding.getRoot());
  }

  @Override
  public void onBindViewHolder(ContactItemViewHolder holder, int position) {
    ContactModel model = contacts.get(position);
    holder.binding.setContact(model);
  }

  @Override
  public int getItemCount() {
    return contacts.size();
  }

  /**
   * ViewHolder for contact item
   */
  class ContactItemViewHolder extends RecyclerView.ViewHolder {

    private ItemContactBinding binding;

    ContactItemViewHolder(View itemView) {
      super(itemView);
      binding = DataBindingUtil.bind(itemView);
    }

  }

  /**
   * Bind icon
   */
  @BindingAdapter("bind:icon")
  public static void loadIcon(ImageView imageView, String v) {
    if(v != null)
    imageView.setImageURI(Uri.parse(v));
  }

}

活动代码

public class MainActivity extends AppCompatActivity {

  private RecyclerView recyclerView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    setupRecyclerView();
  }

  private void setupRecyclerView() {
    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(layoutManager);
    showContacts();
  }

  private void showContacts() {
    if (PermissionUtils.isReadContactsPermissionGranted(this)) {
      setupAdapter();
    } else {
      PermissionUtils.requestReadContactsPermission(this);
    }
  }

  private void setupAdapter() {
    ContactItemAdapter adapter = new ContactItemAdapter(fetchContacts());
    recyclerView.setAdapter(adapter);
  }

  // Commented code is the methods of get contacts
  private List<ContactModel> fetchContacts() {
    /*return ContactFetchUtils.getContactsWithNativeMethod(this);*/
    /*return ContactFetchUtils.getContactsWithEasyProvidersLibrary(this);*/
    return ContactFetchUtils.getContactsWithContactsLibrary();
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
      @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (PermissionUtils.isReadContactsPermissionGranted(requestCode, grantResults)) {
      setupAdapter();
    }

  }
}

获取联系人实用程序代码

public final class ContactFetchUtils {

  private ContactFetchUtils() { /* empty private constructor */ }

  // standart android method
  public static List<ContactModel> getContactsWithNativeMethod(Context context) {
    List<ContactModel> contacts = new ArrayList<>();
    Cursor phones = context.getContentResolver()
        .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null, null, null, null);
    while (phones.moveToNext()) {

      String name = phones.getString(
          phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
      String photoUri = phones.getString(
          phones.getColumnIndex(ContactsContract.CommonDataKinds.Photo.PHOTO_THUMBNAIL_URI));

      ContactModel contact = new ContactModel();
      contact.setPhotoUri(photoUri);
      contact.setName(name);
      contacts.add(contact);

    }
    phones.close();
    return contacts;
  }

  // me.everything.providers
  public static List<ContactModel> getContactsWithEasyProvidersLibrary(Context context) {
    ContactsProvider provider = new ContactsProvider(context);
    List<ContactModel> models = new ArrayList<>();
    List<me.everything.providers.android.contacts.Contact> contacts = provider.getContacts()
        .getList();
    for (me.everything.providers.android.contacts.Contact contact : contacts) {
      ContactModel model = new ContactModel();
      model.setName(contact.displayName);
      model.setPhotoUri(contact.uriPhoto);
      models.add(model);
    }
    return models;
  }

  // com.github.tamir7.contacts
  public static List<ContactModel> getContactsWithContactsLibrary() {
    List<Contact> contacts = Contacts.getQuery().find();
    List<ContactModel> models = new ArrayList<>();
    for (Contact contact : contacts) {
      ContactModel model = new ContactModel();
      model.setName(contact.getDisplayName());
      model.setPhotoUri(contact.getPhotoUri());
      models.add(model);
    }
    return models;
  }
}

问题存在于所有设备上,我已经测试过:

  • 小米红米 Note 2 - 5.1.0

  • 三星 Galaxy S6 - 6.0.1

  • Nexus 5x - 7.0.0

【问题讨论】:

    标签: android


    【解决方案1】:

    经过一些调试,我得到了答案。 似乎问题实际上是 RecyclerView 正在重用旧视图来显示信息,并且由于这段代码它使用了另一张照片:

    @BindingAdapter("bind:icon")
      public static void loadIcon(ImageView imageView, String v) {
        if(v != null)
        imageView.setImageURI(Uri.parse(v));
      }
    

    当我把它改成:

    @BindingAdapter("bind:icon")
      public static void loadIcon(ImageView imageView, String v) {
        if (v == null || v.equals("")) {
          imageView.setImageURI(null);
        } else {
          imageView.setImageURI(Uri.parse(v));
        }
      }
    

    一切都好了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      • 2014-01-14
      • 2011-09-23
      相关资源
      最近更新 更多