[android研究联系人之一]联系人IM/website数据操作



最近要忙于工作了,工作中的事情有点多,也没时间做UI了。不过,等过一点时间充裕。会继续推出新的学UI博客。感谢大家的关注!!!


这篇博客,主要是要介绍android联系人数据操作,讲解一些工作中遇到的一些新情况。分享给大家!


从Android2.2以后,android又经过几个版本的更新,联系人这块的操作已经发生了很大的变化。这次先讲解今天遇到两个数据操作问题:


一、联系人中IM数据怎样更新?

       先看IM有哪些数据,看图:



总共类型,大概有10种,包括用户可以自定义类型。


先介绍主要的Im类中的主要的字段:

ContactsContract.Data.MIMETYPE-->ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE("vnd.android.cursor.item/im")

ContactsContract.Data.DATA5-->ContactsContract.CommonDataKinds.Im.PROTOCOL

ContactsContract.Data.DATA6-->ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL

ContactsContract.Data.DATA1-->ContactsContract.CommonDataKinds.Im.DATA (从CommonColumns继承而来)

ContactsContract.Data.DATA2-->ContactsContract.CommonDataKinds.Im.TYPE (从CommonColumns继承而来)

统一的查询Uri: ContactsContract.Data.CONTENT_URI

所有的数据存放,基本上都在ContactsContract .Data类中,如想取数据:

private static final String[] PROJECTION = new String[] {

                Data.CONTACT_ID,

                Data.DATA1, Data.DATA2,

                Data.DATA3, Data.DATA4,

                Data.DATA5, Data.DATA6,

                Data.DATA7, Data.DATA8,

                Data.DATA9, Data.DATA10,

                Data.MIMETYPE

        };


查询的条件必须加上类型,如:ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE


如果是查询IM数据,则需要关心,以下几个字段:

       Data.RAW_CONTACT_ID表示联系人的ID

     Data.MIMETYPE:表示mime类型,查im则类型为:Im.CONTENT_ITEM_TYPE

       Data.DATA1:表示用户填写的数据,如:是QQ类型,则此为QQ号:123456789

       Data.DATA2:表示数据类型,个人感觉是源码中对应的此类型:(目前手机中读取出来的值都为3)

                                    public static final int TYPE_HOME = 1;

                                    public static final int TYPE_WORK = 2;

                                    public static final int TYPE_OTHER = 3;

           也看图,有图有真相:

          添加数据图:

             

          两条基本数据,一条自定义数据。

        看看数据库中的结果图:


data2就是type,是不是都是3啊(用手机测试,也是这个值)。

Data.DATA5:在源码中是Im.PROTOCOL:它才表示的是真正的类型,如源码中对应的类型:

                                  public static final int PROTOCOL_CUSTOM = -1;

                                  public static final int PROTOCOL_AIM = 0;

                                  public static final int PROTOCOL_MSN = 1;

                                  public static final int PROTOCOL_YAHOO = 2;

                                  public static final int PROTOCOL_SKYPE = 3;

                                  public static final int PROTOCOL_QQ = 4;

                                  public static final int PROTOCOL_GOOGLE_TALK = 5;

                                 public static final int PROTOCOL_ICQ = 6;

                                 public static final int PROTOCOL_JABBER = 7;

                                  public static final int PROTOCOL_NETMEETING = 8;

而当PROTOCOL的取值为-1时,则要取出Data.DATA6的值。

Data.DATA6 :在源码中是Im.CUSTOM_PROTOCOL字段,它表示是用户自定义的值,

                                              也就是只有data5为-1时,这个取取出来才不是null(上图能很好的证明了)


基本上只要了解这几个字段,就能正确的完成Im数据的操作。


二、怎样更新Website数据?

下面,再介绍一个很是纠结的数据:Website

website在手机中,是可以插入多条数据,但在操作的数据库,是不能区分多条数据(不知道为啥)。

做项目,当然不能凭感觉说话,要找到证据才能说明问题,这时候,当然去看数据库,有图有真相:


这是我编辑的两条数据,也没有类型选择。所以,用类型区分是不可能的。此点已证明。

接下来看数据库中保存的内容,看看最终保存的结果,就知道结果:


从上面的数据,可以看出来保存的数据,也没有字段区分这两条数据。所以,再一次证明,推论正确。

这是website的问题,但下面看一下Website需要操作的字段:

   Data.MIMETYPE:表示mime类型,查Website类型为:Website.CONTENT_ITEM_TYPE

   Website.TYPE:表示类型,对应的类型如下:(但手机中都对应的是7,感觉基本无用)

                            public static final int TYPE_HOMEPAGE = 1;
                            public static final int TYPE_BLOG = 2;
                            public static final int TYPE_PROFILE = 3;
                            public static final int TYPE_HOME = 4;
                            public static final int TYPE_WORK = 5;
                            public static final int TYPE_FTP = 6;
                            public static final int TYPE_OTHER = 7;
    Website.URL:对应Data.data1数据:表示用户输入的数据,如:www.csdn.com
   Website.LABEL:暂时无用了。

  website操作结论:要想实现更新,就只能先删除,再重新插入。


这两个类型数据,比较简单,只要知道操作哪些数据了,基本就没什么问题了。

操作的代码不在电脑上,所以,就不上传了。如果大家对此有任何疑问,欢迎一起讨论!!!


后续,还会再研究联系人中的其它字段。欢迎大家关注了,如发现有错误的地方,欢迎指正!!!



修正:

Website数据,它的源码:

  

  /** MIME type used when storing this in data table. */
            public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/website";

            public static final int TYPE_HOMEPAGE = 1;
            public static final int TYPE_BLOG = 2;
            public static final int TYPE_PROFILE = 3;
            public static final int TYPE_HOME = 4;
            public static final int TYPE_WORK = 5;
            public static final int TYPE_FTP = 6;
            public static final int TYPE_OTHER = 7;

            /**
             * The website URL string.
             * <P>Type: TEXT</P>
             */
            public static final String URL = DATA;

这个类中的主要数据只有这些,其实看到它定义了类型,就知道,它应该也可以添加为多条。

在以前的分析中,由于只是在模拟器中分析,发现它不能添加多条,所以,就有一个错误的地方。

现在在moto里程碑二中,是有多条数据的。所以,它的type和label也是有用的。

在此说明一下。


补充:Im说明

文章前面讲述了从源码中的一些字段说明,这里要再提一下的是,对于相同类型的数据,在data表中只能通过_id

来标识,除此之外,想要通过其它字段做更新,是不可行的。

如下图,添加的两条数据:


被红线圈的数据,就是类型一样的数据。除了 id是无法区分的。

后面要纠正上文对Im解释中的一些问题:

    public static final class Im implements DataColumnsWithJoins, CommonColumns {
            /**
             * This utility class cannot be instantiated
             */
            private Im() {}

            /** MIME type used when storing this in data table. */
            public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/im";

            public static final int TYPE_HOME = 1;
            public static final int TYPE_WORK = 2;
            public static final int TYPE_OTHER = 3;

            /**
             * This column should be populated with one of the defined
             * constants, e.g. {@link #PROTOCOL_YAHOO}. If the value of this
             * column is {@link #PROTOCOL_CUSTOM}, the {@link #CUSTOM_PROTOCOL}
             * should contain the name of the custom protocol.
             */
            public static final String PROTOCOL = DATA5;

            public static final String CUSTOM_PROTOCOL = DATA6;

            /*
             * The predefined IM protocol types.
             */
            public static final int PROTOCOL_CUSTOM = -1;
            public static final int PROTOCOL_AIM = 0;
            public static final int PROTOCOL_MSN = 1;
            public static final int PROTOCOL_YAHOO = 2;
            public static final int PROTOCOL_SKYPE = 3;
            public static final int PROTOCOL_QQ = 4;
            public static final int PROTOCOL_GOOGLE_TALK = 5;
            public static final int PROTOCOL_ICQ = 6;
            public static final int PROTOCOL_JABBER = 7;
            public static final int PROTOCOL_NETMEETING = 8;

            /**
             * Return the string resource that best describes the given
             * {@link #TYPE}. Will always return a valid resource.
             */
            public static final int getTypeLabelResource(int type) {
                switch (type) {
                    case TYPE_HOME: return com.android.internal.R.string.imTypeHome;
                    case TYPE_WORK: return com.android.internal.R.string.imTypeWork;
                    case TYPE_OTHER: return com.android.internal.R.string.imTypeOther;
                    default: return com.android.internal.R.string.imTypeCustom;
                }
            }

            /**
             * Return a {@link CharSequence} that best describes the given type,
             * possibly substituting the given {@link #LABEL} value
             * for {@link #TYPE_CUSTOM}.
             */
            public static final CharSequence getTypeLabel(Resources res, int type,
                    CharSequence label) {
                if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) {
                    return label;
                } else {
                    final int labelRes = getTypeLabelResource(type);
                    return res.getText(labelRes);
                }
            }

            /**
             * Return the string resource that best describes the given
             * {@link #PROTOCOL}. Will always return a valid resource.
             */
            public static final int getProtocolLabelResource(int type) {
                switch (type) {
                    case PROTOCOL_AIM: return com.android.internal.R.string.imProtocolAim;
                    case PROTOCOL_MSN: return com.android.internal.R.string.imProtocolMsn;
                    case PROTOCOL_YAHOO: return com.android.internal.R.string.imProtocolYahoo;
                    case PROTOCOL_SKYPE: return com.android.internal.R.string.imProtocolSkype;
                    case PROTOCOL_QQ: return com.android.internal.R.string.imProtocolQq;
                    case PROTOCOL_GOOGLE_TALK: return com.android.internal.R.string.imProtocolGoogleTalk;
                    case PROTOCOL_ICQ: return com.android.internal.R.string.imProtocolIcq;
                    case PROTOCOL_JABBER: return com.android.internal.R.string.imProtocolJabber;
                    case PROTOCOL_NETMEETING: return com.android.internal.R.string.imProtocolNetMeeting;
                    default: return com.android.internal.R.string.imProtocolCustom;
                }
            }

            /**
             * Return a {@link CharSequence} that best describes the given
             * protocol, possibly substituting the given
             * {@link #CUSTOM_PROTOCOL} value for {@link #PROTOCOL_CUSTOM}.
             */
            public static final CharSequence getProtocolLabel(Resources res, int type,
                    CharSequence label) {
                if (type == PROTOCOL_CUSTOM && !TextUtils.isEmpty(label)) {
                    return label;
                } else {
                    final int labelRes = getProtocolLabelResource(type);
                    return res.getText(labelRes);
                }
            }
        }

这是Im字段的源码。其实它有Type字段,在数据表中是Data.data2表示。

当Type为Custom(为0)的时候,这时就是自定义的数据类型。这个时候

自定义的名称为Label,存在Data.data3字段中。

而这里需要说明的一点是,Im是有一个PROTOCOL字段,用Data.data5存储。

它表示是哪种协议的Im,如QQ、skype等。

如果是自定义类型的,则在CUSTOM_PROTOCOL,也就是Data.data6字段中,存有一份和data3一样的数据。

所以,对im操作,首先要注意:data2的数据类型。若为自定义的,就要取label值。

                             接着要注意:data5的值,它能判断出来是哪种Im.

这些说明,希望能帮助大家更好的理解数据库表,如有问题,欢迎交流!!!














评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值