我正在尝试从电话簿中获取与其关联的号码的所有联系人。我在这里遇到 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
,这样只有在提取整个电话簿时才会关闭光标。
我是一名优秀的程序员,十分优秀!