java - RxAndroid : How can I extract all contacts from phonebook?

标签 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();
}

最佳答案

我能够使用这些代码更改解决此问题:

在 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();
}

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

关于java - RxAndroid : How can I extract all contacts from phonebook?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51539150/

相关文章:

java - 适用于 Android 的扫描仪(条形码)Api 无法检测到条形码

android - 如何以及在何处使用 Fragments 中的 setInitialSavedState 和 saveFragmentInstanceState

android - 如何使用 MediaPlayer (android) 同时播放两个或多个音频 fragment

没有gcm的Android推送消息可能吗?

java - 与 mySQL 一起使用的自动 java 类

Java - 接口(interface)方法

c# - 如何确定 Windows Java 安装位置

android - 数据绑定(bind) ViewModel 与 RxJava 2

android - RxJava 事件总线

java - rxjava 当超时时跳过项目并继续下一个项目