Реализация RecyclerView для отображения контактов устройства, используя ContactsContract, но есть ошибка. Я задействовал код ошибки gradle ниже

#java #android

#java #Android

Вопрос:

Я попытался показать контакты устройства в recyclerview. Я использую ContactsContract для заполнения списка. Я думаю, ошибка в том, что контакты не извлекаются, но я не знаю почему.

Не могли бы вы, пожалуйста, проверить мою ошибку?

Ошибка:

     10-11 17:50:21.550 27076-27076/com.example.anubh.contactsearch D/Proxy: setHttpRequestCheckHandler
    10-11 17:50:21.694 27076-27076/com.example.anubh.contactsearch D/OpenSSLLib: OpensslErr:Module:13(114:155); file:external/openssl/crypto/asn1/asn1_lib.c ;Line:142;Function:ASN1_get_object
    10-11 17:50:22.532 27076-27076/com.example.anubh.contactsearch D/ActivityThread: BIND_APPLICATION handled : 0 / AppBindData{appInfo=ApplicationInfo{14eaff4b com.example.anubh.contactsearch}}
    10-11 17:50:22.533 27076-27076/com.example.anubh.contactsearch V/ActivityThread: Handling launch of ActivityRecord{d9bd28 token=android.os.BinderProxy@2947ea41 {com.example.anubh.contactsearch/com.example.anubh.contactsearch.MainActivity}}
    10-11 17:50:22.803 27076-27076/com.example.anubh.contactsearch V/ActivityThread: ActivityRecord{d9bd28 token=android.os.BinderProxy@2947ea41 {com.example.anubh.contactsearch/com.example.anubh.contactsearch.MainActivity}}: app=android.app.Application@4684527, appName=com.example.anubh.contactsearch, pkg=com.example.anubh.contactsearch, comp={com.example.anubh.contactsearch/com.example.anubh.contactsearch.MainActivity}, dir=/data/app/com.example.anubh.contactsearch-1/base.apk
    10-11 17:50:22.941 27076-27076/com.example.anubh.contactsearch W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
    10-11 17:50:23.147 27076-27076/com.example.anubh.contactsearch I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
    10-11 17:50:23.440 27076-27076/com.example.anubh.contactsearch D/ActivityThread: hoder:android.app.IActivityManager$ContentProviderHolder@36d02546,provider,holder.Provider:android.content.ContentProviderProxy@1c1f6307
    10-11 17:50:23.482 27076-27076/com.example.anubh.contactsearch I/System.out: Name: Micromax carephone: 18605008286
    10-11 17:50:23.486 27076-27076/com.example.anubh.contactsearch D/AndroidRuntime: Shutting down VM
    10-11 17:50:23.487 27076-27076/com.example.anubh.contactsearch E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                     Process: com.example.anubh.contactsearch, PID: 27076
                                                                                     java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.anubh.contactsearch/com.example.anubh.contactsearch.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'boolean java.util.List.add(java.lang.Object)' on a null object reference
                                                                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2455)
                                                                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2517)
                                                                                         at android.app.ActivityThread.access$800(ActivityThread.java:162)
                                                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
                                                                                         at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                                         at android.os.Looper.loop(Looper.java:189)
                                                                                         at android.app.ActivityThread.main(ActivityThread.java:5530)
                                                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                                                         at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950)
                                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
                                                                                      Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'boolean java.util.List.add(java.lang.Object)' on a null object reference
                                                                                         at com.example.anubh.contactsearch.myAdapter.<init>(myAdapter.java:71)
                                                                                         at com.example.anubh.contactsearch.MainActivity.onCreate(MainActivity.java:30)
                                                                                         at android.app.Activity.performCreate(Activity.java:5966)
                                                                                         at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                                                                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2408)
                                                                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2517) 
                                                                                         at android.app.ActivityThread.access$800(ActivityThread.java:162) 
                                                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412) 
                                                                                         at android.os.Handler.dispatchMessage(Handler.java:106) 
                                                                                         at android.os.Looper.loop(Looper.java:189) 
                                                                                         at android.app.ActivityThread.main(ActivityThread.java:5530) 
                                                                                         at java.lang.reflect.Method.invoke(Native Method) 
                                                                                         at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950) 
                                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:74510-11 17:50:29.394 27076-27089/com.example.anubh.contactsearch W/CursorWrapperInner: Cursor finalized without prior close()
  

MainActivity.java

     package com.example.anubh.contactsearch;

    import android.os.AsyncTask;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.Toolbar;
    import android.view.Menu;

    import java.util.ArrayList;

    public class MainActivity extends AppCompatActivity {

        Toolbar toolbar;
        RecyclerView recyclerView;
        myAdapter adapter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);

            //getSupportActionBar().setTitle("Contacts");
            getSupportActionBar().setSubtitle("Search");
            getSupportActionBar().setIcon(R.drawable.ic_action_toolbar);

            recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
            adapter = new myAdapter(this);

            recyclerView.setAdapter(adapter);
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.menu,menu);
            return super.onCreateOptionsMenu(menu);
        }
    }
  

myAdapter.java

     package com.example.anubh.contactsearch;

    import android.content.ContentResolver;
    import android.content.Context;
    import android.database.Cursor;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.net.Uri;
    import android.provider.ContactsContract;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.TextView;

    import java.io.BufferedInputStream;
    import java.io.InputStream;
    import java.util.List;

    public class myAdapter extends RecyclerView.Adapter<ListViewHolder>{

        private List<ListItems> listItemsList;
        private Context mContext;
        private int focusedItem = 0;

        public myAdapter(Context context){
            mContext = context;

            ContentResolver cr = mContext.getContentResolver();
            Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
            String name;
            String phone = null;
            String image_uri = "";
            ListItems listItems;
            int i = 1;
            if (cur.getCount() > 0) {
                while (cur.moveToNext()) {
                    if(i == 1){
                        cur.moveToFirst();
                        i  ;
                    }
                    String id = cur.getString(cur
                            .getColumnIndex(ContactsContract.Contacts._ID));
                    name = cur
                            .getString(cur
                                    .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

                    image_uri = cur
                            .getString(cur
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
                    Cursor pCur = cr.query(
                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                            null,
                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                      " = ?", new String[]{id}, null);
                    if (pCur.moveToNext()) {
                        phone = pCur
                                .getString(pCur
                                        .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                        System.out.println("Name: "  name   "phone: "   phone);
                    }
                    pCur.close();
                    listItems = new ListItems(name,phone,image_uri);
                    listItemsList.add(listItems);
                }
                cur.close();
            }
        }
        @Override
        public ListViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
            Context context = viewGroup.getContext();
            LayoutInflater layoutInflater = LayoutInflater.from(context);
            View v = layoutInflater.inflate(R.layout.list_row,null);
            //View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row,null);
            ListViewHolder holder = new ListViewHolder(v);

            holder.relativeLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                }
            });

            return holder;
        }

        @Override
        public void onBindViewHolder(ListViewHolder holder, int position) {
            ListItems listItems = listItemsList.get(position);

            TextView contact_name = holder.contactname;
            TextView contact_num = holder.contactnum;
            ImageView contact_image = holder.contactimage;

            contact_name.setText(listItems.getContactname());
            contact_num.setText(listItems.getContactnum());
            Uri myuri = Uri.parse(listItems.getThumbnail());
            InputStream photo_stream = ContactsContract.Contacts.openContactPhotoInputStream(mContext.getContentResolver(),myuri);
            BufferedInputStream buf =new BufferedInputStream(photo_stream);
            Bitmap my_btmp = BitmapFactory.decodeStream(buf);
            contact_image.setImageBitmap(my_btmp);
        }

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

ListViewHolder.java

     package com.example.anubh.contactsearch;

    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.RelativeLayout;
    import android.widget.TextView;

    public class ListViewHolder extends RecyclerView.ViewHolder {
        protected ImageView contactimage;
        protected TextView contactname,contactnum;
        protected RelativeLayout relativeLayout;
        public ListViewHolder(View view){
            super(view);

            contactimage = (ImageView)view.findViewById(R.id.contactimage);
            contactname = (TextView) view.findViewById(R.id.contactname);
            contactnum = (TextView) view.findViewById(R.id.contactno);
            relativeLayout = (RelativeLayout) view.findViewById(R.id.relativeLayout);

            view.setClickable(false);
        }
    }
  

ListItems.java

     package com.example.anubh.contactsearch;

    public class ListItems {
        private String Contactname,contactnum,thumbnail;

        public ListItems(String name,String number,String imageuri){
            this.Contactname = name;
            this.contactnum = number;
            this.thumbnail = imageuri;
        }

        public String getContactname() {
            return Contactname;
        }

        public void setContactname(String contactname) {
            Contactname = contactname;
        }

        public String getContactnum() {
            return contactnum;
        }

        public void setContactnum(String contactnum) {
            this.contactnum = contactnum;
        }

        public String getThumbnail() {
            return thumbnail;
        }

        public void setThumbnail(String thumbnail) {
            this.thumbnail = thumbnail;
        }
    }
  

Manifest.xml

     <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.anubh.contactsearch">
        <uses-permission android:name="android.permission.READ_CONTACTS" />
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.Main" />

                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>

                <meta-data android:name="android.app.searchable"
                    android:resource="@xml/searchable"/>
            </activity>
        </application>

    </manifest>
  

Ответ №1:

Добавьте эту строку в конструктор «MyAdapter».

 listItemsList = new ArrayList<>();
  

Комментарии:

1. Огромное спасибо! Это сработало. Контакты были считаны, но recyclerview ничего не показал. Результатом был пустой экран.

2. Я проверил. Что я смог найти, так это ListItems.Метод getThumbnail() возвращает null. Я не знаю причины этого.

3. ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: main java.lang. Исключение IllegalArgumentException: URI: content://com.android.contacts/contacts/1/photo/photo, вызывающий пользователя: com.example.anubh.contactsearch, вызывающий пакет:com.example.anubh.contactsearch в android.database. DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)

4. Также приложение вылетает, если я продолжаю прокручивать его вниз. Извините, я в этом совершенно новичок.

5. Uri myuri = ListItems.getThumbnail(); Входной поток photo_stream = ContactsContract . Contacts.openContactPhotoInputStream(mContext.getContentResolver(),myuri); BufferedInputStream buf = новый BufferedInputStream(photo_stream); Bitmap my_btmp = BitmapFactory.decodeStream(buf); contact_image.setImageBitmap(my_btmp);

Ответ №2:

Я знаю, что это старая тема, но я проверил ваш код, потому что я делаю что-то подобное. Я видел, что у вас были проблемы с RecyclerView тем, что вы ничего не показывали, и проблема может быть в том, как вы обрабатываете свой ListItems объект.

Прежде всего, вы забыли о менеджере компоновки в MainActivity.java :

 recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
  

Во-вторых, у вас нет проверок, чтобы определить, есть ли у пользователя изображение, потому что в случае, если этого не произойдет, вы получите ошибку исключения нулевого указателя. Когда вы сохраняете null значение в своей thumbnail переменной, позже пытаетесь получить к нему доступ в адаптере

 Uri myuri = Uri.parse(listItems.getThumbnail());
  

отсутствует простая проверка, например

 if (listItems.getThumbnail() != null) {
    Uri myuri = Uri.parse(listItems.getThumbnail());
    InputStream photo_stream = ContactsContract.Contacts.openContactPhotoInputStream(mContext.getContentResolver(),myuri);
    BufferedInputStream buf =new BufferedInputStream(photo_stream);
    Bitmap my_btmp = BitmapFactory.decodeStream(buf);
    contact_image.setImageBitmap(my_btmp);
} else {
    // Find an alternative method, like displaying custom ImageView with name initials
}
  

Наконец, я хотел бы указать на избыточный if оператор в конструкторе адаптера

 if(i == 1){
    cur.moveToFirst();
    i  ;
}
  

Нет необходимости выполнять дополнительную проверку, вы можете просто сказать

 cur.moveToFirst();