【问题标题】:Making a contact app. Getting the hang of quering制作联系人应用程序。掌握查询的窍门
【发布时间】:2013-06-19 06:57:47
【问题描述】:

我是在互联网的帮助下自己制作的,并参考了几本书。下面的代码提取特定联系人的姓名和电话号码,并且可以正常工作(甜蜜)。我的问题是关于 selection 和 selectionArgs。如何添加电子邮件查询?

我不理解所有的等号和 AND withing 引号,所以如果你能指出我可以在哪里了解更多关于“选择”中使用的语言,而不是仅仅在代码中给我答案,那就是d 也极大地帮助了我。

提前致谢

import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.TextView;

/**
 * Created by Pete on 6/19/13.
 */
public class ContactDetails extends Activity {

    TextView tvContactName, tvPhoneNum, tvPhoneType, tvPhoneFull,
            tvEmailAdd, tvEmailType, tvEmailFull,
            tvAddress, tvAddType, tvAddFull;

    String contactId, contactName, phoneType, phoneFull, phoneNum1,
            emailAdd, emailType, emailFull,
            address, addType, addFull;    

    //Contact List query arguments
    Uri uri;
    String[] projection, selectionArgs;
    String selection, sortOrder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.contactinfo);
        initialize();

        contactId = getIntent().getStringExtra("contactId");
        contactName = getIntent().getStringExtra("contactName");

        queryArgs();

        // Create cursor searching for data associated with contactId
        if (contactId != null) {
            // Return all the PHONE data for the contact            
            Cursor cursor = getContentResolver().query(
                    uri, projection, selection, selectionArgs, sortOrder);

            //Get the indexes of the required columns           
            while (cursor.moveToNext()) {
                // Extract the name
                contactName = cursor.getString(
                        cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
                tvContactName.setText(contactName);
                // Extract the phone number
                phoneFull = cursor.getString(
                        cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                tvPhoneFull.setText(phoneFull);
            }
            cursor.close();
        }        
    }

    public void initialize() {
        tvContactName = (TextView)findViewById(R.id.tvContactName);
        tvPhoneNum = (TextView)findViewById(R.id.tvPhoneNum);
        tvPhoneType = (TextView)findViewById(R.id.tvPhoneType);
        tvPhoneFull = (TextView)findViewById(R.id.tvPhoneFull);
        tvEmailAdd = (TextView)findViewById(R.id.tvEmailAdd);
        tvEmailType = (TextView)findViewById(R.id.tvEmailType);
        tvEmailFull = (TextView)findViewById(R.id.tvEmailFull);
        tvAddress = (TextView)findViewById(R.id.tvAddress);
        tvAddType = (TextView)findViewById(R.id.tvAddType);
        tvAddFull = (TextView)findViewById(R.id.tvAddFull);
    }

    public void queryArgs() {
        // Cursor query arguments
        uri = ContactsContract.Data.CONTENT_URI;
        projection = new String[] {
                ContactsContract.Data.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER
        };
        selection = ContactsContract.Data.CONTACT_ID + " = " + contactId + " AND " + 
                    ContactsContract.Data.MIMETYPE + " = " + 
                    ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'";
        selectionArgs = null;;
        sortOrder = null;
    }

    public void setTextValues() {
        tvContactName.setText(contactName);
        tvPhoneNum.setText(phoneNum1);
        tvPhoneType.setText(phoneType);
        tvPhoneFull.setText(phoneFull);
        tvEmailAdd.setText(emailAdd);
        tvEmailType.setText(emailType);
        tvEmailFull.setText(emailFull);
        tvAddress.setText(address);
        tvAddType.setText(addType);
        tvAddFull.setText(addFull);
    }
}

编辑: 我尝试了 Sandy09 的想法(减去我认为 cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER) 之后的错字);

现在我得到了这个错误,当我重新复制我的代码时,我仍然得到它(减去线程引用)。感谢所有帮助:

06-22 04:45:56.316: E/AndroidRuntime(8818): FATAL EXCEPTION: Thread-273
06-22 04:45:56.316: E/AndroidRuntime(8818): android.database.sqlite.SQLiteException: unrecognized token: "'vnd.android.cursor.item/phone_v2))" (code 1): , while compiling: SELECT DISTINCT display_name, data1 FROM view_data data WHERE (1) AND ((contact_id = 1 AND mimetype = 'vnd.android.cursor.item/phone_v2))
06-22 04:45:56.316: E/AndroidRuntime(8818):     at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:181)
06-22 04:45:56.316: E/AndroidRuntime(8818):     at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
06-22 04:45:56.316: E/AndroidRuntime(8818):     at android.content.ContentProviderProxy.query(ContentProviderNative.java:366)
06-22 04:45:56.316: E/AndroidRuntime(8818):     at android.content.ContentResolver.query(ContentResolver.java:372)
06-22 04:45:56.316: E/AndroidRuntime(8818):     at android.content.ContentResolver.query(ContentResolver.java:315)
06-22 04:45:56.316: E/AndroidRuntime(8818):     at sat.tuts4mobile.customlistview.ContactDetails$1.run(ContactDetails.java:42)
06-22 04:45:56.316: E/AndroidRuntime(8818):     at java.lang.Thread.run(Thread.java:856)

【问题讨论】:

  • where 子句中使用的语言严重依赖 SQL。我不认为 ContentProvider 支持的不仅仅是ANDOR
  • 我希望是这样,但是当我尝试时: ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + " AND " + ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE + "'";我最终什么也没得到,所以我知道还有更多
  • 哦,我现在看到你的问题了。你写的查询不正确。我会在答案中发布一个更正的。

标签: android android-sqlite android-contacts


【解决方案1】:

感谢您澄清您遇到的问题。所以是的,

selection = ContactsContract.Data.CONTACT_ID + " = " + contactId + " AND " + 
                ContactsContract.Data.MIMETYPE + " = " + 
                ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'";

选择电话号码。好吧,几乎 - 它在CONTENT_ITEM_TYPE 之前缺少'

为了扩展它,您需要添加一个额外的检查,如下所示:

selection = ContactsContract.Data.CONTACT_ID + " = " + contactId + " AND (" + 
                ContactsContract.Data.MIMETYPE + " = '" + 
                ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "' OR " +
                ContactsContract.Data.MIMETYPE + " = '" + 
                ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE + "')";

这将转化为--

CONTACT_ID = 123 AND ( MIMETYPE = 'Phone' OR MIMETYPE = 'Email' )

虽然使用合同类是正确的 Android 编程,但正如您所做的那样,它确实会导致糟糕的可读性和故障排除。

【讨论】:

  • 是的,对不起。在我学习的时候,我发现将所有东西放在不同的隔间里直到我习惯它更容易。我要去睡觉了,所以我会在早上尝试一下。我是否认为我也需要添加到投影:ContactsContract.CommonDataKinds.Email.ADDRESS ?
  • 没有理由感到抱歉——在所有这些混乱中忽略一个丢失的单引号是很正常的。你在这里没有做错任何事。是的,您需要扩展您的投影以包含您希望看到的列。晚安!
【解决方案2】:

Android 更喜欢在新线程(任务)上运行数据库操作以避免ANR 对话框,在新线程上编写查询,

email 你可以参考这个。 对于所有providers,请通过 android doc。

@Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initialize();
            contactId = getIntent().getStringExtra("contactId");
            contactName = getIntent().getStringExtra("contactName");
            new Thread(new Runnable() {
                @Override
            public void run() {
            queryArgs();
            if (contactId != null) {
            Cursor cursor = getContentResolver().query(uri, projection,
                            selection, selectionArgs, sortOrder);
            while (cursor.moveToNext()) {
                    contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
                        tvContactName.setText(contactName);
                        // Extract the phone number
                        phoneFull += cursor.getString(cursor
                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
                                + " ,";
                    }

                    tvPhoneFull.post(new Runnable() {
                        @Override
                        public void run() {
                        tvPhoneFull.setText(phoneFull); 
                        }
                    });

                    cursor.close();
                }
            }
        }).start();

    }

【讨论】:

    猜你喜欢
    • 2020-06-25
    • 2018-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    相关资源
    最近更新 更多