问题现象
导入号码格式核心代码如下,其中参数 defaultFormattingType 设置为 FORMAT_NANP
最终得到号码为1-558-888-6666,参数设置为 FORMAT_JAPAN 则正常
String source = "15588886666"; //normal int defaultFormattingType = PhoneNumberUtils.FORMAT_JAPAN; //bug // int defaultFormattingType = PhoneNumberUtils.FORMAT_NANP; final SpannableStringBuilder text = new SpannableStringBuilder(source); PhoneNumberUtils.formatNumber(text, defaultFormattingType); String phone = text.toString(); Log.d("Provision","phone="+phone);
解决办法
frameworks/opt/vcard/java/com/android/vcard/VCardUtils.java
public static int getPhoneNumberFormat(final int vcardType) { if (VCardConfig.isJapaneseDevice(vcardType)) { return PhoneNumberUtils.FORMAT_JAPAN; } else { // return PhoneNumberUtils.FORMAT_NANP;//cczheng fix import phone with - bug return PhoneNumberUtils.FORMAT_JAPAN; } }
导入 vcf 联系人调用代码如下
private void importVCard(){ File file = new File("/sdcard/test.vcf"); Uri uriProvider = FileProvider.getUriForFile(this, "xxxxx.fileprovider", file); //Uri uriFile = Uri.fromFile(file); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(uri, "text/x-vcard"); startActivity(intent); }
可以看到实际上跳转系统界面去导入,经过查找发现跳转的目的地就是 Contacts 应用,如果安装了其它联系人应用比如谷歌 contact,
会弹框提示要选用那一个。高版本安卓系统,不能直接访问 sdcard 文件,传递 uri 也是无用的,若要不跳转 Contact 界面中再去手动选择
vcf 文件,则将 Contacts 改为 uid system 属性即可
packages\apps\Contacts\AndroidManifest.xml
<!-- vCard related --> <activity android:name=".vcard.ImportVCardActivity" android:configChanges="orientation|screenSize|keyboardHidden" android:exported="true" android:theme="@style/BackgroundOnlyTheme"> <intent-filter> <action android:name="android.intent.action.VIEW"/> <data android:mimeType="text/directory"/> <data android:mimeType="text/vcard"/> <data android:mimeType="text/x-vcard"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>
具体流程如下
Contact
|
|----传递 vcf 文件 uri 至 ImportVCardActivity
|----解析构造 ImportRequest 后 VCardService 调用 handleImportRequest 处理
|----实际通过线程 ImportProcessor 调用 runInternal() 转至下方 vcard
vcard
|
|----VCardEntryConstructor onEntryStarted
|----VCardEntry addPhone
|----VCardUtils getPhoneNumberFormat
|----PhoneNumberUtilsPort formatNumber