1

我正在尝试通过提供电话号码来获取未本地存储在我的设备上但在 Microsoft Exchange ActiveSync 目录中找到的联系人。我关注了 igorepst 的帖子,该帖子提供了一个简单的按名称检索联系人的解决方案,并且我尝试对其进行修改以满足我的需要,但我被卡住了。

这是代码让我按名称获取联系人

主要活动

public class MainActivity extends AppCompatActivity {

    static final String TAG = "MAIN";
    private ArrayList<Long> dirIds;
    private String[] projection;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);

        if (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.WRITE_CONTACTS}, 1);
        }

        if (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.READ_CONTACTS}, 1);
        }

        CursorQueryWrapper wrapper = new CursorQueryWrapper(TAG);
        dirIds = new ArrayList<Long>();
        wrapper.query(this, ContactsContract.Directory.CONTENT_URI, new String[]{
                        ContactsContract.Directory._ID, ContactsContract.Directory.ACCOUNT_NAME, ContactsContract.Directory.ACCOUNT_TYPE
                }, null, null, null,
                new CursorQueryWrapper.CursorResultIterator() {
                    @Override
                    public void iterate(Cursor cursor) throws Exception {
                        long id = cursor.getLong(0);
                        if (ContactsContract.Directory.DEFAULT != id && ContactsContract.Directory.LOCAL_INVISIBLE != id) {
                            dirIds.add(id);
                            Log.d(TAG, "Account: id=" + id + " name=" + cursor.getString(1) + " type=" + cursor.getString(2));
                        }
                    }
                });
        if (dirIds.isEmpty()) {
            String result = "Cannot find additional accounts";
            Log.e(TAG, result);
            textView.setText(result);
        }else{
            HashSet<String> projSet = new HashSet<String>();
            projSet.add(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
            projSet.add(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
            projSet.add(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
            projSet.add(ContactsContract.CommonDataKinds.Email.ADDRESS);
            projSet.add(ContactsContract.CommonDataKinds.Phone.NUMBER);
            projSet.add(ContactsContract.Contacts.Data.MIMETYPE);
            projSet.add(ContactsContract.CommonDataKinds.Email.TYPE);
            projSet.add(ContactsContract.CommonDataKinds.Phone.TYPE);
            projection = projSet.toArray(new String[projSet.size()]);

            final String searchStr = "SOME NAME";

            new Thread(new Runnable() {
                @Override
                public void run() {
                    final String result;
                    if (TextUtils.isEmpty(searchStr)) {
                        result = "No input";
                    } else {
                        result = search(searchStr);
                    }

                    System.out.println(result);
                }
            }).start();

        }
    }

    private String search(final String searchString) {
        final StringBuilder bld = new StringBuilder();
        CursorQueryWrapper wrapper = new CursorQueryWrapper(TAG);
        final Context context = this;
        for (Long id : dirIds) {
            final String idStr = String.valueOf(id);
            Uri uri = ContactsContract.Contacts.CONTENT_FILTER_URI.buildUpon().appendEncodedPath(searchString)
                    .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, idStr).build();

            final ArrayList<String> lookupKeys = new ArrayList<String>();
            wrapper.query(context, uri, new String[] {
                    ContactsContract.Contacts.LOOKUP_KEY
            }, null, null, null, new CursorQueryWrapper.CursorResultIterator() {
                @Override
                public void iterate(Cursor cursor) throws Exception {
                    lookupKeys.add(cursor.getString(0));
                }
            });
            if (lookupKeys.isEmpty()) {
                continue;
            }

            for (String lookupKey : lookupKeys) {
                uri = ContactsContract.Contacts.CONTENT_LOOKUP_URI.buildUpon().appendEncodedPath(lookupKey)
                        .appendPath(ContactsContract.Contacts.Entity.CONTENT_DIRECTORY)
                        .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, idStr).build();
                wrapper.query(context, uri, projection, null, null, null, new CursorQueryWrapper.CursorResultIterator() {
                    @Override
                    public void iterate(Cursor cursor) throws Exception {
                        String mime = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.Data.MIMETYPE));
                        if (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE.equals(mime)) {
                            String result = "Given name:"
                                    + cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME))
                                    + " Family name:"
                                    + cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME))
                                    + " Display name:"
                                    + cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
                            Log.d(TAG, result);
                            bld.append(result).append('\n');
                        } else if (ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE.equals(mime)) {
                            String result = "Email address:"
                                    + cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS))
                                    + " with type:"
                                    + ContactsContract.CommonDataKinds.Email.getTypeLabel(context.getResources(), cursor.getInt(cursor
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE)), null);
                            Log.d(TAG, result);
                            bld.append(result).append('\n');
                        }
                        else if (ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE.equals(mime)) {
                            String result = "Phone num:"
                                    + cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
                                    + " with type:"
                                    + ContactsContract.CommonDataKinds.Phone.getTypeLabel(context.getResources(), cursor.getInt(cursor
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)), null);
                            Log.d(TAG, result);
                            bld.append(result).append('\n');
                        }
                    }
                });
                String result = "*************************************";
                Log.d(TAG, result);
                bld.append(result).append('\n');
            }
        }
        if (bld.length() == 0) {
            String result = "Cannot find matching contacts for the string '" + searchString + "'";
            Log.d(TAG, result);
            return result;
        }
        return bld.toString();
    }
}

CursorQueryWrapper

public class CursorQueryWrapper {

    private final String tag;
    private QueryInterface queryInterface;

    public static class CursorIteratonInterrupt extends Exception {
        private static final long serialVersionUID = -1124533346986767621L;
    }

    public static abstract class CursorResultIterator {
        public void iterate(Cursor cursor) throws Exception {
        }

        public boolean shouldIterate() {
            return true;
        }

        public void prepareForIterations(Cursor cursor) {
        }
    }

    public interface QueryInterface {
        Cursor query(Context context, Uri uri, String[] projection,
                     String selection, String[] selectionArgs, String sortOrder);
    }

    public static class ContextQuery implements QueryInterface {

        @Override
        public Cursor query(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs,
                            String sortOrder) {
            return context.getContentResolver()
                    .query(uri, projection, selection, selectionArgs, sortOrder);
        }

    }

    public CursorQueryWrapper(final String tag) {
        this(tag, null);
    }

    public CursorQueryWrapper(final String tag, QueryInterface queryInterface) {
        this.tag = tag;
        this.queryInterface = queryInterface == null ? new ContextQuery() : queryInterface;
    }

    public boolean query(Context context, Uri uri, String[] projection,
                         String selection, String[] selectionArgs, String sortOrder, CursorResultIterator iterator) {
        Cursor cursor = null;
        Log.d(tag, "Starting query");
        try {
            StringBuilder bld = new StringBuilder(
                    "Running query");
            bld.append("\nUri: ").append(uri.toString());
            bld.append("\nProjection: ").append(projection == null ? "null" : TextUtils.join(", ", projection));
            bld.append("\nSelection: ").append(selection);
            bld.append("\nSelectionArgs: ").append(
                    selectionArgs == null ? "null" : TextUtils.join(", ", selectionArgs));
            bld.append("\nSortOrder: ").append(sortOrder);
            Log.d(tag, bld.toString());
            cursor = queryInterface.query(context, uri, projection, selection, selectionArgs, sortOrder);
            if (cursor == null) {
                Log.e(tag, "Cannot process the query. The cursor is null as a result of some error.");
                return false;
            }
            Log.d(tag, "Cursor's count is " + cursor.getCount());
            iterator.prepareForIterations(cursor);
            if (iterator.shouldIterate()) {
                while (cursor.moveToNext()) {
                    iterator.iterate(cursor);
                }
            }
        } catch (Exception e) {
            if (!(e instanceof CursorIteratonInterrupt)) {
                Log.e(tag,
                        "Cannot process the query.", e);
                return false;
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        Log.d(tag, "The query is ended successfully");
        return true;
    }

}

现在,为了按号码获取联系人,我将搜索方法(MainActivity)的第一个 Uri 更改为:

    Uri uri = ContactsContract.Contacts.CONTENT_FILTER_URI.buildUpon().appendEncodedPath("SOME PHONE NUMBER")
        .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, idStr).build();

但它永远找不到任何结果。我在这里错过了什么?

4

0 回答 0