RxAndroid:如何从电话簿中提取所有联系人?

时间:2018-07-26 12:44:11

标签: java android rx-java2

我正在尝试从电话簿中获取所有与之关联的联系人。我在这里遇到2个问题,

1。我无法获得所有联系人。
我正在获取联系人的所有电话号码,但是只给了我约154个电话号码,该电话号码以字母M开头,最后一个电话号码被切成两半(只有前5个数字被打印出来,最后5个都找不到),而列表一直排到“ z”。

2。无法获得单个联系人
电话簿中有一些重复的内容,为此,我只想获得截然不同的详细信息,但是我无法获得单个联系人并确保其唯一性。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_tab2, container, false);
    mbutton = v.findViewById(R.id.extractContact);

    mbutton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // Here, thisActivity is the current activity
            if (ContextCompat.checkSelfPermission(getContext(),
                    Manifest.permission.READ_CONTACTS)
                    != PackageManager.PERMISSION_GRANTED) {

                // Permission is not granted
                // Should we show an explanation?
                if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                        Manifest.permission.READ_CONTACTS)) {
                    // Show an explanation to the user *asynchronously* -- don't block
                    // this thread waiting for the user's response! After the user
                    // sees the explanation, try again to request the permission.
                } else {
                    // No explanation needed; request the permission
                    ActivityCompat.requestPermissions(getActivity(),
                            new String[]{Manifest.permission.READ_CONTACTS},
                            MY_PERMISSIONS_REQUEST_READ_CONTACTS);

                    // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
                    // app-defined int constant. The callback method gets the
                    // result of the request.
                }
            } else {
                // Permission has already been granted
                Observer observer = new Observer() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Object o) {
                        Log.d("Observer_contact", (String) o);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        Log.d("Observer_contact", "Completed");
                    }
                };

                io.reactivex.Observable.create(new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                        try {
                            emitter.onNext(loadContacts());
                            emitter.onComplete();
                        } catch (Exception e) {
                            emitter.onError(e);
                        }
                    }
                }).subscribeOn(Schedulers.io())
                        .distinct()
                        .subscribeWith(observer);

            }
        }
    });



    // Inflate the layout for this fragment
    return v;
}  

下面的代码应该提取联系人,但是我无法弄清楚如何一次返回单个联系人,所以现在我正在使用StringBuilder返回整个记录。

public String loadContacts() {
    StringBuilder mBuilder = new StringBuilder();
    ContentResolver mContentResolver = getActivity().getContentResolver();
    Cursor mCursor = mContentResolver.query(ContactsContract.Contacts.CONTENT_URI,
            null, null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");

    if (mCursor.getCount() > 0 ) {
        while (mCursor.moveToNext()) {
            String id = mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts._ID));
            String name = mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            int hasPhoneNumber = Integer.parseInt(mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));

            if (hasPhoneNumber > 0) {
                Cursor cursor = mContentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "= ?",
                        new String[]{id}, null);

                while (cursor.moveToNext()) {
                    String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    phoneNumber = phoneNumber.replaceAll("\\s","");
                    mBuilder.append(name).append(", ").append(phoneNumber).append("\n");
                }

                cursor.close();
            }
        }
    }
    mCursor.close();

    return mBuilder.toString();
}

1 个答案:

答案 0 :(得分:0)

我可以使用以下代码更改来解决此问题:

在loadContacts(){}

    if (hasPhoneNumber > 0) {
        mBuilder.append("\"").append(name).append("\"");
        Cursor cursor = mContentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                null,
                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "= ?",
                new String[]{id}, null);

        assert cursor != null;
        while (cursor.moveToNext()) {
            String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
                    .replaceAll("\\s", "");

            // if number is not existing in the list, then add number to the string
            if (!(mBuilder.toString().contains(phoneNumber))) {
                mBuilder.append(", ").append(phoneNumber);
            }
        }

        cursor.close();
    }

并在调用onNext()方法时,使其对每个联系人都运行:

try {
    for (count = 0; count < mCursor.getCount(); count++) {
        emitter.onNext(loadContacts(count));
    }
    emitter.onComplete();
}

这样,可观察对象以字符串形式为每个联系人发出详细信息,并且字符串中的所有数字都是唯一的。另外,请确保用mCursor关闭onComplete(),以便仅在提取完整个电话簿后才关闭光标。