ContactsContract.PhoneLookup.NUMBER使ContentResolver查询崩溃

时间:2014-05-20 01:03:50

标签: android crash

我正在尝试向我的联系人应用发送隐含意图,以便用户选择联系人。我的应用程序将提取该联系人的姓名和电话号码,以便在应用程序中使用。

(注意:我在BigNerdRanch的Android书的第21章,做了挑战所以没有回答键。我查看他们的[非活动]论坛,但找不到这个bug的解释。)

首先,本书教程让它在查询中只包含名称的地方工作。但是,当我尝试为电话号码添加另一列时,每次选择联系人时都会崩溃,因此正在返回发送隐式意图的原始活动。

我想也许它崩溃了,因为我选择的联系人没有存储电话号码?所以我试了一个电话号码和名字,但它仍然崩溃了。

这是代码,所有代码都具有相同的类(扩展了支持片段)。谢谢你的帮助!

FWIW:这里是你可以在这里下载第21章解决方案的页面http://www.bignerdranch.com/we-write/android-programming,它基本上显示了我所拥有的所有代码,除了我改变以解决挑战问题。

onCreateView(...):

...
mSuspectButton = (Button)v.findViewById(R.id.crime_suspectButton);
        mSuspectButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
                startActivityForResult(i, REQUEST_CONTACT);
            }
        });
        if(mCrime.getSuspect() != null) {
            mSuspectButton.setText(mCrime.getSuspect());
        }

        mDialButton = (Button)v.findViewById(R.id.crime_dialButton);
        if(mCrime.getPhoneNumber() == null) {
            mDialButton.setVisibility(View.INVISIBLE);
        }
        mDialButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(Intent.ACTION_DIAL, mCrime.getPhoneNumber());
            }
        });
        return v;
    }

onActivityResult:

当代码是这样时,它会崩溃。

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CONTACT) {
        Uri contactUri = data.getData();
            //Specify which fields you want your query to return values for.
            String[] queryFields = new String[] {

                    ContactsContract.Contacts.DISPLAY_NAME,
                    ContactsContract.PhoneLookup.NUMBER
            };

            //Perform your query - the contactUri is like a "where" clause here
            Cursor c = getActivity().getContentResolver().query(contactUri, queryFields, null, null, null);

            //Double-check that you actually got results
            if (c.getCount() == 0) {
                c.close();
                return;
            }

            //Pull out the first column of the first row of data - that is your suspect's name.
            c.moveToFirst();
            Log.d(TAG, "" + c.getColumnCount());
            String suspect = c.getString(0);
            String phoneNumber = "1"; //c.getString(1);  
            mCrime.setSuspect(suspect);
            mCrime.setPhoneNumber(phoneNumber);
            if(mCrime.getPhoneNumber() == null) {
                mDialButton.setVisibility(View.INVISIBLE);
            }
            mSuspectButton.setText(suspect);

            c.close();


        }

注意:在这一行

String phoneNumber = "1"; //c.getString(1);  

它应该是“c.getString(1)”,但我正在测试任何数字,看它是否仍会崩溃,它仍然存在。

当我用此替换查询时,

String[] queryFields = new String[] {

                    ContactsContract.Contacts.DISPLAY_NAME
            };

然后它工作正常,并没有崩溃。

logcat的:

05-19 18:38:38.462: E/AndroidRuntime(20212): FATAL EXCEPTION: main
05-19 18:38:38.462: E/AndroidRuntime(20212): Process: com.bignerdranch.android.criminalintent, PID: 20212
05-19 18:38:38.462: E/AndroidRuntime(20212): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65539, result=-1, data=Intent { dat=content://com.android.contacts/contacts/lookup/133r155-3D2F5537/155 flg=0x1 }} to activity {com.bignerdranch.android.criminalintent/com.bignerdranch.android.criminalintent.CrimePagerActivity}: java.lang.IllegalArgumentException: Invalid column number
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3365)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3408)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.app.ActivityThread.access$1300(ActivityThread.java:135)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.os.Handler.dispatchMessage(Handler.java:102)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.os.Looper.loop(Looper.java:136)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.app.ActivityThread.main(ActivityThread.java:5017)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at java.lang.reflect.Method.invokeNative(Native Method)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at java.lang.reflect.Method.invoke(Method.java:515)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at dalvik.system.NativeStart.main(Native Method)
05-19 18:38:38.462: E/AndroidRuntime(20212): Caused by: java.lang.IllegalArgumentException: Invalid column number
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.content.ContentProviderProxy.query(ContentProviderNative.java:413)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.content.ContentResolver.query(ContentResolver.java:461)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.content.ContentResolver.query(ContentResolver.java:404)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at com.bignerdranch.android.criminalintent.CrimeFragment.onActivityResult(CrimeFragment.java:618)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:166)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.app.Activity.dispatchActivityResult(Activity.java:5423)
05-19 18:38:38.462: E/AndroidRuntime(20212):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3361)
05-19 18:38:38.462: E/AndroidRuntime(20212):    ... 11 more
05-19 18:38:40.382: D/Lexi(20281): {"location":"provo","age":"22","name":"Lexi"}
05-19 18:38:40.422: I/Adreno-EGL(20281): <qeglDrvAPI_eglInitialize:320>: EGL 1.4 QUALCOMM Build: I0404c4692afb8623f95c43aeb6d5e13ed4b30ddbDate: 11/06/13
05-19 18:38:40.442: D/OpenGLRenderer(20281): Enabling debug mode 0

2 个答案:

答案 0 :(得分:0)

请尝试使用此代码,您将获得一个电话号码。

Uri contactUri = data.getData();

                Cursor c = getActivity().getContentResolver().query(contactUri,
                        null, null, null, null);

                if (c.getCount() == 0) {
                    c.close();
                    return;
                }

                if (c.moveToFirst()) {
                    String name = c
                            .getString(c
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    String phoneNumber = c
                            .getString(c
                                    .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
                    String contactId = c.getString(c
                            .getColumnIndex(ContactsContract.Contacts._ID));
                    if (phoneNumber.equals("1")) {
                        Cursor phones = getActivity()
                                .getContentResolver()
                                .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                        null,
                                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                                + " = " + contactId, null, null);
                        while (phones.moveToNext()) {
                            phoneNumber = phones
                                    .getString(phones
                                            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        }
                        phones.close();
                    }
                    Log.d("Stack",
                            name + " " + " " + phoneNumber + " "
                                    + c.getColumnCount());
                }
                c.close();

注意: - 实际上,您正在尝试提取数据表单列(列名称&#34;数字&#34;),这些列不存在于&#34; ContactsContract.Contacts.CONTENT_URI&#34;这就是为什么得到异常的原因java.lang.IllegalArgumentException:列号无效

答案 1 :(得分:0)

现在已经很晚了,但我相信有一个更好,更干净的替代方案来解决你所面临的问题。只需在代码中添加以下行。

String SELECTION = ContactsContract.Contacts.HAS_PHONE_NUMBER "='1'";
Cursor c = getActivity().getContentResolver().query(contactUri, queryFields, SELECTION, null, null);

选择参数HAS_PHONE_NUMBER = 1确保您只检索具有至少1个电话号码的联系人。因此不会发生非法的列索引异常。