代码分为两部分:

Part One 将预置的联系人插入到数据库中;

Part Two 保证预置联系人仅仅读,无法被编辑删除(在三个地方屏蔽对预置联系人进行编辑处理:联系人详情界面、联系人多选界面、新建联系人选择合并联系人时)。

【注意】假设您不须要限制预置联系人的删除/编辑操作,增加Part One部分代码就可以,并去掉第三步”新增函数“  中的语句:contactvalues.put(RawContacts.IS_SDN_CONTACT, -1);

 

Part One:

File:AbstractStartSIMService.java

Path: alps\packages\apps\Contacts\src\com\mediatek\contacts\simcontact

 

1.引入包

import android.provider.ContactsContract.PhoneLookup;

 

2.添加变量

private static boolean sIsRunningNumberCheck = false;

private static final int INSERT_PRESET_NUMBER_COUNT = xxx;           //预置联系人的个数

private static final String  INSERT_PRESET_NAME[]    = {"xxx1","xxx2",...};  //各预置联系人的姓名 

private static final String  INSERT_PRESET_NUMBER[] = {"xxx1","xxx2",...};  //各预置联系人的号码

 

3.添加函数(将预置联系人信息写入数据库中):

  private void importDefaultReadonlyContact() {

      new Thread(new Runnable() {

 

          @Override

          public void run() {

              Log.i(TAG, "isRunningNumberCheck before: " + sIsRunningNumberCheck);

              if (sIsRunningNumberCheck) {

                   return;

              }

              sIsRunningNumberCheck = true;

              for(int i = 0;i < INSERT_PRESET_NUMBER_COUNT; i++)

              {

                Log.i(TAG, "isRunningNumberCheck after: " + sIsRunningNumberCheck);

                Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri

                        .encode(INSERT_PRESET_NUMBER[i]));

                Log.i(TAG, "getContactInfoByPhoneNumbers(), uri = " + uri);

 

                Cursor contactCursor = getContentResolver().query(uri, new String[] {

                        PhoneLookup.DISPLAY_NAME, PhoneLookup.PHOTO_ID

                }, null, null, null);

                try {

                    if (contactCursor != null && contactCursor.getCount() > 0) {

                        return;

                    } else {

                        final ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();

                        ContentProviderOperation.Builder builder = ContentProviderOperation

                                .newInsert(RawContacts.CONTENT_URI);

                        ContentValues contactvalues = new ContentValues();

                        contactvalues.put(RawContacts.ACCOUNT_NAME,

                                AccountType.ACCOUNT_NAME_LOCAL_PHONE);

                        contactvalues.put(RawContacts.ACCOUNT_TYPE,

                                AccountType.ACCOUNT_TYPE_LOCAL_PHONE);

                        contactvalues.put(RawContacts.INDICATE_PHONE_SIM,

                                ContactsContract.RawContacts.INDICATE_PHONE);

                        contactvalues.put(RawContacts.IS_SDN_CONTACT, -1);

                        builder.withValues(contactvalues);

                        builder.withValue(RawContacts.AGGREGATION_MODE,

                                RawContacts.AGGREGATION_MODE_DISABLED);

                        operationList.add(builder.build());

 

                        builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);

                        builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0);

                        builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);

                        builder.withValue(Phone.TYPE, Phone.TYPE_MOBILE);

                        builder.withValue(Phone.NUMBER, INSERT_PRESET_NUMBER[i]);

                        builder.withValue(Data.IS_PRIMARY, 1);

                        operationList.add(builder.build());

 

                        builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);

                        builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, 0);

                        builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);

                        builder.withValue(StructuredName.DISPLAY_NAME, INSERT_PRESET_NAME[i]);

                        operationList.add(builder.build());

 

                        try {

                            getContentResolver().applyBatch(

                                    ContactsContract.AUTHORITY, operationList);

                        } catch (RemoteException e) {

                            Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));

                        } catch (OperationApplicationException e) {

                            Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));

                        }

 

                    }

                } finally {

                    // when this service start,but the contactsprovider has not been started yet.

                    // the contactCursor perhaps null, but not always.(first load will weekup the provider)

                    // so add null block to avoid nullpointerexception

                    if (contactCursor != null) {

                        contactCursor.close();

                    }

                }

              }//for

              Log.i(TAG, "isRunningNumberCheck insert: " + sIsRunningNumberCheck);

              sIsRunningNumberCheck = false;

          }

      }).start();

 

  }

   

4.onStart中调用这个函数:

 

    public void onStart(Intent intent, int startId) {

        .....           

        //add by MTK---Preset Contacts

        importDefaultReadonlyContact();

           

        log("[onStart]" + intent + ", startId " + startId);

        if (intent == null) {

            return;

        }

        .....

}

 

Part Two

1.File:DefaultContactListAdapter.java  Path:alps\packages\apps\contacts\src\com\android\contacts\list

(1)configureSelection函数中有五处 RawContacts.IS_SDN_CONTACT + " = 0",都改为:RawContacts.IS_SDN_CONTACT + " < 1"

 

(2)configureOnlyShowPhoneContactsSelection函数中例如以下语句:

selection.append(Contacts.INDICATE_PHONE_SIM + "= ?");

        selectionArgs.add("-1");

之后添加以下的代码

selection.append(" AND " + RawContacts.IS_SDN_CONTACT + " > -1");

 

 

2.File:ProfileAndContactsLoader.java  Path:alps\packages\apps\contacts\src\com\android\contacts\list 

loadSDN函数中有两处 RawContacts.IS_SDN_CONTACT + " = 0",都改为:RawContacts.IS_SDN_CONTACT + " < 1"

 

3. File:Contact.java  Path:alps\packages\apps\contacts\src\com\android\contacts\model 

添加例如以下函数:

    //add by MTK---Preset Contacts

    public boolean isReadOnlyContact() {

             return mIsSdnContact == -1;

     }

 

4. File:ContactLoaderFragment.java Path:alps\packages\apps\contacts\src\com\android\contacts\detail 

将isContactEditable函数改动为:

   public boolean isContactEditable() {

        return mContactData != null && !mContactData.isDirectoryEntry()

                && !mContactData.isSdnContacts() &&  !mContactData.isReadOnlyContact() ;

    }

 

5. File:ContactEntryListAdapter.java Path:alps\packages\apps\contacts\src\com\android\contacts\list  

在文件最后添加下面代码:

    public boolean showReadOnlyContact = true;

    public void setShowReadOnlyContact(boolean canDelete) {

        showReadOnlyContact = canDelete;

    }

 

6. File:ContactEntryListFragment.java  Path:alps\packages\apps\contacts\src\com\android\contacts\list

引入例如以下包:

import com.mediatek.contacts.list.ContactsMultiDeletionFragment;

 

在onCreateLoader函数中。倒数第二句mAdapter.configureLoader(loader, directoryId);之前添加语句:   

            mAdapter.setShowReadOnlyContact((this instanceof ContactsMultiDeletionFragment) ?

false : true);

 

8 7.File:MultiContactsBasePickerAdapter.java Path:alps\packages\apps\contacts\src\com\mediatek\contacts\list  在configureSelection函数最后的语句 loader.setSelection(selection.toString());之前添加语句:

        if (!showReadOnlyContact ) {

            selection.append(" AND " + Contacts.IS_SDN_CONTACT + "=0");

        }

      

 

8.File:AggregationSuggestionEngine.java Path:alps\packages\apps\contacts\src\com\android\contacts\editor

在configureSelection函数最后的语句 

在语句:   sb.append(" AND " + Contacts.INDICATE_PHONE_SIM + "=-1");

之后加入: sb.append(" AND " + Contacts.IS_SDN_CONTACT + "!=-1");

9.File:JoinContactListAdapter.java

Path:packages\apps\contacts\src\com\android\contacts\list   

函数:public void configureLoader(CursorLoader cursorLoader, long directoryId) 

将: loader.setSelection(Contacts._ID + "!=?"+" AND " + Contacts.INDICATE_PHONE_SIM + "=-1");‘

改动为:

    loader.setSelection(Contacts._ID + "!=?"+" AND " + Contacts.INDICATE_PHONE_SIM + "=-1" + " AND " + Contacts.IS_SDN_CONTACT + "!=-1");

 

【After JB5】

实现预置联系人(包括姓名、号码信息)至手机中;并保证该联系人是仅仅读的。无法被删除/编辑。

代码分为两部分:

Part One 将预置的联系人插入到数据库中;

Part Two 保证预置联系人仅仅读,无法被编辑删除(在三个地方屏蔽对预置联系人进行编辑处理:联系人详情界面、联系人多选界面、新建联系人选择合并联系人时)。

【注意】假设您不须要限制预置联系人的删除/编辑操作,增加Part One部分代码就可以。并去掉第一步”新增函数“  中的语句:contactvalues.put(RawContacts.IS_SDN_CONTACT, -2);

 

Part One:

1.新建PresetContactsImportProcessor.java

Path: alps\packages\apps\Contacts\src\com\mediatek\contacts\simservice

package com.mediatek.contacts.simservice;

 

import com.mediatek.contacts.simservice.SIMProcessorManager.ProcessorCompleteListener;

 

import android.content.Context;

import android.content.Intent;

import android.util.Log;

import android.content.ContentProviderOperation;

import android.content.ContentValues;

import android.content.OperationApplicationException;

import android.database.Cursor;

import android.net.Uri;

 

import android.provider.ContactsContract;

import android.provider.ContactsContract.CommonDataKinds.Email;//for usim

import android.provider.ContactsContract.CommonDataKinds.GroupMembership;

import android.provider.ContactsContract.CommonDataKinds.Phone;

import android.provider.ContactsContract.CommonDataKinds.StructuredName;

import android.provider.ContactsContract.Data;

import android.provider.ContactsContract.Groups;

import android.provider.ContactsContract.RawContacts;

 

 

import com.android.contacts.common.model.account.AccountType;

import android.os.RemoteException;

 

import java.util.ArrayList;

import com.mediatek.contacts.simservice.SIMProcessorManager.ProcessorCompleteListener;

import com.mediatek.contacts.simservice.SIMServiceUtils;

import com.mediatek.contacts.simservice.SIMServiceUtils.ServiceWorkData;

import com.mediatek.contacts.simcontact.SimCardUtils;

import com.mediatek.contacts.util.LogUtils;

import android.provider.ContactsContract.PhoneLookup;

 

public class PresetContactsImportProcessor extends SIMProcessorBase {

    private static final String TAG = "PresetContactsImportProcessor";

   

    private static boolean sIsRunningNumberCheck = false;

    private static final int INSERT_PRESET_NUMBER_COUNT = xxx;           //预置联系人的个数

    private static final String  INSERT_PRESET_NAME[]    = {"xxx1","xxx2",...};  //各预置联系人的姓名

    private static final String  INSERT_PRESET_NUMBER[] = {"xxx1","xxx2",...};  //各预置联系人的号码

   

    private int mSlotId;

    private Context mContext;

 

    public PresetContactsImportProcessor(Context context, int slotId, Intent intent,

            ProcessorCompleteListener listener) {

        super(intent, listener);

        mContext = context;

        mSlotId = slotId;

    }

 

    @Override

    public int getType() {

        return SIMServiceUtils.SERVICE_WORK_IMPORT_PRESET_CONTACTS;

    }

 

    @Override

    public void doWork() {

        if (isCancelled()) {

            LogUtils.d(TAG, "[doWork]cancel import preset contacts work. Thread id=" + Thread.currentThread().getId());

            return;

        }

        importDefaultReadonlyContact();

    }

   

    private void importDefaultReadonlyContact(){

         Log.i(TAG, "isRunningNumberCheck before: " + sIsRunningNumberCheck);

         if (sIsRunningNumberCheck) {

            return;

         }

         sIsRunningNumberCheck = true;

         for(int i = 0;i < INSERT_PRESET_NUMBER_COUNT; i++)

         {

             Log.i(TAG, "isRunningNumberCheck after: " + sIsRunningNumberCheck);

             Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri

                      .encode(INSERT_PRESET_NUMBER[i]));

             Log.i(TAG, "getContactInfoByPhoneNumbers(), uri = " + uri);

 

             Cursor contactCursor = mContext.getContentResolver().query(uri, new String[] {

                      PhoneLookup.DISPLAY_NAME, PhoneLookup.PHOTO_ID

         }, null, null, null);

         try {

             if (contactCursor != null && contactCursor.getCount() > 0) {

                  return;

             } else {

                  final ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();

                  ContentProviderOperation.Builder builder = ContentProviderOperation

                          .newInsert(RawContacts.CONTENT_URI);

                  ContentValues contactvalues = new ContentValues();

                  contactvalues.put(RawContacts.ACCOUNT_NAME,

                          AccountType.ACCOUNT_NAME_LOCAL_PHONE);

                  contactvalues.put(RawContacts.ACCOUNT_TYPE,

                          AccountType.ACCOUNT_TYPE_LOCAL_PHONE);

                  contactvalues.put(RawContacts.INDICATE_PHONE_SIM,

                          ContactsContract.RawContacts.INDICATE_PHONE);

                  contactvalues.put(RawContacts.IS_SDN_CONTACT, -2);

                  builder.withValues(contactvalues);

                  builder.withValue(RawContacts.AGGREGATION_MODE,

                          RawContacts.AGGREGATION_MODE_DISABLED);

                  operationList.add(builder.build());

 

                  builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);

                  builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0);

                  builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);

                  builder.withValue(Phone.TYPE, Phone.TYPE_MOBILE);

                  builder.withValue(Phone.NUMBER, INSERT_PRESET_NUMBER[i]);

                  builder.withValue(Data.IS_PRIMARY, 1);

                  operationList.add(builder.build());

 

                  builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);

                  builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, 0);

                  builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);

                  builder.withValue(StructuredName.DISPLAY_NAME, INSERT_PRESET_NAME[i]);

                  operationList.add(builder.build());

 

                  try {

                      mContext.getContentResolver().applyBatch(

                               ContactsContract.AUTHORITY, operationList);

                  } catch (RemoteException e) {

                      Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));

                  } catch (OperationApplicationException e) {

                      Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));

                  }

 

             }

         } finally {

             // when this service start,but the contactsprovider has not been started yet.

             // the contactCursor perhaps null, but not always.(first load will weekup the provider)

             // so add null block to avoid nullpointerexception

             if (contactCursor != null) {

                  contactCursor.close();

             }

         }//for

         Log.i(TAG, "isRunningNumberCheck insert: " + sIsRunningNumberCheck);

         sIsRunningNumberCheck = false;

         }

    }

}

 

2. 改动SIMServiceUtils.java

Path:alps\packages\apps\ContactsCommon\src\com\mediatek\contacts\simservice  

加入

public static final int SERVICE_WORK_IMPORT_PRESET_CONTACTS = 5;

3. 改动SIMProcessorManager.java

Path:alps\packages\apps\Contacts\src\com\mediatek\contacts\simservice

在SIMProcessorManager.java中createProcessor函数里加入

else if (workType == SIMServiceUtils.SERVICE_WORK_IMPORT_PRESET_CONTACTS) {

            processor = new PresetContactsImportProcessor(context, slotId, intent, listener);

        }

4. 改动BootCmpReceiver.java

Path:alps\packages\apps\Contacts\src\com\mediatek\contacts\simcontact

在BootCmpReceiver.java中processBootComplete()方法最后加入代码

startSimService(-1, SIMServiceUtils.SERVICE_WORK_IMPORT_PRESET_CONTACTS);

Part Two

1.  File:DefaultContactListAdapter.java 

Path: alps\packages\apps\ContactsCommon\src\com\android\contacts\common\list

(1)configureOnlyShowPhoneContactsSelection函数中例如以下语句:

selection.append(Contacts.INDICATE_PHONE_SIM + "= ?

");

        selectionArgs.add("-1");

之后添加以下的代码

selection.append(" AND " + RawContacts.IS_SDN_CONTACT + " > -2");

2.  File:Contact.java 

Path: alps\packages\apps\ContactsCommon\src\com\android\contacts\common\model 

添加例如以下函数:

    //add by MTK---Preset Contacts

    public boolean isReadOnlyContact() {

             return mIsSdnContact == -2;

     }

3.  File:ContactLoaderFragment.java

Path:alps\packages\apps\contacts\src\com\android\contacts\detail 

将isContactEditable函数改动为:

   public boolean isContactEditable() {

        return mContactData != null && !mContactData.isDirectoryEntry()&& !mContactData.isSdnContacts()&&  !mContactData.is InternationalDialNumber()&&  !mContactData.isReadOnlyContact() ;

    }

 

4.  File:ContactEntryListAdapter.java 

Path:alps\packages\apps\contactscommon\src\com\android\contacts\common\list  

在文件最后添加下面代码:

    public boolean showReadOnlyContact = true;

    public void setShowReadOnlyContact(boolean canDelete) {

        showReadOnlyContact = canDelete;

    }

 

5.  File:ContactEntryListFragment.java  

Path:alps\packages\apps\contactscommon\src\com\android\contacts\common\list

加入代码:

    protected boolean isInstanceOfContactsMultiDeletionFragment(){

    return false;

    }

在onCreateLoader函数中,倒数第二句mAdapter.configureLoader(loader, directoryId);之前添加语句:   

            mAdapter.setShowReadOnlyContact(isInstanceOfContactsMultiDeletionFragment() ? false : true);

6.  File: ContactsMultiDeletionFragment.java

Path:alps\packages\apps\Contacts\src\com\mediatek\contacts\list

加入代码:

    protected boolean isInstanceOfContactsMultiDeletionFragment(){

    return true;

    }

7.File:MultiContactsBasePickerAdapter.java

Path:alps\packages\apps\contacts\src\com\mediatek\contacts\list 

在configureSelection函数最后的语句 loader.setSelection(selection.toString());之前添加语句:

        if (!showReadOnlyContact ) {

            selection.append(" AND " + Contacts.IS_SDN_CONTACT + "=0");

}

8.File:AggregationSuggestionEngine.java

Path:alps\packages\apps\contacts\src\com\android\contacts\editor

在loadAggregationSuggestions函数最后的语句 

在语句:   sb.append(" AND " + Contacts.INDICATE_PHONE_SIM + "=-1");

之后加入: sb.append(" AND " + Contacts.IS_SDN_CONTACT + "!=-2");

9.File:JoinContactListAdapter.java

Path:packages\apps\contacts\src\com\android\contacts\list   

函数:public void configureLoader(CursorLoader cursorLoader, long directoryId) 

将: loader.setSelection(Contacts._ID + "!=?

"+" AND " + Contacts.INDICATE_PHONE_SIM + "=-1");

改动为:

    loader.setSelection(Contacts._ID + "!=?"+" AND " + Contacts.INDICATE_PHONE_SIM + "=-1" + " AND " + Contacts.IS_SDN_CONTACT + "!=-2");

在手机中预置联系人/Service Number的更多相关文章

  1. 读取手机中的联系人信息(android.provider.ContactsContract)

    本篇开始讲如何从Android中得到本机联系人的信息.由于Android较快的版本升级,部分API已经发生了变化.本篇探究的通过ContentProvider机制获取联系人的API从Android2. ...

  2. Android向手机通讯录中的所有的联系人(包括SIM卡),向手机通讯录中插入联系人

    package com.example.myapi.phonepersion; import java.util.ArrayList; import java.util.List; import an ...

  3. Android-->发送短信页面实现(短信发送以及群发和从电话本中选择联系人)-----------》2

    分析下怎么写 首先,我们需要一个输入框,可以手动的输入手机号码, 其次,很少有人愿意手动输入,那么我们需要提供一个按钮来给我们的用户选择自己电话本中的联系人(一次可以选择多个即群发) 然后,我们需要一 ...

  4. [UWP]UWP中获取联系人/邮件发送/SMS消息发送操作

    这篇博客将介绍如何在UWP程序中获取联系人/邮件发送/SMS发送的基础操作. 1. 获取联系人 UWP中联系人获取需要引入Windows.ApplicationModel.Contacts名称空间. ...

  5. 【转】Android 增,删,改,查 通讯录中的联系人

    一.权限 操作通讯录必须在AndroidManifest.xml中先添加2个权限, <uses-permission android:name="android.permission. ...

  6. 微软BI 之SSIS 系列 - 在 SSIS 中使用 Web Service 以及 XML 解析

    开篇介绍 Web Service 的用途非常广几乎无处不在,像各大门户网站上的天气预报使用到的第三方 Web Service API,像手机客户端和服务器端的交互等都可以通过事先设计好的 Web Se ...

  7. Android 增,删,改,查 通讯录中的联系人

    一.权限 操作通讯录必须在AndroidManifest.xml中先添加2个权限, <uses-permission android:name="android.permission. ...

  8. 从Android手机中取出已安装的app包,导出apk

    从Android手机中取出已安装的app包,导出apk TAG:Android,提取,apk,adb,pm,root,导出apk 假设有这样一个场景,A君看到你手机上一个实用APP,想要安装到自己手机 ...

  9. 【Java EE 学习 24 下】【注解在数据库开发中的使用】【反射+注解+动态代理在事务中的应用service层】

    一.使用注解可以解决JavaBean和数据库中表名不一致.字段名不一致.字段数量不一致的问题. 1.Sun公司给jdbc提供的注解 @Table.@Column.@Id.@OneToMany.@One ...

随机推荐

  1. EF数据迁移命令

    在包管理器控制台中输入命令“enable-migrations”,然后按Enter键!Visual Studio将生成一个名为“Configurations.cs”的文件; 你可以安全地忽略它,但你需 ...

  2. Android控件-单选按钮RadioButton

    RadioGroup单选按钮用法,还是先看效果图 先中后,点RadioGroup测试按钮,可在标题栏显示选择结果,点清除可以清除选择.下面上代码,main.xml: <RadioGroup an ...

  3. 在C# 获取当前应用网址

    /// <summary>        /// 获取当前应用网址        /// </summary>        /// <returns></r ...

  4. XFCE 桌面环境美化,fedora27系统

    一.添加RPM Fusion源,安装方法这里就不说了以前的文章里写过. 二.安装XFCE 主题管理器 xfce-theme-manager [root@Fedora ~]# dnf install x ...

  5. 【Henu ACM Round#15 D】Ilya and Escalator

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 概率DP; 设f[i][j]表示前i个单位时间,j个人进入房间的概率是多少 然后想一下和i-1秒的时候要怎么转移就可以了. i-1秒 ...

  6. HDU——T 3072 Intelligence System

    http://acm.hdu.edu.cn/showproblem.php?pid=3072 Time Limit: 2000/1000 MS (Java/Others)    Memory Limi ...

  7. Redis命令学习-Transaction(事务)

    DISCARD ​DISCARD :取消事务,放弃运行事务块内的全部代码.假设在使用WATCH命令监视某个key.则取消监视,等同于UNWATCH. ​返回值:总是返回ok.    ​     ​ ...

  8. 操作excel脚本练习

    # -*- coding: utf-8 -*- import xlrd import xlwt import sys from xlwt import * from xlrd import open_ ...

  9. 怎样通过MSG_WAITALL设置阻塞时间,IO模式精细讲解: MSG_DONTWAIT 、 MSG_WAITALL

    首先给出MSDN上一段设置阻塞超时的代码:(网址为http://social.msdn.microsoft.com/Forums/zh-SG/visualcpluszhchs/thread/3d9da ...

  10. BZOJ 1232 Kruskal

    思路: 跟昨天的考试题特别像-.. 就是裸的Kruskal 把边权设为连接的两个点的点权之和加上边权*2 搞定 //By SiriusRen #include <cstdio> #incl ...