联系人操作

Android系统中的联系人也是通过ContentProvider来对外提供数据的,我们这里实现获取所有联系人、通过电话号码获取联系人、添加联系人、使用事务添加联系人。

获取所有联系人

1.   Android系统中的联系人也是通过ContentProvider来对外提供数据的

2.   数据库路径为:/data/data/com.android.providers.contacts/database/contacts2.db

3.   我们需要关注的有3张表

     raw_contacts:其中保存了联系人id

     data:和raw_contacts是多对一的关系,保存了联系人的各项数据

     mimetypes:为数据类型

4.   Provider的authorites为com.android.contacts

5.   查询raw_contacts表的路径为:contacts

6.   查询data表的路径为:contacts/#/data

     这个路径为连接查询,要查询“mimetype”字段可以根据“mimetype_id”查询到mimetypes表中的数据

7.   先查询raw_contacts得到每个联系人的id,在使用id从data表中查询对应数据,根据mimetype分类数据

示例:

[html]  view plain copy
  1.          //查询所有联系人  
  2. public void testGetAll() {  
  3.     ContentResolver resolver = getContext().getContentResolver();  
  4.     Uri uri = Uri.parse("content://com.android.contacts/contacts");  
  5.     Cursor idCursor = resolver.query(uri, new String[] { "_id" }, null, null, null);  
  6.     while (idCursor.moveToNext()) {  
  7.         //获取到raw_contacts表中的id  
  8.         int id = idCursor.getInt(0);   
  9.         //根据获取到的ID查询data表中的数据  
  10.         uri = Uri.parse("content://com.android.contacts/contacts/" + id + "/data");  
  11.         Cursor dataCursor = resolver.query(uri, new String[] { "data1", "mimetype" }, null, null, null);  
  12.         StringBuilder sb = new StringBuilder();  
  13.         sb.append("id=" + id);  
  14.         //查询联系人表中的  
  15.         while (dataCursor.moveToNext()) {  
  16.             String data = dataCursor.getString(0);  
  17.             String type = dataCursor.getString(1);  
  18.             if ("vnd.android.cursor.item/name".equals(type))  
  19.                 sb.append(", name=" + data);  
  20.             else if ("vnd.android.cursor.item/phone_v2".equals(type))  
  21.                 sb.append(", phone=" + data);  
  22.             else if ("vnd.android.cursor.item/email_v2".equals(type))  
  23.                 sb.append(", email=" + data);  
  24.         }  
  25.         System.out.println(sb);  
  26.     }  
  27. }  


 

通过电话号码获取联系人

1.   系统内部提供了根据电话号码获取data表数据的功能,路径为:data/phones/filter/*

2.   用电话号码替换“*”部分就可以查到所需数据,获取“display_name”可以获取到联系人显示名

示例:

[html]  view plain copy
  1.         //根据电话号码查询联系人名称  
  2. public void testGetName() {  
  3.     ContentResolver resolver = getContext().getContentResolver();  
  4.     Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/1111");  
  5.     Cursor c = resolver.query(uri, new String[] { "display_name" }, null, null, null);  
  6.     while (c.moveToNext()) {  
  7.         System.out.println(c.getString(0));  
  8.     }  
  9. }  

 

添加联系人

1.   先向raw_contacts表插入id,路径为:raw_contacts

2.   得到id之后再向data表插入数据,路径为:data

示例:

[html]  view plain copy
  1.        //添加联系人  
  2. ublic void testInsert() {  
  3. ContentResolver resolver = getContext().getContentResolver();  
  4. Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");  
  5. ContentValues values = new ContentValues();  
  6. // 向raw_contacts插入一条除了ID之外, 其他全部为NULL的记录, ID是自动生成的  
  7. long id = ContentUris.parseId(resolver.insert(uri, values));   
  8. //添加联系人姓名  
  9. uri = Uri.parse("content://com.android.contacts/data");  
  10. values.put("raw_contact_id", id);  
  11. values.put("data2", "FHM");  
  12. values.put("mimetype", "vnd.android.cursor.item/name");  
  13. resolver.insert(uri, values);  
  14.                 //添加联系人电话  
  15. values.clear(); // 清空上次的数据  
  16. values.put("raw_contact_id", id);  
  17. values.put("data1", "18600000000");  
  18. values.put("data2", "2");  
  19. values.put("mimetype", "vnd.android.cursor.item/phone_v2");  
  20. resolver.insert(uri, values);  
  21. //添加联系人邮箱  
  22. values.clear();  
  23. values.put("raw_contact_id", id);  
  24. values.put("data1", "zxx@itcast.cn");  
  25. values.put("data2", "1");  
  26. values.put("mimetype", "vnd.android.cursor.item/email_v2");  
  27. resolver.insert(uri, values);  


 

使用事务添加联系人

1.   在添加联系人得时候是分多次访问Provider,如果在过程中出现异常,会出现数据不完整的情况,这些操作应该放在一次事务中

2.   使用ContentResolver的applyBatch(String authority,ArrayList<ContentProviderOperation> operations) 方法可以将多个操作在一个事务中执行

3.   文档位置:

      file:///F:/android-sdk-windows/docs/reference/android/provider/ContactsContract.RawContacts.html

示例:

[html]  view plain copy
  1.         //使用事务添加联系人  
  2. public void testInsertBatch() throws Exception {  
  3.     ContentResolver resolver = getContext().getContentResolver();  
  4.   
  5.     ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();  
  6.   
  7.     ContentProviderOperation operation1 = ContentProviderOperation //  
  8.             .newInsert(Uri.parse("content://com.android.contacts/raw_contacts")) //  
  9.             .withValue("_id", null) //  
  10.             .build();  
  11.     operations.add(operation1);  
  12.   
  13.     ContentProviderOperation operation2 = ContentProviderOperation //  
  14.             .newInsert(Uri.parse("content://com.android.contacts/data")) //  
  15.             .withValueBackReference("raw_contact_id", 0) //  
  16.             .withValue("data2", "ZZH") //  
  17.             .withValue("mimetype", "vnd.android.cursor.item/name") //  
  18.             .build();  
  19.     operations.add(operation2);  
  20.       
  21.     ContentProviderOperation operation3 = ContentProviderOperation //  
  22.             .newInsert(Uri.parse("content://com.android.contacts/data")) //  
  23.             .withValueBackReference("raw_contact_id", 0) //  
  24.             .withValue("data1", "18612312312") //  
  25.             .withValue("data2", "2") //  
  26.             .withValue("mimetype", "vnd.android.cursor.item/phone_v2") //  
  27.             .build();  
  28.     operations.add(operation3);  
  29.   
  30.     ContentProviderOperation operation4 = ContentProviderOperation //  
  31.             .newInsert(Uri.parse("content://com.android.contacts/data")) //  
  32.             .withValueBackReference("raw_contact_id", 0) //  
  33.             .withValue("data1", "zq@itcast.cn") //  
  34.             .withValue("data2", "2") //  
  35.             .withValue("mimetype", "vnd.android.cursor.item/email_v2") //  
  36.             .build();  
  37.     operations.add(operation4);  
  38.   
  39.     // 在事务中对多个操作批量执行  
  40.     resolver.applyBatch("com.android.contacts", operations);  
  1. }  



  1.                        ContactsContract.RawContacts


  2. long    _ID                 read-only        Row ID;update rather than to delete and re-insert it.
  3. long    CONTACT_ID          read-only        ContactsContract.Contacts 中的ID
  4. int     AGGREGATION_MODE    read/write       组合模式;值为AGGREGATION_MODE_DEFAULT, AGGREGATION_MODE_DISABLED 或AGGREGATION_MODE_SUSPENDED.
  5. int     DELETED             read/write       删除标记;0 or 1;1has been marked for deletion.
  6. int     TIMES_CONTACTED     read/write       已经联系次数
  7. long    LAST_TIME_CONTACTED read/write       上次联系的时间戳
  8. int     STARRED             read/write       特别友好的联系人;1 if favorite;0 otherwise
  9. int     CUSTOM_RINGTONE     read/write       与该记录相关的手机铃声
  10. int     SEND_TO_VOICEMAIL   read/write       当这个Raw来电时,是否转发的语言信箱;1是或0否
  11. String  ACCOUNT_NAME        read/write-once  账号名
  12. String  ACCOUNT_TYPE        read/write-once  账号密码
  13. int     VERSION             read-only        版本;当列或相关数据修改是,将会自动修改
  14. int     DIRTY               read/write       版本发生改变的标记;同步的 当Raw contact发生改变时,自动设为1(除 URI has the CALLER_IS_SYNCADAPTER外)


  15.                           ContactsContract.Contacts


  16. long    _ID                        read-only        Row ID.建议用LOOKUP_KEY代替
  17. String  LOOKUP_KEY                 read-only        与提示如何找到特定联系的值
  18. long    NAME_RAW_CONTACT_ID        read-only        
  19. long    PNOTO_ID                   read-only        ContactsContract.Data table holding the photo. That row has the mime type CONTENT_ITEM_TYPE. 
  20. String  DISPLAY_NAME_PRIMARY       read-only        联系人显示的名字
  21. int     IN_VISIBLE_GROUP           read-only        这个联系人在UI中是否可见;
  22. int     HAS_PHONE_NUMBER           read-only        该联系人否至少有一个手机号码
  23. int     TIMES_CONTACTED            read-only        与该联系人联系的次数
  24. long    LAST_TIME_CONTACTED        read/write       上次联系的时间戳
  25. String  CUSTOM_RINGTONE            read/write       与联系人相关的铃声
  26. int     STARRED                    read/write       是否是常用联系人
  27. int     SEND_TO_VOICEMAIL          read/write       
  28. int     CONTACT_PRESENCE           read-only        Contact IM presence status
  29. String  CONTACT_STATUS             read-only        Contact's latest status update. Automatically computed as the latest of all constituent raw contacts' status updates.
  30. long    CONTACT_STATUS_TIMESTAMP   read-only        插入或修改的最新时间
  31. String  CONTACT_STATUS_RES_PACKAGE read-only        The package containing resources for this status: label and icon
  32. long    CONTACT_STATUS_LABEL       read-only        The resource ID of the label describing the source of contact status, e.g. "Google Talk". This resource is scoped by the CONTACT_STATUS_RES_PACKAGE
  33. long    CONTACT_STATUS_ICON        read-only        The resource ID of the label describing the source of contact status, e.g. "Google Talk". This resource is scoped by the CONTACT_STATUS_RES_PACKAGE.


  34.                             ContactsContract.Data


  35. long    _ID                         read-only        Row ID
  36. String  MIMETYPE                    read/write-once  StructuredName.CONTENT_ITEM_TYPE ;Phone.CONTENT_ITEM_TYPE;Email.CONTENT_ITEM_TYPE ;Organization.CONTENT_ITEM_TYPE;Im.CONTENT_ITEM_TYPE ;Nickname.CONTENT_ITEM_TYPE ;Note.CONTENT_ITEM_TYPE;StructuredPostal.CONTENT_ITEM_TYPE;GroupMembership.CONTENT_ITEM_TYPE ;Website.CONTENT_ITEM_TYPE;Event.CONTENT_ITEM_TYPE ;Relation.CONTENT_ITEM_TYPE;
  37. long    RAW_CONTACT_ID              read/write       The id of the row in the ContactsContract.RawContacts table that this data belongs to.
  38. int     IS_PRIMARY                  read/write       Whether this is the primary entry of its kind for the raw contact it belongs to. "1" if true, "0" if false. 
  39. int     IS_SUPER_PRIMARY            read/write       Whether this is the primary entry of its kind for the aggregate contact it belongs to. Any data record that is "super primary" must also be "primary". For example, the super-primary entry may be interpreted as the default contact value of its kind (for example, the default phone number to use for the contact).
  40.                             

  41.                              ContactsContract.Groups
  42. long    _ID                         read/write       Row ID
  43. String  TITLE                       read/write       The display title of this group
  44. String  NOTE                        read/write       Notes about the group
  45. int     SUMMARY_COUNT               read-only        The total number of Contacts that have ContactsContract.CommonDataKinds.GroupMembership in this group. Read-only value that is only present when querying CONTENT_SUMMARY_URI.
  46. int     SUMMARY_WITH_PHONES         read-only        The total number of Contacts that have both ContactsContract.CommonDataKinds.GroupMembership in this group, and also have phone numbers. Read-only value that is only present when querying CONTENT_SUMMARY_URI.
  47. int     GROUP_VISIBLE               read-only        群组是否在数据库中可见1 or 0
  48. int     DELETED                     read/write       删除标记 0,default;1 if the row has been marked for deletion
  49. int     SHOULD_SYNC                 read/write       Whether this group should be synced if the SYNC_EVERYTHING settings is false for this group's account.




       主要要添加权限:

java代码:
  1. <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
  2. <uses-permission android:name="android.permission.WRITE_CONTACTS"></uses-permission>
复制代码

       删除联系人 

java代码:
  1. private void delContact(Context context, String name) {

  2. Cursor cursor = getContentResolver().query(Data.CONTENT_URI,new String[] { Data.RAW_CONTACT_ID },

  3. ContactsContract.Contacts.DISPLAY_NAME + "=?",new String[] { name }, null);

  4. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

  5. if (cursor.moveToFirst()) {
  6. do {
  7. long Id = cursor.getLong(cursor.getColumnIndex(Data.RAW_CONTACT_ID));

  8. ops.add(ContentProviderOperation.newDelete(
  9. ContentUris.withAppendedId(RawContacts.CONTENT_URI,Id)).build());
  10. try {
  11. getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

  12. catch (Exception e){}
  13. } while (cursor.moveToNext());
  14. cursor.close();
  15. }
  16. }

复制代码

       更新联系人信息

java代码:
  1. private void updateContact(Context context,String oldname, String name, String phone, String email,String website, String organization, String note) {

  2. Cursor cursor = getContentResolver().query(Data.CONTENT_URI,new String[] { Data.RAW_CONTACT_ID },

  3. ContactsContract.Contacts.DISPLAY_NAME + "=?",new String[] { oldname }, null);
  4. cursor.moveToFirst();
  5. String id = cursor.getString(cursor.getColumnIndex(Data.RAW_CONTACT_ID));
  6. cursor.close();
  7. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

复制代码

       更新电话号码

java代码:
  1. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  2. .withSelection(

  3. Data.RAW_CONTACT_ID + "=?" + " AND "+ ContactsContract.Data.MIMETYPE + " = ?" +
  4. " AND " + Phone.TYPE + "=?",new String[] { String.valueOf(id),Phone.CONTENT_ITEM_TYPE,
  5. String.valueOf(Phone.TYPE_HOME) }).withValue(Phone.NUMBER, phone).build());

  6. // 更新email
  7. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  8. .withSelection(Data.RAW_CONTACT_ID + "=?" + " AND "+ ContactsContract.Data.MIMETYPE + " = ?" +" AND " + Email.TYPE + "=?",new String[] { String.valueOf(id),Email.CONTENT_ITEM_TYPE,
  9. String.valueOf(Email.TYPE_HOME) }).withValue(Email.DATA, email).build());

  10. // 更新姓名
  11. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  12. .withSelection(Data.RAW_CONTACT_ID + "=?" + " AND "+ ContactsContract.Data.MIMETYPE + " = ?",new String[] { String.valueOf(id),StructuredName.CONTENT_ITEM_TYPE }).withValue(StructuredName.DISPLAY_NAME, name).build());

  13. // 更新网站
  14. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  15. .withSelection(Data.RAW_CONTACT_ID + "=?" + " AND "+ ContactsContract.Data.MIMETYPE + " = ?",new String[] { String.valueOf(id),Website.CONTENT_ITEM_TYPE }).withValue(Website.URL, website).build());

  16. // 更新公司
  17. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  18. .withSelection(Data.RAW_CONTACT_ID + "=?" + " AND "+ ContactsContract.Data.MIMETYPE + " = ?",new String[] { String.valueOf(id),Organization.CONTENT_ITEM_TYPE })
  19. .withValue(Organization.COMPANY, organization).build());

  20. // 更新note
  21. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  22. .withSelection(Data.RAW_CONTACT_ID + "=?" + " AND "+ ContactsContract.Data.MIMETYPE + " = ?",new String[] { String.valueOf(id),Note.CONTENT_ITEM_TYPE }).withValue(Note.NOTE, note).build());

  23. try{
  24. getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
  25. } catch (Exception e) {
  26. }
  27. }

复制代码

       添加联系人

java代码:

  1. private void addContact(Context context, String name,
  2. String organisation,String phone, String fax, String email, String address,String website){

  3. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

  4. //在名片表插入一个新名片
  5. ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
  6. .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null).withValue(ContactsContract.RawContacts._ID, 0).withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null).withValue(
  7. ContactsContract.RawContacts.AGGREGATION_MODE,ContactsContract.RawContacts.AGGREGATION_MODE_DISABLED).build());

  8. // add name
  9. //添加一条新名字记录;对应RAW_CONTACT_ID为0的名片
  10. if (!name.equals("")) {
  11. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
  12. .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(
  13. ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE).withValue(
  14. ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,name).build());
  15. }

  16. //添加昵称
  17. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
  18. .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(
  19. ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE).withValue(ContactsContract.CommonDataKinds.Nickname.NAME,"Anson昵称").build());

  20. // add company
  21. if (!organisation.equals("")) {
  22. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(ContactsContract.Data.MIMETYPE,
  23. ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE).withValue(
  24. ContactsContract.CommonDataKinds.Organization.COMPANY,organisation).withValue(
  25. ContactsContract.CommonDataKinds.Organization.TYPE,ContactsContract.CommonDataKinds.Organization.TYPE_WORK).build());
  26. }

  27. // add phone
  28. if (!phone.equals("")) {
  29. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
  30. .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
  31. .withValue(ContactsContract.Data.MIMETYPE,
  32. ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE).withValue(ContactsContract.CommonDataKinds.Phone.NUMBER,phone).withValue(ContactsContract.CommonDataKinds.Phone.TYPE,1).build());
  33. }

  34. // add Fax
  35. if (!fax.equals("")) {
  36. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).withValueBackReference(
  37. ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(
  38. ContactsContract.Data.MIMETYPE,
  39. ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE).withValue(
  40. ContactsContract.CommonDataKinds.Phone.NUMBER,fax)
  41. .withValue(ContactsContract.CommonDataKinds.Phone.TYPE,
  42. ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK).build());
  43. }



  44. // add email
  45. if (!email.equals("")) {
  46. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
  47. .withValueBackReference(
  48. ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(
  49. ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE).withValue(ContactsContract.CommonDataKinds.Email.DATA,email).withValue(ContactsContract.CommonDataKinds.Email.TYPE,1).build());
  50. }

  51. // add address
  52. if (!address.equals("")) {
  53. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(
  54. ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE).withValue(
  55. ContactsContract.CommonDataKinds.StructuredPostal.STREET,address)
  56. .withValue(ContactsContract.CommonDataKinds.StructuredPostal.TYPE,
  57. ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK).build());
  58. }

  59. // add website
  60. if (!website.equals("")) {
  61. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
  62. .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
  63. .withValue(ContactsContract.Data.MIMETYPE,
  64. ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE).withValue(
  65. ContactsContract.CommonDataKinds.Website.URL,website)
  66. .withValue(
  67. ContactsContract.CommonDataKinds.Website.TYPE,
  68. ContactsContract.CommonDataKinds.Website.TYPE_WORK).build());
  69. }

  70. // add IM
  71. String qq1="452824089";
  72. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).withValueBackReference(
  73. ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(
  74. ContactsContract.Data.MIMETYPE,
  75. ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE).withValue(
  76. ContactsContract.CommonDataKinds.Im.DATA1,qq1)
  77. .withValue(
  78. ContactsContract.CommonDataKinds.Im.PROTOCOL,
  79. ContactsContract.CommonDataKinds.Im.PROTOCOL_QQ).build());

  80. // add logo image
  81. // Bitmap bm = logo;
  82. // if (bm != null) {
  83. // ByteArrayOutputStream baos = new ByteArrayOutputStream();
  84. // bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
  85. // byte[] photo = baos.toByteArray();
  86. // if (photo != null) {
  87. //
  88. // ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
  89. // .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
  90. // .withValue(ContactsContract.Data.MIMETYPE,
  91. // ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
  92. // .withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photo)
  93. // .build());
  94. // }
  95. // }

  96. try {
  97. context.getContentResolver().applyBatch(
  98. ContactsContract.AUTHORITY, ops);
  99. } catch (Exception e){
  100. }

  101. }
复制代码



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值