Merge change Iecf85b40 into eclair-mr2
* changes: Rename several files so that readers would not be confused.
This commit is contained in:
@@ -83,18 +83,6 @@ package android.pim.vcard;
|
||||
|
||||
public static final String PARAM_TYPE = "TYPE";
|
||||
|
||||
// How more than one TYPE fields are expressed is different between vCard 2.1 and vCard 3.0
|
||||
//
|
||||
// e.g.
|
||||
// 1) Probably valid in both vCard 2.1 and vCard 3.0: "ADR;TYPE=DOM;TYPE=HOME:..."
|
||||
// 2) Valid in vCard 2.1 but not in vCard 3.0: "ADR;DOM;HOME:..."
|
||||
// 3) Valid in vCard 3.0 but not in vCard 2.1: "ADR;TYPE=DOM,HOME:..."
|
||||
//
|
||||
// 2) has been the default of VCard exporter/importer in Android, but we can see the other
|
||||
// formats in vCard data emitted by the other softwares/devices.
|
||||
//
|
||||
// So we are currently not sure which type is the best; probably we will have to change which
|
||||
// type should be emitted depending on the device.
|
||||
public static final String PARAM_TYPE_HOME = "HOME";
|
||||
public static final String PARAM_TYPE_WORK = "WORK";
|
||||
public static final String PARAM_TYPE_FAX = "FAX";
|
||||
@@ -117,7 +105,6 @@ package android.pim.vcard;
|
||||
public static final String PARAM_TYPE_TLX = "TLX"; // Telex
|
||||
|
||||
// Phone types existing in vCard 2.1 but not known to ContactsContract.
|
||||
// TODO: should make parser make these TYPE_CUSTOM.
|
||||
public static final String PARAM_TYPE_MODEM = "MODEM";
|
||||
public static final String PARAM_TYPE_MSG = "MSG";
|
||||
public static final String PARAM_TYPE_BBS = "BBS";
|
||||
@@ -156,9 +143,11 @@ package android.pim.vcard;
|
||||
public static final String PROPERTY_X_GOOGLE_TALK_WITH_SPACE = "X-GOOGLE TALK";
|
||||
}
|
||||
|
||||
// TODO: Should be in ContactsContract?
|
||||
/* package */ static final int MAX_DATA_COLUMN = 15;
|
||||
|
||||
/* package */ static final int MAX_CHARACTER_NUMS_QP = 76;
|
||||
static final int MAX_CHARACTER_NUMS_BASE64_V30 = 75;
|
||||
|
||||
private Constants() {
|
||||
}
|
||||
}
|
||||
380
core/java/android/pim/vcard/JapaneseUtils.java
Normal file
380
core/java/android/pim/vcard/JapaneseUtils.java
Normal file
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.pim.vcard;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* TextUtils especially for Japanese.
|
||||
*/
|
||||
/* package */ class JapaneseUtils {
|
||||
static private final Map<Character, String> sHalfWidthMap =
|
||||
new HashMap<Character, String>();
|
||||
|
||||
static {
|
||||
// There's no logical mapping rule in Unicode. Sigh.
|
||||
sHalfWidthMap.put('\u3001', "\uFF64");
|
||||
sHalfWidthMap.put('\u3002', "\uFF61");
|
||||
sHalfWidthMap.put('\u300C', "\uFF62");
|
||||
sHalfWidthMap.put('\u300D', "\uFF63");
|
||||
sHalfWidthMap.put('\u301C', "~");
|
||||
sHalfWidthMap.put('\u3041', "\uFF67");
|
||||
sHalfWidthMap.put('\u3042', "\uFF71");
|
||||
sHalfWidthMap.put('\u3043', "\uFF68");
|
||||
sHalfWidthMap.put('\u3044', "\uFF72");
|
||||
sHalfWidthMap.put('\u3045', "\uFF69");
|
||||
sHalfWidthMap.put('\u3046', "\uFF73");
|
||||
sHalfWidthMap.put('\u3047', "\uFF6A");
|
||||
sHalfWidthMap.put('\u3048', "\uFF74");
|
||||
sHalfWidthMap.put('\u3049', "\uFF6B");
|
||||
sHalfWidthMap.put('\u304A', "\uFF75");
|
||||
sHalfWidthMap.put('\u304B', "\uFF76");
|
||||
sHalfWidthMap.put('\u304C', "\uFF76\uFF9E");
|
||||
sHalfWidthMap.put('\u304D', "\uFF77");
|
||||
sHalfWidthMap.put('\u304E', "\uFF77\uFF9E");
|
||||
sHalfWidthMap.put('\u304F', "\uFF78");
|
||||
sHalfWidthMap.put('\u3050', "\uFF78\uFF9E");
|
||||
sHalfWidthMap.put('\u3051', "\uFF79");
|
||||
sHalfWidthMap.put('\u3052', "\uFF79\uFF9E");
|
||||
sHalfWidthMap.put('\u3053', "\uFF7A");
|
||||
sHalfWidthMap.put('\u3054', "\uFF7A\uFF9E");
|
||||
sHalfWidthMap.put('\u3055', "\uFF7B");
|
||||
sHalfWidthMap.put('\u3056', "\uFF7B\uFF9E");
|
||||
sHalfWidthMap.put('\u3057', "\uFF7C");
|
||||
sHalfWidthMap.put('\u3058', "\uFF7C\uFF9E");
|
||||
sHalfWidthMap.put('\u3059', "\uFF7D");
|
||||
sHalfWidthMap.put('\u305A', "\uFF7D\uFF9E");
|
||||
sHalfWidthMap.put('\u305B', "\uFF7E");
|
||||
sHalfWidthMap.put('\u305C', "\uFF7E\uFF9E");
|
||||
sHalfWidthMap.put('\u305D', "\uFF7F");
|
||||
sHalfWidthMap.put('\u305E', "\uFF7F\uFF9E");
|
||||
sHalfWidthMap.put('\u305F', "\uFF80");
|
||||
sHalfWidthMap.put('\u3060', "\uFF80\uFF9E");
|
||||
sHalfWidthMap.put('\u3061', "\uFF81");
|
||||
sHalfWidthMap.put('\u3062', "\uFF81\uFF9E");
|
||||
sHalfWidthMap.put('\u3063', "\uFF6F");
|
||||
sHalfWidthMap.put('\u3064', "\uFF82");
|
||||
sHalfWidthMap.put('\u3065', "\uFF82\uFF9E");
|
||||
sHalfWidthMap.put('\u3066', "\uFF83");
|
||||
sHalfWidthMap.put('\u3067', "\uFF83\uFF9E");
|
||||
sHalfWidthMap.put('\u3068', "\uFF84");
|
||||
sHalfWidthMap.put('\u3069', "\uFF84\uFF9E");
|
||||
sHalfWidthMap.put('\u306A', "\uFF85");
|
||||
sHalfWidthMap.put('\u306B', "\uFF86");
|
||||
sHalfWidthMap.put('\u306C', "\uFF87");
|
||||
sHalfWidthMap.put('\u306D', "\uFF88");
|
||||
sHalfWidthMap.put('\u306E', "\uFF89");
|
||||
sHalfWidthMap.put('\u306F', "\uFF8A");
|
||||
sHalfWidthMap.put('\u3070', "\uFF8A\uFF9E");
|
||||
sHalfWidthMap.put('\u3071', "\uFF8A\uFF9F");
|
||||
sHalfWidthMap.put('\u3072', "\uFF8B");
|
||||
sHalfWidthMap.put('\u3073', "\uFF8B\uFF9E");
|
||||
sHalfWidthMap.put('\u3074', "\uFF8B\uFF9F");
|
||||
sHalfWidthMap.put('\u3075', "\uFF8C");
|
||||
sHalfWidthMap.put('\u3076', "\uFF8C\uFF9E");
|
||||
sHalfWidthMap.put('\u3077', "\uFF8C\uFF9F");
|
||||
sHalfWidthMap.put('\u3078', "\uFF8D");
|
||||
sHalfWidthMap.put('\u3079', "\uFF8D\uFF9E");
|
||||
sHalfWidthMap.put('\u307A', "\uFF8D\uFF9F");
|
||||
sHalfWidthMap.put('\u307B', "\uFF8E");
|
||||
sHalfWidthMap.put('\u307C', "\uFF8E\uFF9E");
|
||||
sHalfWidthMap.put('\u307D', "\uFF8E\uFF9F");
|
||||
sHalfWidthMap.put('\u307E', "\uFF8F");
|
||||
sHalfWidthMap.put('\u307F', "\uFF90");
|
||||
sHalfWidthMap.put('\u3080', "\uFF91");
|
||||
sHalfWidthMap.put('\u3081', "\uFF92");
|
||||
sHalfWidthMap.put('\u3082', "\uFF93");
|
||||
sHalfWidthMap.put('\u3083', "\uFF6C");
|
||||
sHalfWidthMap.put('\u3084', "\uFF94");
|
||||
sHalfWidthMap.put('\u3085', "\uFF6D");
|
||||
sHalfWidthMap.put('\u3086', "\uFF95");
|
||||
sHalfWidthMap.put('\u3087', "\uFF6E");
|
||||
sHalfWidthMap.put('\u3088', "\uFF96");
|
||||
sHalfWidthMap.put('\u3089', "\uFF97");
|
||||
sHalfWidthMap.put('\u308A', "\uFF98");
|
||||
sHalfWidthMap.put('\u308B', "\uFF99");
|
||||
sHalfWidthMap.put('\u308C', "\uFF9A");
|
||||
sHalfWidthMap.put('\u308D', "\uFF9B");
|
||||
sHalfWidthMap.put('\u308E', "\uFF9C");
|
||||
sHalfWidthMap.put('\u308F', "\uFF9C");
|
||||
sHalfWidthMap.put('\u3090', "\uFF72");
|
||||
sHalfWidthMap.put('\u3091', "\uFF74");
|
||||
sHalfWidthMap.put('\u3092', "\uFF66");
|
||||
sHalfWidthMap.put('\u3093', "\uFF9D");
|
||||
sHalfWidthMap.put('\u309B', "\uFF9E");
|
||||
sHalfWidthMap.put('\u309C', "\uFF9F");
|
||||
sHalfWidthMap.put('\u30A1', "\uFF67");
|
||||
sHalfWidthMap.put('\u30A2', "\uFF71");
|
||||
sHalfWidthMap.put('\u30A3', "\uFF68");
|
||||
sHalfWidthMap.put('\u30A4', "\uFF72");
|
||||
sHalfWidthMap.put('\u30A5', "\uFF69");
|
||||
sHalfWidthMap.put('\u30A6', "\uFF73");
|
||||
sHalfWidthMap.put('\u30A7', "\uFF6A");
|
||||
sHalfWidthMap.put('\u30A8', "\uFF74");
|
||||
sHalfWidthMap.put('\u30A9', "\uFF6B");
|
||||
sHalfWidthMap.put('\u30AA', "\uFF75");
|
||||
sHalfWidthMap.put('\u30AB', "\uFF76");
|
||||
sHalfWidthMap.put('\u30AC', "\uFF76\uFF9E");
|
||||
sHalfWidthMap.put('\u30AD', "\uFF77");
|
||||
sHalfWidthMap.put('\u30AE', "\uFF77\uFF9E");
|
||||
sHalfWidthMap.put('\u30AF', "\uFF78");
|
||||
sHalfWidthMap.put('\u30B0', "\uFF78\uFF9E");
|
||||
sHalfWidthMap.put('\u30B1', "\uFF79");
|
||||
sHalfWidthMap.put('\u30B2', "\uFF79\uFF9E");
|
||||
sHalfWidthMap.put('\u30B3', "\uFF7A");
|
||||
sHalfWidthMap.put('\u30B4', "\uFF7A\uFF9E");
|
||||
sHalfWidthMap.put('\u30B5', "\uFF7B");
|
||||
sHalfWidthMap.put('\u30B6', "\uFF7B\uFF9E");
|
||||
sHalfWidthMap.put('\u30B7', "\uFF7C");
|
||||
sHalfWidthMap.put('\u30B8', "\uFF7C\uFF9E");
|
||||
sHalfWidthMap.put('\u30B9', "\uFF7D");
|
||||
sHalfWidthMap.put('\u30BA', "\uFF7D\uFF9E");
|
||||
sHalfWidthMap.put('\u30BB', "\uFF7E");
|
||||
sHalfWidthMap.put('\u30BC', "\uFF7E\uFF9E");
|
||||
sHalfWidthMap.put('\u30BD', "\uFF7F");
|
||||
sHalfWidthMap.put('\u30BE', "\uFF7F\uFF9E");
|
||||
sHalfWidthMap.put('\u30BF', "\uFF80");
|
||||
sHalfWidthMap.put('\u30C0', "\uFF80\uFF9E");
|
||||
sHalfWidthMap.put('\u30C1', "\uFF81");
|
||||
sHalfWidthMap.put('\u30C2', "\uFF81\uFF9E");
|
||||
sHalfWidthMap.put('\u30C3', "\uFF6F");
|
||||
sHalfWidthMap.put('\u30C4', "\uFF82");
|
||||
sHalfWidthMap.put('\u30C5', "\uFF82\uFF9E");
|
||||
sHalfWidthMap.put('\u30C6', "\uFF83");
|
||||
sHalfWidthMap.put('\u30C7', "\uFF83\uFF9E");
|
||||
sHalfWidthMap.put('\u30C8', "\uFF84");
|
||||
sHalfWidthMap.put('\u30C9', "\uFF84\uFF9E");
|
||||
sHalfWidthMap.put('\u30CA', "\uFF85");
|
||||
sHalfWidthMap.put('\u30CB', "\uFF86");
|
||||
sHalfWidthMap.put('\u30CC', "\uFF87");
|
||||
sHalfWidthMap.put('\u30CD', "\uFF88");
|
||||
sHalfWidthMap.put('\u30CE', "\uFF89");
|
||||
sHalfWidthMap.put('\u30CF', "\uFF8A");
|
||||
sHalfWidthMap.put('\u30D0', "\uFF8A\uFF9E");
|
||||
sHalfWidthMap.put('\u30D1', "\uFF8A\uFF9F");
|
||||
sHalfWidthMap.put('\u30D2', "\uFF8B");
|
||||
sHalfWidthMap.put('\u30D3', "\uFF8B\uFF9E");
|
||||
sHalfWidthMap.put('\u30D4', "\uFF8B\uFF9F");
|
||||
sHalfWidthMap.put('\u30D5', "\uFF8C");
|
||||
sHalfWidthMap.put('\u30D6', "\uFF8C\uFF9E");
|
||||
sHalfWidthMap.put('\u30D7', "\uFF8C\uFF9F");
|
||||
sHalfWidthMap.put('\u30D8', "\uFF8D");
|
||||
sHalfWidthMap.put('\u30D9', "\uFF8D\uFF9E");
|
||||
sHalfWidthMap.put('\u30DA', "\uFF8D\uFF9F");
|
||||
sHalfWidthMap.put('\u30DB', "\uFF8E");
|
||||
sHalfWidthMap.put('\u30DC', "\uFF8E\uFF9E");
|
||||
sHalfWidthMap.put('\u30DD', "\uFF8E\uFF9F");
|
||||
sHalfWidthMap.put('\u30DE', "\uFF8F");
|
||||
sHalfWidthMap.put('\u30DF', "\uFF90");
|
||||
sHalfWidthMap.put('\u30E0', "\uFF91");
|
||||
sHalfWidthMap.put('\u30E1', "\uFF92");
|
||||
sHalfWidthMap.put('\u30E2', "\uFF93");
|
||||
sHalfWidthMap.put('\u30E3', "\uFF6C");
|
||||
sHalfWidthMap.put('\u30E4', "\uFF94");
|
||||
sHalfWidthMap.put('\u30E5', "\uFF6D");
|
||||
sHalfWidthMap.put('\u30E6', "\uFF95");
|
||||
sHalfWidthMap.put('\u30E7', "\uFF6E");
|
||||
sHalfWidthMap.put('\u30E8', "\uFF96");
|
||||
sHalfWidthMap.put('\u30E9', "\uFF97");
|
||||
sHalfWidthMap.put('\u30EA', "\uFF98");
|
||||
sHalfWidthMap.put('\u30EB', "\uFF99");
|
||||
sHalfWidthMap.put('\u30EC', "\uFF9A");
|
||||
sHalfWidthMap.put('\u30ED', "\uFF9B");
|
||||
sHalfWidthMap.put('\u30EE', "\uFF9C");
|
||||
sHalfWidthMap.put('\u30EF', "\uFF9C");
|
||||
sHalfWidthMap.put('\u30F0', "\uFF72");
|
||||
sHalfWidthMap.put('\u30F1', "\uFF74");
|
||||
sHalfWidthMap.put('\u30F2', "\uFF66");
|
||||
sHalfWidthMap.put('\u30F3', "\uFF9D");
|
||||
sHalfWidthMap.put('\u30F4', "\uFF73\uFF9E");
|
||||
sHalfWidthMap.put('\u30F5', "\uFF76");
|
||||
sHalfWidthMap.put('\u30F6', "\uFF79");
|
||||
sHalfWidthMap.put('\u30FB', "\uFF65");
|
||||
sHalfWidthMap.put('\u30FC', "\uFF70");
|
||||
sHalfWidthMap.put('\uFF01', "!");
|
||||
sHalfWidthMap.put('\uFF02', "\"");
|
||||
sHalfWidthMap.put('\uFF03', "#");
|
||||
sHalfWidthMap.put('\uFF04', "$");
|
||||
sHalfWidthMap.put('\uFF05', "%");
|
||||
sHalfWidthMap.put('\uFF06', "&");
|
||||
sHalfWidthMap.put('\uFF07', "'");
|
||||
sHalfWidthMap.put('\uFF08', "(");
|
||||
sHalfWidthMap.put('\uFF09', ")");
|
||||
sHalfWidthMap.put('\uFF0A', "*");
|
||||
sHalfWidthMap.put('\uFF0B', "+");
|
||||
sHalfWidthMap.put('\uFF0C', ",");
|
||||
sHalfWidthMap.put('\uFF0D', "-");
|
||||
sHalfWidthMap.put('\uFF0E', ".");
|
||||
sHalfWidthMap.put('\uFF0F', "/");
|
||||
sHalfWidthMap.put('\uFF10', "0");
|
||||
sHalfWidthMap.put('\uFF11', "1");
|
||||
sHalfWidthMap.put('\uFF12', "2");
|
||||
sHalfWidthMap.put('\uFF13', "3");
|
||||
sHalfWidthMap.put('\uFF14', "4");
|
||||
sHalfWidthMap.put('\uFF15', "5");
|
||||
sHalfWidthMap.put('\uFF16', "6");
|
||||
sHalfWidthMap.put('\uFF17', "7");
|
||||
sHalfWidthMap.put('\uFF18', "8");
|
||||
sHalfWidthMap.put('\uFF19', "9");
|
||||
sHalfWidthMap.put('\uFF1A', ":");
|
||||
sHalfWidthMap.put('\uFF1B', ";");
|
||||
sHalfWidthMap.put('\uFF1C', "<");
|
||||
sHalfWidthMap.put('\uFF1D', "=");
|
||||
sHalfWidthMap.put('\uFF1E', ">");
|
||||
sHalfWidthMap.put('\uFF1F', "?");
|
||||
sHalfWidthMap.put('\uFF20', "@");
|
||||
sHalfWidthMap.put('\uFF21', "A");
|
||||
sHalfWidthMap.put('\uFF22', "B");
|
||||
sHalfWidthMap.put('\uFF23', "C");
|
||||
sHalfWidthMap.put('\uFF24', "D");
|
||||
sHalfWidthMap.put('\uFF25', "E");
|
||||
sHalfWidthMap.put('\uFF26', "F");
|
||||
sHalfWidthMap.put('\uFF27', "G");
|
||||
sHalfWidthMap.put('\uFF28', "H");
|
||||
sHalfWidthMap.put('\uFF29', "I");
|
||||
sHalfWidthMap.put('\uFF2A', "J");
|
||||
sHalfWidthMap.put('\uFF2B', "K");
|
||||
sHalfWidthMap.put('\uFF2C', "L");
|
||||
sHalfWidthMap.put('\uFF2D', "M");
|
||||
sHalfWidthMap.put('\uFF2E', "N");
|
||||
sHalfWidthMap.put('\uFF2F', "O");
|
||||
sHalfWidthMap.put('\uFF30', "P");
|
||||
sHalfWidthMap.put('\uFF31', "Q");
|
||||
sHalfWidthMap.put('\uFF32', "R");
|
||||
sHalfWidthMap.put('\uFF33', "S");
|
||||
sHalfWidthMap.put('\uFF34', "T");
|
||||
sHalfWidthMap.put('\uFF35', "U");
|
||||
sHalfWidthMap.put('\uFF36', "V");
|
||||
sHalfWidthMap.put('\uFF37', "W");
|
||||
sHalfWidthMap.put('\uFF38', "X");
|
||||
sHalfWidthMap.put('\uFF39', "Y");
|
||||
sHalfWidthMap.put('\uFF3A', "Z");
|
||||
sHalfWidthMap.put('\uFF3B', "[");
|
||||
sHalfWidthMap.put('\uFF3C', "\\");
|
||||
sHalfWidthMap.put('\uFF3D', "]");
|
||||
sHalfWidthMap.put('\uFF3E', "^");
|
||||
sHalfWidthMap.put('\uFF3F', "_");
|
||||
sHalfWidthMap.put('\uFF41', "a");
|
||||
sHalfWidthMap.put('\uFF42', "b");
|
||||
sHalfWidthMap.put('\uFF43', "c");
|
||||
sHalfWidthMap.put('\uFF44', "d");
|
||||
sHalfWidthMap.put('\uFF45', "e");
|
||||
sHalfWidthMap.put('\uFF46', "f");
|
||||
sHalfWidthMap.put('\uFF47', "g");
|
||||
sHalfWidthMap.put('\uFF48', "h");
|
||||
sHalfWidthMap.put('\uFF49', "i");
|
||||
sHalfWidthMap.put('\uFF4A', "j");
|
||||
sHalfWidthMap.put('\uFF4B', "k");
|
||||
sHalfWidthMap.put('\uFF4C', "l");
|
||||
sHalfWidthMap.put('\uFF4D', "m");
|
||||
sHalfWidthMap.put('\uFF4E', "n");
|
||||
sHalfWidthMap.put('\uFF4F', "o");
|
||||
sHalfWidthMap.put('\uFF50', "p");
|
||||
sHalfWidthMap.put('\uFF51', "q");
|
||||
sHalfWidthMap.put('\uFF52', "r");
|
||||
sHalfWidthMap.put('\uFF53', "s");
|
||||
sHalfWidthMap.put('\uFF54', "t");
|
||||
sHalfWidthMap.put('\uFF55', "u");
|
||||
sHalfWidthMap.put('\uFF56', "v");
|
||||
sHalfWidthMap.put('\uFF57', "w");
|
||||
sHalfWidthMap.put('\uFF58', "x");
|
||||
sHalfWidthMap.put('\uFF59', "y");
|
||||
sHalfWidthMap.put('\uFF5A', "z");
|
||||
sHalfWidthMap.put('\uFF5B', "{");
|
||||
sHalfWidthMap.put('\uFF5C', "|");
|
||||
sHalfWidthMap.put('\uFF5D', "}");
|
||||
sHalfWidthMap.put('\uFF5E', "~");
|
||||
sHalfWidthMap.put('\uFF61', "\uFF61");
|
||||
sHalfWidthMap.put('\uFF62', "\uFF62");
|
||||
sHalfWidthMap.put('\uFF63', "\uFF63");
|
||||
sHalfWidthMap.put('\uFF64', "\uFF64");
|
||||
sHalfWidthMap.put('\uFF65', "\uFF65");
|
||||
sHalfWidthMap.put('\uFF66', "\uFF66");
|
||||
sHalfWidthMap.put('\uFF67', "\uFF67");
|
||||
sHalfWidthMap.put('\uFF68', "\uFF68");
|
||||
sHalfWidthMap.put('\uFF69', "\uFF69");
|
||||
sHalfWidthMap.put('\uFF6A', "\uFF6A");
|
||||
sHalfWidthMap.put('\uFF6B', "\uFF6B");
|
||||
sHalfWidthMap.put('\uFF6C', "\uFF6C");
|
||||
sHalfWidthMap.put('\uFF6D', "\uFF6D");
|
||||
sHalfWidthMap.put('\uFF6E', "\uFF6E");
|
||||
sHalfWidthMap.put('\uFF6F', "\uFF6F");
|
||||
sHalfWidthMap.put('\uFF70', "\uFF70");
|
||||
sHalfWidthMap.put('\uFF71', "\uFF71");
|
||||
sHalfWidthMap.put('\uFF72', "\uFF72");
|
||||
sHalfWidthMap.put('\uFF73', "\uFF73");
|
||||
sHalfWidthMap.put('\uFF74', "\uFF74");
|
||||
sHalfWidthMap.put('\uFF75', "\uFF75");
|
||||
sHalfWidthMap.put('\uFF76', "\uFF76");
|
||||
sHalfWidthMap.put('\uFF77', "\uFF77");
|
||||
sHalfWidthMap.put('\uFF78', "\uFF78");
|
||||
sHalfWidthMap.put('\uFF79', "\uFF79");
|
||||
sHalfWidthMap.put('\uFF7A', "\uFF7A");
|
||||
sHalfWidthMap.put('\uFF7B', "\uFF7B");
|
||||
sHalfWidthMap.put('\uFF7C', "\uFF7C");
|
||||
sHalfWidthMap.put('\uFF7D', "\uFF7D");
|
||||
sHalfWidthMap.put('\uFF7E', "\uFF7E");
|
||||
sHalfWidthMap.put('\uFF7F', "\uFF7F");
|
||||
sHalfWidthMap.put('\uFF80', "\uFF80");
|
||||
sHalfWidthMap.put('\uFF81', "\uFF81");
|
||||
sHalfWidthMap.put('\uFF82', "\uFF82");
|
||||
sHalfWidthMap.put('\uFF83', "\uFF83");
|
||||
sHalfWidthMap.put('\uFF84', "\uFF84");
|
||||
sHalfWidthMap.put('\uFF85', "\uFF85");
|
||||
sHalfWidthMap.put('\uFF86', "\uFF86");
|
||||
sHalfWidthMap.put('\uFF87', "\uFF87");
|
||||
sHalfWidthMap.put('\uFF88', "\uFF88");
|
||||
sHalfWidthMap.put('\uFF89', "\uFF89");
|
||||
sHalfWidthMap.put('\uFF8A', "\uFF8A");
|
||||
sHalfWidthMap.put('\uFF8B', "\uFF8B");
|
||||
sHalfWidthMap.put('\uFF8C', "\uFF8C");
|
||||
sHalfWidthMap.put('\uFF8D', "\uFF8D");
|
||||
sHalfWidthMap.put('\uFF8E', "\uFF8E");
|
||||
sHalfWidthMap.put('\uFF8F', "\uFF8F");
|
||||
sHalfWidthMap.put('\uFF90', "\uFF90");
|
||||
sHalfWidthMap.put('\uFF91', "\uFF91");
|
||||
sHalfWidthMap.put('\uFF92', "\uFF92");
|
||||
sHalfWidthMap.put('\uFF93', "\uFF93");
|
||||
sHalfWidthMap.put('\uFF94', "\uFF94");
|
||||
sHalfWidthMap.put('\uFF95', "\uFF95");
|
||||
sHalfWidthMap.put('\uFF96', "\uFF96");
|
||||
sHalfWidthMap.put('\uFF97', "\uFF97");
|
||||
sHalfWidthMap.put('\uFF98', "\uFF98");
|
||||
sHalfWidthMap.put('\uFF99', "\uFF99");
|
||||
sHalfWidthMap.put('\uFF9A', "\uFF9A");
|
||||
sHalfWidthMap.put('\uFF9B', "\uFF9B");
|
||||
sHalfWidthMap.put('\uFF9C', "\uFF9C");
|
||||
sHalfWidthMap.put('\uFF9D', "\uFF9D");
|
||||
sHalfWidthMap.put('\uFF9E', "\uFF9E");
|
||||
sHalfWidthMap.put('\uFF9F', "\uFF9F");
|
||||
sHalfWidthMap.put('\uFFE5', "\u005C\u005C");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return half-width version of that character if possible. Return null if not possible
|
||||
* @param ch input character
|
||||
* @return CharSequence object if the mapping for ch exists. Return null otherwise.
|
||||
*/
|
||||
public static CharSequence tryGetHalfWidthText(char ch) {
|
||||
if (sHalfWidthMap.containsKey(ch)) {
|
||||
return sHalfWidthMap.get(ch);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,7 +196,7 @@ public class VCardComposer {
|
||||
* An useful example handler, which emits VCard String to outputstream one by one.
|
||||
* </p>
|
||||
* <p>
|
||||
* The input OutputStream object is closed() on {{@link #onTerminate()}.
|
||||
* The input OutputStream object is closed() on {@link #onTerminate()}.
|
||||
* Must not close the stream outside.
|
||||
* </p>
|
||||
*/
|
||||
@@ -353,7 +353,8 @@ public class VCardComposer {
|
||||
/**
|
||||
* Construct for supporting call log entry vCard composing.
|
||||
*/
|
||||
public VCardComposer(Context context, int vcardType, boolean careHandlerErrors) {
|
||||
public VCardComposer(final Context context, final int vcardType,
|
||||
final boolean careHandlerErrors) {
|
||||
mContext = context;
|
||||
mVCardType = vcardType;
|
||||
mCareHandlerErrors = careHandlerErrors;
|
||||
@@ -403,7 +404,7 @@ public class VCardComposer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Must call before {{@link #init()}.
|
||||
* Must be called before {@link #init()}.
|
||||
*/
|
||||
public void addHandler(OneEntryHandler handler) {
|
||||
if (handler != null) {
|
||||
@@ -510,8 +511,7 @@ public class VCardComposer {
|
||||
} catch (OutOfMemoryError error) {
|
||||
// Maybe some data (e.g. photo) is too big to have in memory. But it
|
||||
// should be rare.
|
||||
Log.e(LOG_TAG, "OutOfMemoryError occured. Ignore the entry: "
|
||||
+ name);
|
||||
Log.e(LOG_TAG, "OutOfMemoryError occured. Ignore the entry: " + name);
|
||||
System.gc();
|
||||
// TODO: should tell users what happened?
|
||||
return true;
|
||||
@@ -676,7 +676,7 @@ public class VCardComposer {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean containsNonEmptyName(ContentValues contentValues) {
|
||||
private boolean containsNonEmptyName(final ContentValues contentValues) {
|
||||
final String familyName = contentValues.getAsString(StructuredName.FAMILY_NAME);
|
||||
final String middleName = contentValues.getAsString(StructuredName.MIDDLE_NAME);
|
||||
final String givenName = contentValues.getAsString(StructuredName.GIVEN_NAME);
|
||||
@@ -715,7 +715,7 @@ public class VCardComposer {
|
||||
} else if (primaryContentValues == null) {
|
||||
// We choose the first "primary" ContentValues
|
||||
// if "super primary" ContentValues does not exist.
|
||||
Integer isPrimary = contentValues.getAsInteger(StructuredName.IS_PRIMARY);
|
||||
final Integer isPrimary = contentValues.getAsInteger(StructuredName.IS_PRIMARY);
|
||||
if (isPrimary != null && isPrimary > 0 &&
|
||||
containsNonEmptyName(contentValues)) {
|
||||
primaryContentValues = contentValues;
|
||||
@@ -897,11 +897,11 @@ public class VCardComposer {
|
||||
final String phoneticMiddleName;
|
||||
final String phoneticGivenName;
|
||||
{
|
||||
String tmpPhoneticFamilyName =
|
||||
final String tmpPhoneticFamilyName =
|
||||
primaryContentValues.getAsString(StructuredName.PHONETIC_FAMILY_NAME);
|
||||
String tmpPhoneticMiddleName =
|
||||
final String tmpPhoneticMiddleName =
|
||||
primaryContentValues.getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
|
||||
String tmpPhoneticGivenName =
|
||||
final String tmpPhoneticGivenName =
|
||||
primaryContentValues.getAsString(StructuredName.PHONETIC_GIVEN_NAME);
|
||||
if (mNeedsToConvertPhoneticString) {
|
||||
phoneticFamilyName = VCardUtils.toHalfWidthString(tmpPhoneticFamilyName);
|
||||
@@ -913,10 +913,11 @@ public class VCardComposer {
|
||||
phoneticGivenName = tmpPhoneticGivenName;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(TextUtils.isEmpty(phoneticFamilyName)
|
||||
&& TextUtils.isEmpty(phoneticMiddleName)
|
||||
&& TextUtils.isEmpty(phoneticGivenName))) {
|
||||
|
||||
// Try to emit the field(s) related to phonetic name.
|
||||
if (mIsV30) {
|
||||
final String sortString = VCardUtils
|
||||
.constructNameFromElements(mVCardType,
|
||||
@@ -937,6 +938,12 @@ public class VCardComposer {
|
||||
// since it is supported by
|
||||
// a lot of Japanese mobile phones. This is "X-" property, so
|
||||
// any parser hopefully would not get confused with this.
|
||||
//
|
||||
// Also, DoCoMo's specification requires vCard composer to use just the first
|
||||
// column.
|
||||
// i.e.
|
||||
// o SOUND;X-IRMC-N:Miyakawa Daisuke;;;;
|
||||
// x SOUND;X-IRMC-N:Miyakawa;Daisuke;;;
|
||||
builder.append(Constants.PROPERTY_SOUND);
|
||||
builder.append(VCARD_PARAM_SEPARATOR);
|
||||
builder.append(Constants.PARAM_TYPE_X_IRMC_N);
|
||||
@@ -970,8 +977,6 @@ public class VCardComposer {
|
||||
builder.append(mVCardCharsetParameter);
|
||||
}
|
||||
builder.append(VCARD_DATA_SEPARATOR);
|
||||
// DoCoMo's specification requires vCard composer to use just the first
|
||||
// column.
|
||||
{
|
||||
boolean first = true;
|
||||
if (!TextUtils.isEmpty(encodedPhoneticFamilyName)) {
|
||||
@@ -999,16 +1004,18 @@ public class VCardComposer {
|
||||
builder.append(VCARD_ITEM_SEPARATOR);
|
||||
builder.append(VCARD_END_OF_LINE);
|
||||
}
|
||||
} else if (mIsDoCoMo) {
|
||||
builder.append(Constants.PROPERTY_SOUND);
|
||||
builder.append(VCARD_PARAM_SEPARATOR);
|
||||
builder.append(Constants.PARAM_TYPE_X_IRMC_N);
|
||||
builder.append(VCARD_DATA_SEPARATOR);
|
||||
builder.append(VCARD_ITEM_SEPARATOR);
|
||||
builder.append(VCARD_ITEM_SEPARATOR);
|
||||
builder.append(VCARD_ITEM_SEPARATOR);
|
||||
builder.append(VCARD_ITEM_SEPARATOR);
|
||||
builder.append(VCARD_END_OF_LINE);
|
||||
} else { // If phonetic name fields are all empty
|
||||
if (mIsDoCoMo) {
|
||||
builder.append(Constants.PROPERTY_SOUND);
|
||||
builder.append(VCARD_PARAM_SEPARATOR);
|
||||
builder.append(Constants.PARAM_TYPE_X_IRMC_N);
|
||||
builder.append(VCARD_DATA_SEPARATOR);
|
||||
builder.append(VCARD_ITEM_SEPARATOR);
|
||||
builder.append(VCARD_ITEM_SEPARATOR);
|
||||
builder.append(VCARD_ITEM_SEPARATOR);
|
||||
builder.append(VCARD_ITEM_SEPARATOR);
|
||||
builder.append(VCARD_END_OF_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
if (mUsesDefactProperty) {
|
||||
@@ -1252,48 +1259,50 @@ public class VCardComposer {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<Integer, Integer> sPostalTypePriorityMap;
|
||||
|
||||
static {
|
||||
sPostalTypePriorityMap = new HashMap<Integer, Integer>();
|
||||
sPostalTypePriorityMap.put(StructuredPostal.TYPE_HOME, 0);
|
||||
sPostalTypePriorityMap.put(StructuredPostal.TYPE_WORK, 1);
|
||||
sPostalTypePriorityMap.put(StructuredPostal.TYPE_OTHER, 2);
|
||||
sPostalTypePriorityMap.put(StructuredPostal.TYPE_CUSTOM, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to append just one line. If there's no appropriate address
|
||||
* information, append an empty line.
|
||||
*/
|
||||
private void appendPostalsForDoCoMo(final StringBuilder builder,
|
||||
final List<ContentValues> contentValuesList) {
|
||||
// TODO: from old, inefficient code. fix this.
|
||||
if (appendPostalsForDoCoMoInternal(builder, contentValuesList,
|
||||
StructuredPostal.TYPE_HOME)) {
|
||||
return;
|
||||
}
|
||||
if (appendPostalsForDoCoMoInternal(builder, contentValuesList,
|
||||
StructuredPostal.TYPE_WORK)) {
|
||||
return;
|
||||
}
|
||||
if (appendPostalsForDoCoMoInternal(builder, contentValuesList,
|
||||
StructuredPostal.TYPE_OTHER)) {
|
||||
return;
|
||||
}
|
||||
if (appendPostalsForDoCoMoInternal(builder, contentValuesList,
|
||||
StructuredPostal.TYPE_CUSTOM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log.w(LOG_TAG,
|
||||
"Should not come here. Must have at least one postal data.");
|
||||
}
|
||||
|
||||
private boolean appendPostalsForDoCoMoInternal(final StringBuilder builder,
|
||||
final List<ContentValues> contentValuesList, Integer preferedType) {
|
||||
int currentPriority = Integer.MAX_VALUE;
|
||||
int currentType = Integer.MAX_VALUE;
|
||||
ContentValues currentContentValues = null;
|
||||
for (ContentValues contentValues : contentValuesList) {
|
||||
final Integer type = contentValues.getAsInteger(StructuredPostal.TYPE);
|
||||
final String label = contentValues.getAsString(StructuredPostal.LABEL);
|
||||
if (type == preferedType) {
|
||||
// Note: Not sure why we need to emit "empty" line even when actual
|
||||
// data does not exist. There may be some reason or may not.
|
||||
// We keep safer side since the previous implementation did so.
|
||||
appendVCardPostalLine(builder, type, label, contentValues, true, true);
|
||||
return true;
|
||||
if (contentValues == null) {
|
||||
continue;
|
||||
}
|
||||
final Integer typeAsInteger = contentValues.getAsInteger(StructuredPostal.TYPE);
|
||||
final Integer priorityAsInteger = sPostalTypePriorityMap.get(typeAsInteger);
|
||||
final int priority =
|
||||
(priorityAsInteger != null ? priorityAsInteger : Integer.MAX_VALUE);
|
||||
if (priority < currentPriority) {
|
||||
currentPriority = priority;
|
||||
currentType = typeAsInteger;
|
||||
currentContentValues = contentValues;
|
||||
if (priority == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
if (currentContentValues == null) {
|
||||
Log.w(LOG_TAG, "Should not come here. Must have at least one postal data.");
|
||||
return;
|
||||
}
|
||||
|
||||
final String label = currentContentValues.getAsString(StructuredPostal.LABEL);
|
||||
appendVCardPostalLine(builder, currentType, label, currentContentValues, false, true);
|
||||
}
|
||||
|
||||
private void appendPostalsForGeneric(final StringBuilder builder,
|
||||
@@ -1302,9 +1311,9 @@ public class VCardComposer {
|
||||
if (contentValues == null) {
|
||||
continue;
|
||||
}
|
||||
final Integer typeAsObject = contentValues.getAsInteger(StructuredPostal.TYPE);
|
||||
final int type = (typeAsObject != null ?
|
||||
typeAsObject : DEFAULT_POSTAL_TYPE);
|
||||
final Integer typeAsInteger = contentValues.getAsInteger(StructuredPostal.TYPE);
|
||||
final int type = (typeAsInteger != null ?
|
||||
typeAsInteger : DEFAULT_POSTAL_TYPE);
|
||||
final String label = contentValues.getAsString(StructuredPostal.LABEL);
|
||||
final Integer isPrimaryAsInteger =
|
||||
contentValues.getAsInteger(StructuredPostal.IS_PRIMARY);
|
||||
@@ -1525,9 +1534,9 @@ public class VCardComposer {
|
||||
photoType = "GIF";
|
||||
} else if (data.length >= 4 && data[0] == (byte) 0x89
|
||||
&& data[1] == 'P' && data[2] == 'N' && data[3] == 'G') {
|
||||
// Note: vCard 2.1 officially does not support PNG, but we may
|
||||
// have it and using X- word like "X-PNG" may not let importers
|
||||
// know it is PNG. So we use the String "PNG" as is...
|
||||
// Note: vCard 2.1 officially does not support PNG, but we may have it and
|
||||
// using X- word like "X-PNG" may not let importers know it is PNG.
|
||||
// So we use the String "PNG" as is...
|
||||
photoType = "PNG";
|
||||
} else if (data.length >= 2 && data[0] == (byte) 0xff
|
||||
&& data[1] == (byte) 0xd8) {
|
||||
@@ -1599,7 +1608,7 @@ public class VCardComposer {
|
||||
rawDataList.add(mimeType);
|
||||
final List<String> columnNameList;
|
||||
if (Nickname.CONTENT_ITEM_TYPE.equals(mimeType)) {
|
||||
|
||||
|
||||
} else {
|
||||
// If you add the other field, please check all the columns are able to be
|
||||
// converted to String.
|
||||
@@ -1851,7 +1860,7 @@ public class VCardComposer {
|
||||
break;
|
||||
}
|
||||
case StructuredPostal.TYPE_CUSTOM: {
|
||||
if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
|
||||
if (!TextUtils.isEmpty(label)
|
||||
&& VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
|
||||
// We're not sure whether the label is valid in the spec
|
||||
// ("IANA-token" in the vCard 3.0 is unclear...)
|
||||
@@ -1871,17 +1880,14 @@ public class VCardComposer {
|
||||
}
|
||||
|
||||
// Actual data construction starts from here.
|
||||
// TODO: add a new version of appendVCardLine() for this purpose.
|
||||
|
||||
builder.append(Constants.PROPERTY_ADR);
|
||||
builder.append(VCARD_PARAM_SEPARATOR);
|
||||
|
||||
// Parameters
|
||||
{
|
||||
boolean shouldAppendParamSeparator = false;
|
||||
if (!parameterList.isEmpty()) {
|
||||
builder.append(VCARD_PARAM_SEPARATOR);
|
||||
appendTypeParameters(builder, parameterList);
|
||||
shouldAppendParamSeparator = true;
|
||||
}
|
||||
|
||||
if (appendCharset) {
|
||||
@@ -1889,19 +1895,13 @@ public class VCardComposer {
|
||||
// but we will add it since the information should be useful for importers,
|
||||
//
|
||||
// Assume no parser does not emit error with this parameter in vCard 3.0.
|
||||
if (shouldAppendParamSeparator) {
|
||||
builder.append(VCARD_PARAM_SEPARATOR);
|
||||
}
|
||||
builder.append(VCARD_PARAM_SEPARATOR);
|
||||
builder.append(mVCardCharsetParameter);
|
||||
shouldAppendParamSeparator = true;
|
||||
}
|
||||
|
||||
if (reallyUseQuotedPrintable) {
|
||||
if (shouldAppendParamSeparator) {
|
||||
builder.append(VCARD_PARAM_SEPARATOR);
|
||||
}
|
||||
builder.append(VCARD_PARAM_SEPARATOR);
|
||||
builder.append(VCARD_PARAM_ENCODING_QP);
|
||||
shouldAppendParamSeparator = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1916,13 +1916,9 @@ public class VCardComposer {
|
||||
final String typeAsString;
|
||||
switch (type) {
|
||||
case Email.TYPE_CUSTOM: {
|
||||
// For backward compatibility.
|
||||
// Detail: Until Donut, there isn't TYPE_MOBILE for email while there is now.
|
||||
// To support mobile type at that time, this custom label had been used.
|
||||
if (android.provider.Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME
|
||||
.equals(label)) {
|
||||
if (VCardUtils.isMobilePhoneLabel(label)) {
|
||||
typeAsString = Constants.PARAM_TYPE_CELL;
|
||||
} else if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
|
||||
} else if (!TextUtils.isEmpty(label)
|
||||
&& VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
|
||||
typeAsString = "X-" + label;
|
||||
} else {
|
||||
@@ -1966,102 +1962,126 @@ public class VCardComposer {
|
||||
}
|
||||
|
||||
private void appendVCardTelephoneLine(final StringBuilder builder,
|
||||
final Integer typeAsObject, final String label,
|
||||
final Integer typeAsInteger, final String label,
|
||||
final String encodedData, boolean isPrimary) {
|
||||
builder.append(Constants.PROPERTY_TEL);
|
||||
builder.append(VCARD_PARAM_SEPARATOR);
|
||||
|
||||
final int typeAsPrimitive;
|
||||
if (typeAsObject == null) {
|
||||
typeAsPrimitive = Phone.TYPE_OTHER;
|
||||
final int type;
|
||||
if (typeAsInteger == null) {
|
||||
type = Phone.TYPE_OTHER;
|
||||
} else {
|
||||
typeAsPrimitive = typeAsObject;
|
||||
type = typeAsInteger;
|
||||
}
|
||||
|
||||
ArrayList<String> parameterList = new ArrayList<String>();
|
||||
switch (typeAsPrimitive) {
|
||||
case Phone.TYPE_HOME:
|
||||
parameterList.addAll(
|
||||
Arrays.asList(Constants.PARAM_TYPE_HOME));
|
||||
break;
|
||||
case Phone.TYPE_WORK:
|
||||
parameterList.addAll(
|
||||
Arrays.asList(Constants.PARAM_TYPE_WORK));
|
||||
break;
|
||||
case Phone.TYPE_FAX_HOME:
|
||||
parameterList.addAll(
|
||||
Arrays.asList(Constants.PARAM_TYPE_HOME, Constants.PARAM_TYPE_FAX));
|
||||
break;
|
||||
case Phone.TYPE_FAX_WORK:
|
||||
parameterList.addAll(
|
||||
Arrays.asList(Constants.PARAM_TYPE_WORK, Constants.PARAM_TYPE_FAX));
|
||||
break;
|
||||
case Phone.TYPE_MOBILE:
|
||||
parameterList.add(Constants.PARAM_TYPE_CELL);
|
||||
break;
|
||||
case Phone.TYPE_PAGER:
|
||||
if (mIsDoCoMo) {
|
||||
// Not sure about the reason, but previous implementation had
|
||||
// used "VOICE" instead of "PAGER"
|
||||
parameterList.add(Constants.PARAM_TYPE_VOICE);
|
||||
} else {
|
||||
parameterList.add(Constants.PARAM_TYPE_PAGER);
|
||||
switch (type) {
|
||||
case Phone.TYPE_HOME: {
|
||||
parameterList.addAll(
|
||||
Arrays.asList(Constants.PARAM_TYPE_HOME));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Phone.TYPE_OTHER:
|
||||
parameterList.add(Constants.PARAM_TYPE_VOICE);
|
||||
break;
|
||||
case Phone.TYPE_CAR:
|
||||
parameterList.add(Constants.PARAM_TYPE_CAR);
|
||||
break;
|
||||
case Phone.TYPE_COMPANY_MAIN:
|
||||
// There's no relevant field in vCard (at least 2.1).
|
||||
parameterList.add(Constants.PARAM_TYPE_WORK);
|
||||
isPrimary = true;
|
||||
break;
|
||||
case Phone.TYPE_ISDN:
|
||||
parameterList.add(Constants.PARAM_TYPE_ISDN);
|
||||
break;
|
||||
case Phone.TYPE_MAIN:
|
||||
isPrimary = true;
|
||||
break;
|
||||
case Phone.TYPE_OTHER_FAX:
|
||||
parameterList.add(Constants.PARAM_TYPE_FAX);
|
||||
break;
|
||||
case Phone.TYPE_TELEX:
|
||||
parameterList.add(Constants.PARAM_TYPE_TLX);
|
||||
break;
|
||||
case Phone.TYPE_WORK_MOBILE:
|
||||
parameterList.addAll(
|
||||
Arrays.asList(Constants.PARAM_TYPE_WORK, Constants.PARAM_TYPE_CELL));
|
||||
break;
|
||||
case Phone.TYPE_WORK_PAGER:
|
||||
parameterList.add(Constants.PARAM_TYPE_WORK);
|
||||
// See above.
|
||||
if (mIsDoCoMo) {
|
||||
parameterList.add(Constants.PARAM_TYPE_VOICE);
|
||||
} else {
|
||||
parameterList.add(Constants.PARAM_TYPE_PAGER);
|
||||
case Phone.TYPE_WORK: {
|
||||
parameterList.addAll(
|
||||
Arrays.asList(Constants.PARAM_TYPE_WORK));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Phone.TYPE_MMS:
|
||||
parameterList.add(Constants.PARAM_TYPE_MSG);
|
||||
break;
|
||||
case Phone.TYPE_CUSTOM:
|
||||
if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
|
||||
&& VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
|
||||
// Note: Strictly, vCard 2.1 does not allow "X-" parameter without
|
||||
// "TYPE=" string.
|
||||
parameterList.add("X-" + label);
|
||||
} else {
|
||||
// Just ignore the custom type.
|
||||
parameterList.add(Constants.PARAM_TYPE_VOICE);
|
||||
case Phone.TYPE_FAX_HOME: {
|
||||
parameterList.addAll(
|
||||
Arrays.asList(Constants.PARAM_TYPE_HOME, Constants.PARAM_TYPE_FAX));
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_FAX_WORK: {
|
||||
parameterList.addAll(
|
||||
Arrays.asList(Constants.PARAM_TYPE_WORK, Constants.PARAM_TYPE_FAX));
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_MOBILE: {
|
||||
parameterList.add(Constants.PARAM_TYPE_CELL);
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_PAGER: {
|
||||
if (mIsDoCoMo) {
|
||||
// Not sure about the reason, but previous implementation had
|
||||
// used "VOICE" instead of "PAGER"
|
||||
parameterList.add(Constants.PARAM_TYPE_VOICE);
|
||||
} else {
|
||||
parameterList.add(Constants.PARAM_TYPE_PAGER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_OTHER: {
|
||||
parameterList.add(Constants.PARAM_TYPE_VOICE);
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_CAR: {
|
||||
parameterList.add(Constants.PARAM_TYPE_CAR);
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_COMPANY_MAIN: {
|
||||
// There's no relevant field in vCard (at least 2.1).
|
||||
parameterList.add(Constants.PARAM_TYPE_WORK);
|
||||
isPrimary = true;
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_ISDN: {
|
||||
parameterList.add(Constants.PARAM_TYPE_ISDN);
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_MAIN: {
|
||||
isPrimary = true;
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_OTHER_FAX: {
|
||||
parameterList.add(Constants.PARAM_TYPE_FAX);
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_TELEX: {
|
||||
parameterList.add(Constants.PARAM_TYPE_TLX);
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_WORK_MOBILE: {
|
||||
parameterList.addAll(
|
||||
Arrays.asList(Constants.PARAM_TYPE_WORK, Constants.PARAM_TYPE_CELL));
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_WORK_PAGER: {
|
||||
parameterList.add(Constants.PARAM_TYPE_WORK);
|
||||
// See above.
|
||||
if (mIsDoCoMo) {
|
||||
parameterList.add(Constants.PARAM_TYPE_VOICE);
|
||||
} else {
|
||||
parameterList.add(Constants.PARAM_TYPE_PAGER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_MMS: {
|
||||
parameterList.add(Constants.PARAM_TYPE_MSG);
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_CUSTOM: {
|
||||
if (TextUtils.isEmpty(label)) {
|
||||
// Just ignore the custom type.
|
||||
parameterList.add(Constants.PARAM_TYPE_VOICE);
|
||||
} else if (VCardUtils.isMobilePhoneLabel(label)) {
|
||||
parameterList.add(Constants.PARAM_TYPE_CELL);
|
||||
} else {
|
||||
final String upperLabel = label.toUpperCase();
|
||||
if (VCardUtils.isValidInV21ButUnknownToContactsPhoteType(upperLabel)) {
|
||||
parameterList.add(upperLabel);
|
||||
} else if (VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
|
||||
// Note: Strictly, vCard 2.1 does not allow "X-" parameter without
|
||||
// "TYPE=" string.
|
||||
parameterList.add("X-" + label);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Phone.TYPE_RADIO:
|
||||
case Phone.TYPE_TTY_TDD:
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Phone.TYPE_RADIO:
|
||||
case Phone.TYPE_TTY_TDD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (isPrimary) {
|
||||
@@ -2069,7 +2089,7 @@ public class VCardComposer {
|
||||
}
|
||||
|
||||
if (parameterList.isEmpty()) {
|
||||
appendUncommonPhoneType(builder, typeAsPrimitive);
|
||||
appendUncommonPhoneType(builder, type);
|
||||
} else {
|
||||
appendTypeParameters(builder, parameterList);
|
||||
}
|
||||
@@ -2203,7 +2223,7 @@ public class VCardComposer {
|
||||
final String propertyName,
|
||||
final List<String> parameterList,
|
||||
final List<String> rawDataList, final boolean needCharset,
|
||||
boolean needQuotedPrintable) {
|
||||
final boolean needQuotedPrintable) {
|
||||
builder.append(propertyName);
|
||||
if (parameterList != null && parameterList.size() > 0) {
|
||||
builder.append(VCARD_PARAM_SEPARATOR);
|
||||
@@ -2223,8 +2243,10 @@ public class VCardComposer {
|
||||
builder.append(VCARD_PARAM_ENCODING_QP);
|
||||
encodedData = encodeQuotedPrintable(rawData);
|
||||
} else {
|
||||
// TODO: one line may be too huge, which may be invalid in vCard spec, though
|
||||
// several (even well-known) applications do not care this.
|
||||
// TODO: one line may be too huge, which may be invalid in vCard 3.0
|
||||
// (which says "When generating a content line, lines longer than
|
||||
// 75 characters SHOULD be folded"), though several
|
||||
// (even well-known) applications do not care this.
|
||||
encodedData = escapeCharacters(rawData);
|
||||
}
|
||||
|
||||
@@ -2305,7 +2327,7 @@ public class VCardComposer {
|
||||
}
|
||||
{
|
||||
// Replace "\n" and "\r" with "\r\n".
|
||||
StringBuilder tmpBuilder = new StringBuilder();
|
||||
final StringBuilder tmpBuilder = new StringBuilder();
|
||||
int length = str.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
char ch = str.charAt(i);
|
||||
|
||||
@@ -159,17 +159,31 @@ public class VCardConfig {
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* The flag indicating the vCard composer "for 2.1" emits "TYPE=" string every time
|
||||
* possible. The default behavior does not emit it and is valid, while adding "TYPE="
|
||||
* is also valid. In vCrad 3.0, this flag is unnecessary, since "TYPE=" is MUST in
|
||||
* vCard 3.0 specification.
|
||||
*
|
||||
* If you are targeting to some importer which cannot accept type parameters
|
||||
* without "TYPE=" string (which should be rare though), please use this flag.
|
||||
*
|
||||
* XXX: Really rare?
|
||||
*
|
||||
* e.g. int vcardType = (VCARD_TYPE_V21_GENERIC | FLAG_APPEND_TYPE_PARAM);
|
||||
* The flag indicating the vCard composer "for 2.1" emits "TYPE=" string toward TYPE params
|
||||
* every time possible. The default behavior does not emit it and is valid in the spec.
|
||||
* In vCrad 3.0, this flag is unnecessary, since "TYPE=" is MUST in vCard 3.0 specification.
|
||||
* </P>
|
||||
* <P>
|
||||
* Detail:
|
||||
* How more than one TYPE fields are expressed is different between vCard 2.1 and vCard 3.0.
|
||||
* </p>
|
||||
* <P>
|
||||
* e.g.<BR />
|
||||
* 1) Probably valid in both vCard 2.1 and vCard 3.0: "ADR;TYPE=DOM;TYPE=HOME:..."<BR />
|
||||
* 2) Valid in vCard 2.1 but not in vCard 3.0: "ADR;DOM;HOME:..."<BR />
|
||||
* 3) Valid in vCard 3.0 but not in vCard 2.1: "ADR;TYPE=DOM,HOME:..."<BR />
|
||||
* </P>
|
||||
* <P>
|
||||
* 2) had been the default of VCard exporter/importer in Android, but it is found that
|
||||
* some external exporter is not able to parse the type format like 2) but only 3).
|
||||
* </P>
|
||||
* <P>
|
||||
* If you are targeting to the importer which cannot accept TYPE params without "TYPE="
|
||||
* strings (which should be rare though), please use this flag.
|
||||
* </P>
|
||||
* <P>
|
||||
* Example usage: int vcardType = (VCARD_TYPE_V21_GENERIC | FLAG_APPEND_TYPE_PARAM);
|
||||
* </P>
|
||||
*/
|
||||
public static final int FLAG_APPEND_TYPE_PARAM = 0x04000000;
|
||||
|
||||
@@ -177,13 +191,13 @@ public class VCardConfig {
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* General vCard format with the version 2.1. Uses UTF-8 for the charset.
|
||||
* Generic vCard format with the vCard 2.1. Uses UTF-8 for the charset.
|
||||
* When composing a vCard entry, the US convension will be used toward formatting
|
||||
* some values
|
||||
* some values.
|
||||
* </P>
|
||||
* <P>
|
||||
* e.g. The order of the display name would be "Prefix Given Middle Family Suffix",
|
||||
* while it should be "Prefix Family Middle Given Suffix" in Japan.
|
||||
* while it should be "Prefix Family Middle Given Suffix" in Japan for example.
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_V21_GENERIC_UTF8 =
|
||||
@@ -197,7 +211,7 @@ public class VCardConfig {
|
||||
* General vCard format with the version 3.0. Uses UTF-8 for the charset.
|
||||
* </P>
|
||||
* <P>
|
||||
* Not ready yet. Use with caution when you use this.
|
||||
* Not fully ready yet. Use with caution when you use this.
|
||||
* </P>
|
||||
*/
|
||||
public static final int VCARD_TYPE_V30_GENERIC_UTF8 =
|
||||
@@ -220,7 +234,7 @@ public class VCardConfig {
|
||||
|
||||
/**
|
||||
* <P>
|
||||
* General vCard format with the version 3.0 with some Europe convension. Uses UTF-8
|
||||
* General vCard format with the version 3.0 with some Europe convension. Uses UTF-8.
|
||||
* </P>
|
||||
* <P>
|
||||
* Not ready yet. Use with caution when you use this.
|
||||
@@ -407,6 +421,9 @@ public class VCardConfig {
|
||||
* applied to creating "formatted" something like FORMATTED_ADDRESS.
|
||||
*/
|
||||
public static boolean isJapaneseDevice(final int vcardType) {
|
||||
// TODO: Some mask will be required so that this method wrongly interpret
|
||||
// Japanese"-like" vCard type.
|
||||
// e.g. VCARD_TYPE_V21_JAPANESE_SJIS | FLAG_APPEND_TYPE_PARAMS
|
||||
return sJapaneseMobileTypeSet.contains(vcardType);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,8 +54,11 @@ import java.util.Map;
|
||||
/**
|
||||
* This class bridges between data structure of Contact app and VCard data.
|
||||
*/
|
||||
public class ContactStruct {
|
||||
private static final String LOG_TAG = "vcard.ContactStruct";
|
||||
public class VCardEntry {
|
||||
private static final String LOG_TAG = "VCardEntry";
|
||||
|
||||
private static final String ACCOUNT_TYPE_GOOGLE = "com.google";
|
||||
private static final String GOOGLE_MY_CONTACTS_GROUP = "System Group: My Contacts";
|
||||
|
||||
// Key: the name shown in VCard. e.g. "X-AIM", "X-ICQ"
|
||||
// Value: the result of {@link Contacts.ContactMethods#encodePredefinedImProtocol}
|
||||
@@ -72,7 +75,7 @@ public class ContactStruct {
|
||||
sImMap.put(Constants.ImportOnly.PROPERTY_X_GOOGLE_TALK_WITH_SPACE,
|
||||
Im.PROTOCOL_GOOGLE_TALK);
|
||||
}
|
||||
|
||||
|
||||
static public class PhoneData {
|
||||
public final int type;
|
||||
public final String data;
|
||||
@@ -448,15 +451,15 @@ public class ContactStruct {
|
||||
private final int mVCardType;
|
||||
private final Account mAccount;
|
||||
|
||||
public ContactStruct() {
|
||||
public VCardEntry() {
|
||||
this(VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||
}
|
||||
|
||||
public ContactStruct(int vcardType) {
|
||||
public VCardEntry(int vcardType) {
|
||||
this(vcardType, null);
|
||||
}
|
||||
|
||||
public ContactStruct(int vcardType, Account account) {
|
||||
public VCardEntry(int vcardType, Account account) {
|
||||
mVCardType = vcardType;
|
||||
mAccount = account;
|
||||
}
|
||||
@@ -921,16 +924,14 @@ public class ContactStruct {
|
||||
} else if (propName.equals(Constants.PROPERTY_X_SKYPE_PSTNNUMBER)) {
|
||||
// The phone number available via Skype.
|
||||
Collection<String> typeCollection = paramMap.get(Constants.PARAM_TYPE);
|
||||
// XXX: should use TYPE_CUSTOM + the label "Skype"? (which may need localization)
|
||||
int type = Phone.TYPE_OTHER;
|
||||
final String label = null;
|
||||
final int type = Phone.TYPE_OTHER;
|
||||
final boolean isPrimary;
|
||||
if (typeCollection != null && typeCollection.contains(Constants.PARAM_TYPE_PREF)) {
|
||||
isPrimary = true;
|
||||
} else {
|
||||
isPrimary = false;
|
||||
}
|
||||
addPhone(type, propValue, label, isPrimary);
|
||||
addPhone(type, propValue, null, isPrimary);
|
||||
} else if (sImMap.containsKey(propName)) {
|
||||
final int protocol = sImMap.get(propName);
|
||||
boolean isPrimary = false;
|
||||
@@ -1045,10 +1046,6 @@ public class ContactStruct {
|
||||
}
|
||||
}
|
||||
|
||||
// From GoogleSource.java in Contacts app.
|
||||
private static final String ACCOUNT_TYPE_GOOGLE = "com.google";
|
||||
private static final String GOOGLE_MY_CONTACTS_GROUP = "System Group: My Contacts";
|
||||
|
||||
public void pushIntoContentResolver(ContentResolver resolver) {
|
||||
ArrayList<ContentProviderOperation> operationList =
|
||||
new ArrayList<ContentProviderOperation>();
|
||||
@@ -1060,7 +1057,6 @@ public class ContactStruct {
|
||||
builder.withValue(RawContacts.ACCOUNT_TYPE, mAccount.type);
|
||||
|
||||
// Assume that caller side creates this group if it does not exist.
|
||||
// TODO: refactor this code along with the change in GoogleSource.java
|
||||
if (ACCOUNT_TYPE_GOOGLE.equals(mAccount.type)) {
|
||||
final Cursor cursor = resolver.query(Groups.CONTENT_URI, new String[] {
|
||||
Groups.SOURCE_ID },
|
||||
@@ -1293,11 +1289,11 @@ public class ContactStruct {
|
||||
}
|
||||
}
|
||||
|
||||
public static ContactStruct buildFromResolver(ContentResolver resolver) {
|
||||
public static VCardEntry buildFromResolver(ContentResolver resolver) {
|
||||
return buildFromResolver(resolver, Contacts.CONTENT_URI);
|
||||
}
|
||||
|
||||
public static ContactStruct buildFromResolver(ContentResolver resolver, Uri uri) {
|
||||
public static VCardEntry buildFromResolver(ContentResolver resolver, Uri uri) {
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -19,28 +19,33 @@ import android.content.ContentResolver;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* EntryHandler implementation which commits the entry to Contacts Provider
|
||||
* EntryHandler implementation which commits the entry to ContentResolver.
|
||||
*
|
||||
* Note:
|
||||
* Each vCard may contain big photo images encoded by BASE64,
|
||||
* If we store all vCard entries in memory, OutOfMemoryError may be thrown.
|
||||
* Thus, this class push each VCard entry into ContentResolver immediately.
|
||||
*/
|
||||
public class EntryCommitter implements EntryHandler {
|
||||
public class VCardEntryCommitter implements VCardEntryHandler {
|
||||
public static String LOG_TAG = "vcard.EntryComitter";
|
||||
|
||||
private ContentResolver mContentResolver;
|
||||
private long mTimeToCommit;
|
||||
|
||||
public EntryCommitter(ContentResolver resolver) {
|
||||
public VCardEntryCommitter(ContentResolver resolver) {
|
||||
mContentResolver = resolver;
|
||||
}
|
||||
|
||||
public void onParsingStart() {
|
||||
public void onStart() {
|
||||
}
|
||||
|
||||
public void onParsingEnd() {
|
||||
public void onEnd() {
|
||||
if (VCardConfig.showPerformanceLog()) {
|
||||
Log.d(LOG_TAG, String.format("time to commit entries: %d ms", mTimeToCommit));
|
||||
}
|
||||
}
|
||||
|
||||
public void onEntryCreated(final ContactStruct contactStruct) {
|
||||
public void onEntryCreated(final VCardEntry contactStruct) {
|
||||
long start = System.currentTimeMillis();
|
||||
contactStruct.pushIntoContentResolver(mContentResolver);
|
||||
mTimeToCommit += System.currentTimeMillis() - start;
|
||||
@@ -30,23 +30,17 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* VBuilder for VCard. VCard may contain big photo images encoded by BASE64,
|
||||
* If we store all VNode entries in memory like VDataBuilder.java,
|
||||
* OutOfMemoryError may be thrown. Thus, this class push each VCard entry into
|
||||
* ContentResolver immediately.
|
||||
*/
|
||||
public class VCardDataBuilder implements VCardBuilder {
|
||||
static private String LOG_TAG = "VCardDataBuilder";
|
||||
public class VCardEntryConstructor implements VCardInterpreter {
|
||||
private static String LOG_TAG = "VCardEntryConstructor";
|
||||
|
||||
/**
|
||||
* If there's no other information available, this class uses this charset for encoding
|
||||
* byte arrays.
|
||||
*/
|
||||
static public String TARGET_CHARSET = "UTF-8";
|
||||
|
||||
private ContactStruct.Property mCurrentProperty = new ContactStruct.Property();
|
||||
private ContactStruct mCurrentContactStruct;
|
||||
|
||||
private VCardEntry.Property mCurrentProperty = new VCardEntry.Property();
|
||||
private VCardEntry mCurrentContactStruct;
|
||||
private String mParamType;
|
||||
|
||||
/**
|
||||
@@ -66,23 +60,20 @@ public class VCardDataBuilder implements VCardBuilder {
|
||||
// Just for testing.
|
||||
private long mTimePushIntoContentResolver;
|
||||
|
||||
private List<EntryHandler> mEntryHandlers = new ArrayList<EntryHandler>();
|
||||
private List<VCardEntryHandler> mEntryHandlers = new ArrayList<VCardEntryHandler>();
|
||||
|
||||
public VCardDataBuilder() {
|
||||
public VCardEntryConstructor() {
|
||||
this(null, null, false, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public VCardDataBuilder(int vcardType) {
|
||||
public VCardEntryConstructor(int vcardType) {
|
||||
this(null, null, false, vcardType, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public VCardDataBuilder(String charset,
|
||||
public VCardEntryConstructor(String charset,
|
||||
boolean strictLineBreakParsing, int vcardType, Account account) {
|
||||
this(null, charset, strictLineBreakParsing, vcardType, account);
|
||||
}
|
||||
@@ -90,7 +81,7 @@ public class VCardDataBuilder implements VCardBuilder {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public VCardDataBuilder(String sourceCharset,
|
||||
public VCardEntryConstructor(String sourceCharset,
|
||||
String targetCharset,
|
||||
boolean strictLineBreakParsing,
|
||||
int vcardType,
|
||||
@@ -109,20 +100,20 @@ public class VCardDataBuilder implements VCardBuilder {
|
||||
mVCardType = vcardType;
|
||||
mAccount = account;
|
||||
}
|
||||
|
||||
public void addEntryHandler(EntryHandler entryHandler) {
|
||||
|
||||
public void addEntryHandler(VCardEntryHandler entryHandler) {
|
||||
mEntryHandlers.add(entryHandler);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
for (EntryHandler entryHandler : mEntryHandlers) {
|
||||
entryHandler.onParsingStart();
|
||||
for (VCardEntryHandler entryHandler : mEntryHandlers) {
|
||||
entryHandler.onStart();
|
||||
}
|
||||
}
|
||||
|
||||
public void end() {
|
||||
for (EntryHandler entryHandler : mEntryHandlers) {
|
||||
entryHandler.onParsingEnd();
|
||||
for (VCardEntryHandler entryHandler : mEntryHandlers) {
|
||||
entryHandler.onEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +126,7 @@ public class VCardDataBuilder implements VCardBuilder {
|
||||
*/
|
||||
public void clear() {
|
||||
mCurrentContactStruct = null;
|
||||
mCurrentProperty = new ContactStruct.Property();
|
||||
mCurrentProperty = new VCardEntry.Property();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,12 +144,12 @@ public class VCardDataBuilder implements VCardBuilder {
|
||||
Log.e(LOG_TAG, "This is not VCARD!");
|
||||
}
|
||||
|
||||
mCurrentContactStruct = new ContactStruct(mVCardType, mAccount);
|
||||
mCurrentContactStruct = new VCardEntry(mVCardType, mAccount);
|
||||
}
|
||||
|
||||
public void endRecord() {
|
||||
mCurrentContactStruct.consolidateFields();
|
||||
for (EntryHandler entryHandler : mEntryHandlers) {
|
||||
for (VCardEntryHandler entryHandler : mEntryHandlers) {
|
||||
entryHandler.onEntryCreated(mCurrentContactStruct);
|
||||
}
|
||||
mCurrentContactStruct = null;
|
||||
@@ -17,16 +17,16 @@ package android.pim.vcard;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VCardEntryCounter implements VCardBuilder {
|
||||
public class VCardEntryCounter implements VCardInterpreter {
|
||||
private int mCount;
|
||||
|
||||
|
||||
public int getCount() {
|
||||
return mCount;
|
||||
}
|
||||
|
||||
|
||||
public void start() {
|
||||
}
|
||||
|
||||
|
||||
public void end() {
|
||||
}
|
||||
|
||||
@@ -36,10 +36,10 @@ public class VCardEntryCounter implements VCardBuilder {
|
||||
public void endRecord() {
|
||||
mCount++;
|
||||
}
|
||||
|
||||
|
||||
public void startProperty() {
|
||||
}
|
||||
|
||||
|
||||
public void endProperty() {
|
||||
}
|
||||
|
||||
|
||||
@@ -15,24 +15,20 @@
|
||||
*/
|
||||
package android.pim.vcard;
|
||||
|
||||
/**
|
||||
* Unlike {@link VCardBuilder}, this (and {@link VCardDataBuilder}) assumes
|
||||
* "each VCard entry should be correctly parsed and passed to each EntryHandler object",
|
||||
*/
|
||||
public interface EntryHandler {
|
||||
public interface VCardEntryHandler {
|
||||
/**
|
||||
* Called when the parsing started.
|
||||
*/
|
||||
public void onParsingStart();
|
||||
public void onStart();
|
||||
|
||||
/**
|
||||
* The method called when one VCard entry is successfully created
|
||||
*/
|
||||
public void onEntryCreated(final ContactStruct entry);
|
||||
public void onEntryCreated(final VCardEntry entry);
|
||||
|
||||
/**
|
||||
* Called when the parsing ended.
|
||||
* Able to be use this method for showing performance log, etc.
|
||||
*/
|
||||
public void onParsingEnd();
|
||||
public void onEnd();
|
||||
}
|
||||
@@ -18,81 +18,81 @@ package android.pim.vcard;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class VCardBuilderCollection implements VCardBuilder {
|
||||
public class VCardInterPreterCollection implements VCardInterpreter {
|
||||
|
||||
private final Collection<VCardBuilder> mVCardBuilderCollection;
|
||||
private final Collection<VCardInterpreter> mVCardBuilderCollection;
|
||||
|
||||
public VCardBuilderCollection(Collection<VCardBuilder> vBuilderCollection) {
|
||||
public VCardInterPreterCollection(Collection<VCardInterpreter> vBuilderCollection) {
|
||||
mVCardBuilderCollection = vBuilderCollection;
|
||||
}
|
||||
|
||||
public Collection<VCardBuilder> getVCardBuilderBaseCollection() {
|
||||
public Collection<VCardInterpreter> getCollection() {
|
||||
return mVCardBuilderCollection;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
for (VCardBuilder builder : mVCardBuilderCollection) {
|
||||
for (VCardInterpreter builder : mVCardBuilderCollection) {
|
||||
builder.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void end() {
|
||||
for (VCardBuilder builder : mVCardBuilderCollection) {
|
||||
for (VCardInterpreter builder : mVCardBuilderCollection) {
|
||||
builder.end();
|
||||
}
|
||||
}
|
||||
|
||||
public void startRecord(String type) {
|
||||
for (VCardBuilder builder : mVCardBuilderCollection) {
|
||||
for (VCardInterpreter builder : mVCardBuilderCollection) {
|
||||
builder.startRecord(type);
|
||||
}
|
||||
}
|
||||
|
||||
public void endRecord() {
|
||||
for (VCardBuilder builder : mVCardBuilderCollection) {
|
||||
for (VCardInterpreter builder : mVCardBuilderCollection) {
|
||||
builder.endRecord();
|
||||
}
|
||||
}
|
||||
|
||||
public void startProperty() {
|
||||
for (VCardBuilder builder : mVCardBuilderCollection) {
|
||||
for (VCardInterpreter builder : mVCardBuilderCollection) {
|
||||
builder.startProperty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void endProperty() {
|
||||
for (VCardBuilder builder : mVCardBuilderCollection) {
|
||||
for (VCardInterpreter builder : mVCardBuilderCollection) {
|
||||
builder.endProperty();
|
||||
}
|
||||
}
|
||||
|
||||
public void propertyGroup(String group) {
|
||||
for (VCardBuilder builder : mVCardBuilderCollection) {
|
||||
for (VCardInterpreter builder : mVCardBuilderCollection) {
|
||||
builder.propertyGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
public void propertyName(String name) {
|
||||
for (VCardBuilder builder : mVCardBuilderCollection) {
|
||||
for (VCardInterpreter builder : mVCardBuilderCollection) {
|
||||
builder.propertyName(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void propertyParamType(String type) {
|
||||
for (VCardBuilder builder : mVCardBuilderCollection) {
|
||||
for (VCardInterpreter builder : mVCardBuilderCollection) {
|
||||
builder.propertyParamType(type);
|
||||
}
|
||||
}
|
||||
|
||||
public void propertyParamValue(String value) {
|
||||
for (VCardBuilder builder : mVCardBuilderCollection) {
|
||||
for (VCardInterpreter builder : mVCardBuilderCollection) {
|
||||
builder.propertyParamValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void propertyValues(List<String> values) {
|
||||
for (VCardBuilder builder : mVCardBuilderCollection) {
|
||||
for (VCardInterpreter builder : mVCardBuilderCollection) {
|
||||
builder.propertyValues(values);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ package android.pim.vcard;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface VCardBuilder {
|
||||
public interface VCardInterpreter {
|
||||
void start();
|
||||
|
||||
void end();
|
||||
@@ -27,7 +27,7 @@ public interface VCardBuilder {
|
||||
*/
|
||||
void startRecord(String type);
|
||||
|
||||
/** END:VXX */
|
||||
/** END:VCARD */
|
||||
void endRecord();
|
||||
|
||||
void startProperty();
|
||||
@@ -64,7 +64,7 @@ public abstract class VCardParser {
|
||||
* @return Returns true for success. Otherwise returns false.
|
||||
* @throws IOException, VCardException
|
||||
*/
|
||||
public abstract boolean parse(InputStream is, VCardBuilder builder)
|
||||
public abstract boolean parse(InputStream is, VCardInterpreter builder)
|
||||
throws IOException, VCardException;
|
||||
|
||||
/**
|
||||
@@ -82,7 +82,7 @@ public abstract class VCardParser {
|
||||
* @return Returns true when successful. Otherwise returns false.
|
||||
* @throws IOException, VCardException
|
||||
*/
|
||||
public abstract boolean parse(InputStream is, String charset, VCardBuilder builder)
|
||||
public abstract boolean parse(InputStream is, String charset, VCardInterpreter builder)
|
||||
throws IOException, VCardException;
|
||||
|
||||
/**
|
||||
@@ -91,7 +91,7 @@ public abstract class VCardParser {
|
||||
* @hide
|
||||
*/
|
||||
public abstract void parse(InputStream is, String charset,
|
||||
VCardBuilder builder, boolean canceled)
|
||||
VCardInterpreter builder, boolean canceled)
|
||||
throws IOException, VCardException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -72,7 +72,7 @@ public class VCardParser_V21 extends VCardParser {
|
||||
private String mPreviousLine;
|
||||
|
||||
/** The builder to build parsed data */
|
||||
protected VCardBuilder mBuilder = null;
|
||||
protected VCardInterpreter mBuilder = null;
|
||||
|
||||
/**
|
||||
* The encoding type. "Encoding" in vCard is different from "Charset".
|
||||
@@ -876,13 +876,13 @@ public class VCardParser_V21 extends VCardParser {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(final InputStream is, final VCardBuilder builder)
|
||||
public boolean parse(final InputStream is, final VCardInterpreter builder)
|
||||
throws IOException, VCardException {
|
||||
return parse(is, VCardConfig.DEFAULT_CHARSET, builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean parse(InputStream is, String charset, VCardBuilder builder)
|
||||
public boolean parse(InputStream is, String charset, VCardInterpreter builder)
|
||||
throws IOException, VCardException {
|
||||
if (charset == null) {
|
||||
charset = VCardConfig.DEFAULT_CHARSET;
|
||||
@@ -914,7 +914,7 @@ public class VCardParser_V21 extends VCardParser {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parse(InputStream is, String charset, VCardBuilder builder, boolean canceled)
|
||||
public void parse(InputStream is, String charset, VCardInterpreter builder, boolean canceled)
|
||||
throws IOException, VCardException {
|
||||
mCanceled = canceled;
|
||||
parse(is, charset, builder);
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.Set;
|
||||
* Currently this implementation is very premature.
|
||||
* @hide
|
||||
*/
|
||||
public class VCardSourceDetector implements VCardBuilder {
|
||||
public class VCardSourceDetector implements VCardInterpreter {
|
||||
// Should only be used in package.
|
||||
static final int TYPE_UNKNOWN = 0;
|
||||
static final int TYPE_APPLE = 1;
|
||||
|
||||
@@ -23,9 +23,9 @@ import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
|
||||
import android.telephony.PhoneNumberUtils;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -37,19 +37,14 @@ import java.util.Set;
|
||||
* Utilities for VCard handling codes.
|
||||
*/
|
||||
public class VCardUtils {
|
||||
/*
|
||||
* TODO: some of methods in this class should be placed to the more appropriate place...
|
||||
*/
|
||||
|
||||
// Note that not all types are included in this map/set, since, for example, TYPE_HOME_FAX is
|
||||
// converted to two parameter Strings. These only contain some minor fields valid in both
|
||||
// vCard and current (as of 2009-08-07) Contacts structure.
|
||||
private static final Map<Integer, String> sKnownPhoneTypesMap_ItoS;
|
||||
private static final Set<String> sPhoneTypesSetUnknownToContacts;
|
||||
|
||||
private static final Set<String> sPhoneTypesUnknownToContactsSet;
|
||||
private static final Map<String, Integer> sKnownPhoneTypeMap_StoI;
|
||||
|
||||
private static final Map<Integer, String> sKnownImPropNameMap_ItoS;
|
||||
private static final Set<String> sMobilePhoneLabelSet;
|
||||
|
||||
static {
|
||||
sKnownPhoneTypesMap_ItoS = new HashMap<Integer, String>();
|
||||
@@ -75,10 +70,10 @@ public class VCardUtils {
|
||||
sKnownPhoneTypeMap_StoI.put(Constants.PARAM_PHONE_EXTRA_TYPE_ASSISTANT,
|
||||
Phone.TYPE_ASSISTANT);
|
||||
|
||||
sPhoneTypesSetUnknownToContacts = new HashSet<String>();
|
||||
sPhoneTypesSetUnknownToContacts.add(Constants.PARAM_TYPE_MODEM);
|
||||
sPhoneTypesSetUnknownToContacts.add(Constants.PARAM_TYPE_BBS);
|
||||
sPhoneTypesSetUnknownToContacts.add(Constants.PARAM_TYPE_VIDEO);
|
||||
sPhoneTypesUnknownToContactsSet = new HashSet<String>();
|
||||
sPhoneTypesUnknownToContactsSet.add(Constants.PARAM_TYPE_MODEM);
|
||||
sPhoneTypesUnknownToContactsSet.add(Constants.PARAM_TYPE_BBS);
|
||||
sPhoneTypesUnknownToContactsSet.add(Constants.PARAM_TYPE_VIDEO);
|
||||
|
||||
sKnownImPropNameMap_ItoS = new HashMap<Integer, String>();
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_AIM, Constants.PROPERTY_X_AIM);
|
||||
@@ -90,6 +85,14 @@ public class VCardUtils {
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_JABBER, Constants.PROPERTY_X_JABBER);
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_QQ, Constants.PROPERTY_X_QQ);
|
||||
sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_NETMEETING, Constants.PROPERTY_X_NETMEETING);
|
||||
|
||||
// \u643A\u5E2F\u96FB\u8A71 = Full-width Hiragana "Keitai-Denwa" (mobile phone)
|
||||
// \u643A\u5E2F = Full-width Hiragana "Keitai" (mobile phone)
|
||||
// \u30B1\u30A4\u30BF\u30A4 = Full-width Katakana "Keitai" (mobile phone)
|
||||
// \uFF79\uFF72\uFF80\uFF72 = Half-width Katakana "Keitai" (mobile phone)
|
||||
sMobilePhoneLabelSet = new HashSet<String>(Arrays.asList(
|
||||
"MOBILE", "\u643A\u5E2F\u96FB\u8A71", "\u643A\u5E2F", "\u30B1\u30A4\u30BF\u30A4",
|
||||
"\uFF79\uFF72\uFF80\uFF72"));
|
||||
}
|
||||
|
||||
public static String getPhoneTypeString(Integer type) {
|
||||
@@ -112,7 +115,10 @@ public class VCardUtils {
|
||||
|
||||
if (types != null) {
|
||||
for (String typeString : types) {
|
||||
typeString = typeString.toUpperCase();
|
||||
if (typeString == null) {
|
||||
continue;
|
||||
}
|
||||
typeString = typeString.toUpperCase();
|
||||
if (typeString.equals(Constants.PARAM_TYPE_PREF)) {
|
||||
hasPref = true;
|
||||
} else if (typeString.equals(Constants.PARAM_TYPE_FAX)) {
|
||||
@@ -121,7 +127,10 @@ public class VCardUtils {
|
||||
if (typeString.startsWith("X-") && type < 0) {
|
||||
typeString = typeString.substring(2);
|
||||
}
|
||||
Integer tmp = sKnownPhoneTypeMap_StoI.get(typeString);
|
||||
if (typeString.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
final Integer tmp = sKnownPhoneTypeMap_StoI.get(typeString);
|
||||
if (tmp != null) {
|
||||
final int typeCandidate = tmp;
|
||||
// TYPE_PAGER is prefered when the number contains @ surronded by
|
||||
@@ -168,20 +177,23 @@ public class VCardUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getPropertyNameForIm(int protocol) {
|
||||
@SuppressWarnings("deprecation")
|
||||
public static boolean isMobilePhoneLabel(final String label) {
|
||||
// For backward compatibility.
|
||||
// Detail: Until Donut, there isn't TYPE_MOBILE for email while there is now.
|
||||
// To support mobile type at that time, this custom label had been used.
|
||||
return (android.provider.Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME.equals(label)
|
||||
|| sMobilePhoneLabelSet.contains(label));
|
||||
}
|
||||
|
||||
public static boolean isValidInV21ButUnknownToContactsPhoteType(final String label) {
|
||||
return sPhoneTypesUnknownToContactsSet.contains(label);
|
||||
}
|
||||
|
||||
public static String getPropertyNameForIm(final int protocol) {
|
||||
return sKnownImPropNameMap_ItoS.get(protocol);
|
||||
}
|
||||
|
||||
public static boolean isValidPhoneType(String phoneType, int vcardType) {
|
||||
// TODO: check the following.
|
||||
// - it may violate vCard spec
|
||||
// - it may contain non-ASCII characters
|
||||
//
|
||||
// TODO: use vcardType
|
||||
return (phoneType.startsWith("X-") || phoneType.startsWith("x-") ||
|
||||
sPhoneTypesSetUnknownToContacts.contains(phoneType));
|
||||
}
|
||||
|
||||
public static String[] sortNameElements(final int vcardType,
|
||||
final String familyName, final String middleName, final String givenName) {
|
||||
final String[] list = new String[3];
|
||||
@@ -233,7 +245,7 @@ public class VCardUtils {
|
||||
*/
|
||||
public static void insertStructuredPostalDataUsingContactsStruct(int vcardType,
|
||||
final ContentProviderOperation.Builder builder,
|
||||
final ContactStruct.PostalData postalData) {
|
||||
final VCardEntry.PostalData postalData) {
|
||||
builder.withValueBackReference(StructuredPostal.RAW_CONTACT_ID, 0);
|
||||
builder.withValue(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
|
||||
|
||||
@@ -269,7 +281,7 @@ public class VCardUtils {
|
||||
* So some conversion may be performed in this method. See also
|
||||
* {{@link #insertStructuredPostalDataUsingContactsStruct(int,
|
||||
* android.content.ContentProviderOperation.Builder,
|
||||
* android.pim.vcard.ContactStruct.PostalData)}
|
||||
* android.pim.vcard.VCardEntry.PostalData)}
|
||||
*/
|
||||
public static String[] getVCardPostalElements(ContentValues contentValues) {
|
||||
// adr-value = 0*6(text-value ";") text-value
|
||||
@@ -517,364 +529,3 @@ public class VCardUtils {
|
||||
private VCardUtils() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TextUtils especially for Japanese.
|
||||
* TODO: make this in android.text in the future
|
||||
*/
|
||||
class JapaneseUtils {
|
||||
static private final Map<Character, String> sHalfWidthMap =
|
||||
new HashMap<Character, String>();
|
||||
|
||||
static {
|
||||
// There's no logical mapping rule in Unicode. Sigh.
|
||||
sHalfWidthMap.put('\u3001', "\uFF64");
|
||||
sHalfWidthMap.put('\u3002', "\uFF61");
|
||||
sHalfWidthMap.put('\u300C', "\uFF62");
|
||||
sHalfWidthMap.put('\u300D', "\uFF63");
|
||||
sHalfWidthMap.put('\u301C', "~");
|
||||
sHalfWidthMap.put('\u3041', "\uFF67");
|
||||
sHalfWidthMap.put('\u3042', "\uFF71");
|
||||
sHalfWidthMap.put('\u3043', "\uFF68");
|
||||
sHalfWidthMap.put('\u3044', "\uFF72");
|
||||
sHalfWidthMap.put('\u3045', "\uFF69");
|
||||
sHalfWidthMap.put('\u3046', "\uFF73");
|
||||
sHalfWidthMap.put('\u3047', "\uFF6A");
|
||||
sHalfWidthMap.put('\u3048', "\uFF74");
|
||||
sHalfWidthMap.put('\u3049', "\uFF6B");
|
||||
sHalfWidthMap.put('\u304A', "\uFF75");
|
||||
sHalfWidthMap.put('\u304B', "\uFF76");
|
||||
sHalfWidthMap.put('\u304C', "\uFF76\uFF9E");
|
||||
sHalfWidthMap.put('\u304D', "\uFF77");
|
||||
sHalfWidthMap.put('\u304E', "\uFF77\uFF9E");
|
||||
sHalfWidthMap.put('\u304F', "\uFF78");
|
||||
sHalfWidthMap.put('\u3050', "\uFF78\uFF9E");
|
||||
sHalfWidthMap.put('\u3051', "\uFF79");
|
||||
sHalfWidthMap.put('\u3052', "\uFF79\uFF9E");
|
||||
sHalfWidthMap.put('\u3053', "\uFF7A");
|
||||
sHalfWidthMap.put('\u3054', "\uFF7A\uFF9E");
|
||||
sHalfWidthMap.put('\u3055', "\uFF7B");
|
||||
sHalfWidthMap.put('\u3056', "\uFF7B\uFF9E");
|
||||
sHalfWidthMap.put('\u3057', "\uFF7C");
|
||||
sHalfWidthMap.put('\u3058', "\uFF7C\uFF9E");
|
||||
sHalfWidthMap.put('\u3059', "\uFF7D");
|
||||
sHalfWidthMap.put('\u305A', "\uFF7D\uFF9E");
|
||||
sHalfWidthMap.put('\u305B', "\uFF7E");
|
||||
sHalfWidthMap.put('\u305C', "\uFF7E\uFF9E");
|
||||
sHalfWidthMap.put('\u305D', "\uFF7F");
|
||||
sHalfWidthMap.put('\u305E', "\uFF7F\uFF9E");
|
||||
sHalfWidthMap.put('\u305F', "\uFF80");
|
||||
sHalfWidthMap.put('\u3060', "\uFF80\uFF9E");
|
||||
sHalfWidthMap.put('\u3061', "\uFF81");
|
||||
sHalfWidthMap.put('\u3062', "\uFF81\uFF9E");
|
||||
sHalfWidthMap.put('\u3063', "\uFF6F");
|
||||
sHalfWidthMap.put('\u3064', "\uFF82");
|
||||
sHalfWidthMap.put('\u3065', "\uFF82\uFF9E");
|
||||
sHalfWidthMap.put('\u3066', "\uFF83");
|
||||
sHalfWidthMap.put('\u3067', "\uFF83\uFF9E");
|
||||
sHalfWidthMap.put('\u3068', "\uFF84");
|
||||
sHalfWidthMap.put('\u3069', "\uFF84\uFF9E");
|
||||
sHalfWidthMap.put('\u306A', "\uFF85");
|
||||
sHalfWidthMap.put('\u306B', "\uFF86");
|
||||
sHalfWidthMap.put('\u306C', "\uFF87");
|
||||
sHalfWidthMap.put('\u306D', "\uFF88");
|
||||
sHalfWidthMap.put('\u306E', "\uFF89");
|
||||
sHalfWidthMap.put('\u306F', "\uFF8A");
|
||||
sHalfWidthMap.put('\u3070', "\uFF8A\uFF9E");
|
||||
sHalfWidthMap.put('\u3071', "\uFF8A\uFF9F");
|
||||
sHalfWidthMap.put('\u3072', "\uFF8B");
|
||||
sHalfWidthMap.put('\u3073', "\uFF8B\uFF9E");
|
||||
sHalfWidthMap.put('\u3074', "\uFF8B\uFF9F");
|
||||
sHalfWidthMap.put('\u3075', "\uFF8C");
|
||||
sHalfWidthMap.put('\u3076', "\uFF8C\uFF9E");
|
||||
sHalfWidthMap.put('\u3077', "\uFF8C\uFF9F");
|
||||
sHalfWidthMap.put('\u3078', "\uFF8D");
|
||||
sHalfWidthMap.put('\u3079', "\uFF8D\uFF9E");
|
||||
sHalfWidthMap.put('\u307A', "\uFF8D\uFF9F");
|
||||
sHalfWidthMap.put('\u307B', "\uFF8E");
|
||||
sHalfWidthMap.put('\u307C', "\uFF8E\uFF9E");
|
||||
sHalfWidthMap.put('\u307D', "\uFF8E\uFF9F");
|
||||
sHalfWidthMap.put('\u307E', "\uFF8F");
|
||||
sHalfWidthMap.put('\u307F', "\uFF90");
|
||||
sHalfWidthMap.put('\u3080', "\uFF91");
|
||||
sHalfWidthMap.put('\u3081', "\uFF92");
|
||||
sHalfWidthMap.put('\u3082', "\uFF93");
|
||||
sHalfWidthMap.put('\u3083', "\uFF6C");
|
||||
sHalfWidthMap.put('\u3084', "\uFF94");
|
||||
sHalfWidthMap.put('\u3085', "\uFF6D");
|
||||
sHalfWidthMap.put('\u3086', "\uFF95");
|
||||
sHalfWidthMap.put('\u3087', "\uFF6E");
|
||||
sHalfWidthMap.put('\u3088', "\uFF96");
|
||||
sHalfWidthMap.put('\u3089', "\uFF97");
|
||||
sHalfWidthMap.put('\u308A', "\uFF98");
|
||||
sHalfWidthMap.put('\u308B', "\uFF99");
|
||||
sHalfWidthMap.put('\u308C', "\uFF9A");
|
||||
sHalfWidthMap.put('\u308D', "\uFF9B");
|
||||
sHalfWidthMap.put('\u308E', "\uFF9C");
|
||||
sHalfWidthMap.put('\u308F', "\uFF9C");
|
||||
sHalfWidthMap.put('\u3090', "\uFF72");
|
||||
sHalfWidthMap.put('\u3091', "\uFF74");
|
||||
sHalfWidthMap.put('\u3092', "\uFF66");
|
||||
sHalfWidthMap.put('\u3093', "\uFF9D");
|
||||
sHalfWidthMap.put('\u309B', "\uFF9E");
|
||||
sHalfWidthMap.put('\u309C', "\uFF9F");
|
||||
sHalfWidthMap.put('\u30A1', "\uFF67");
|
||||
sHalfWidthMap.put('\u30A2', "\uFF71");
|
||||
sHalfWidthMap.put('\u30A3', "\uFF68");
|
||||
sHalfWidthMap.put('\u30A4', "\uFF72");
|
||||
sHalfWidthMap.put('\u30A5', "\uFF69");
|
||||
sHalfWidthMap.put('\u30A6', "\uFF73");
|
||||
sHalfWidthMap.put('\u30A7', "\uFF6A");
|
||||
sHalfWidthMap.put('\u30A8', "\uFF74");
|
||||
sHalfWidthMap.put('\u30A9', "\uFF6B");
|
||||
sHalfWidthMap.put('\u30AA', "\uFF75");
|
||||
sHalfWidthMap.put('\u30AB', "\uFF76");
|
||||
sHalfWidthMap.put('\u30AC', "\uFF76\uFF9E");
|
||||
sHalfWidthMap.put('\u30AD', "\uFF77");
|
||||
sHalfWidthMap.put('\u30AE', "\uFF77\uFF9E");
|
||||
sHalfWidthMap.put('\u30AF', "\uFF78");
|
||||
sHalfWidthMap.put('\u30B0', "\uFF78\uFF9E");
|
||||
sHalfWidthMap.put('\u30B1', "\uFF79");
|
||||
sHalfWidthMap.put('\u30B2', "\uFF79\uFF9E");
|
||||
sHalfWidthMap.put('\u30B3', "\uFF7A");
|
||||
sHalfWidthMap.put('\u30B4', "\uFF7A\uFF9E");
|
||||
sHalfWidthMap.put('\u30B5', "\uFF7B");
|
||||
sHalfWidthMap.put('\u30B6', "\uFF7B\uFF9E");
|
||||
sHalfWidthMap.put('\u30B7', "\uFF7C");
|
||||
sHalfWidthMap.put('\u30B8', "\uFF7C\uFF9E");
|
||||
sHalfWidthMap.put('\u30B9', "\uFF7D");
|
||||
sHalfWidthMap.put('\u30BA', "\uFF7D\uFF9E");
|
||||
sHalfWidthMap.put('\u30BB', "\uFF7E");
|
||||
sHalfWidthMap.put('\u30BC', "\uFF7E\uFF9E");
|
||||
sHalfWidthMap.put('\u30BD', "\uFF7F");
|
||||
sHalfWidthMap.put('\u30BE', "\uFF7F\uFF9E");
|
||||
sHalfWidthMap.put('\u30BF', "\uFF80");
|
||||
sHalfWidthMap.put('\u30C0', "\uFF80\uFF9E");
|
||||
sHalfWidthMap.put('\u30C1', "\uFF81");
|
||||
sHalfWidthMap.put('\u30C2', "\uFF81\uFF9E");
|
||||
sHalfWidthMap.put('\u30C3', "\uFF6F");
|
||||
sHalfWidthMap.put('\u30C4', "\uFF82");
|
||||
sHalfWidthMap.put('\u30C5', "\uFF82\uFF9E");
|
||||
sHalfWidthMap.put('\u30C6', "\uFF83");
|
||||
sHalfWidthMap.put('\u30C7', "\uFF83\uFF9E");
|
||||
sHalfWidthMap.put('\u30C8', "\uFF84");
|
||||
sHalfWidthMap.put('\u30C9', "\uFF84\uFF9E");
|
||||
sHalfWidthMap.put('\u30CA', "\uFF85");
|
||||
sHalfWidthMap.put('\u30CB', "\uFF86");
|
||||
sHalfWidthMap.put('\u30CC', "\uFF87");
|
||||
sHalfWidthMap.put('\u30CD', "\uFF88");
|
||||
sHalfWidthMap.put('\u30CE', "\uFF89");
|
||||
sHalfWidthMap.put('\u30CF', "\uFF8A");
|
||||
sHalfWidthMap.put('\u30D0', "\uFF8A\uFF9E");
|
||||
sHalfWidthMap.put('\u30D1', "\uFF8A\uFF9F");
|
||||
sHalfWidthMap.put('\u30D2', "\uFF8B");
|
||||
sHalfWidthMap.put('\u30D3', "\uFF8B\uFF9E");
|
||||
sHalfWidthMap.put('\u30D4', "\uFF8B\uFF9F");
|
||||
sHalfWidthMap.put('\u30D5', "\uFF8C");
|
||||
sHalfWidthMap.put('\u30D6', "\uFF8C\uFF9E");
|
||||
sHalfWidthMap.put('\u30D7', "\uFF8C\uFF9F");
|
||||
sHalfWidthMap.put('\u30D8', "\uFF8D");
|
||||
sHalfWidthMap.put('\u30D9', "\uFF8D\uFF9E");
|
||||
sHalfWidthMap.put('\u30DA', "\uFF8D\uFF9F");
|
||||
sHalfWidthMap.put('\u30DB', "\uFF8E");
|
||||
sHalfWidthMap.put('\u30DC', "\uFF8E\uFF9E");
|
||||
sHalfWidthMap.put('\u30DD', "\uFF8E\uFF9F");
|
||||
sHalfWidthMap.put('\u30DE', "\uFF8F");
|
||||
sHalfWidthMap.put('\u30DF', "\uFF90");
|
||||
sHalfWidthMap.put('\u30E0', "\uFF91");
|
||||
sHalfWidthMap.put('\u30E1', "\uFF92");
|
||||
sHalfWidthMap.put('\u30E2', "\uFF93");
|
||||
sHalfWidthMap.put('\u30E3', "\uFF6C");
|
||||
sHalfWidthMap.put('\u30E4', "\uFF94");
|
||||
sHalfWidthMap.put('\u30E5', "\uFF6D");
|
||||
sHalfWidthMap.put('\u30E6', "\uFF95");
|
||||
sHalfWidthMap.put('\u30E7', "\uFF6E");
|
||||
sHalfWidthMap.put('\u30E8', "\uFF96");
|
||||
sHalfWidthMap.put('\u30E9', "\uFF97");
|
||||
sHalfWidthMap.put('\u30EA', "\uFF98");
|
||||
sHalfWidthMap.put('\u30EB', "\uFF99");
|
||||
sHalfWidthMap.put('\u30EC', "\uFF9A");
|
||||
sHalfWidthMap.put('\u30ED', "\uFF9B");
|
||||
sHalfWidthMap.put('\u30EE', "\uFF9C");
|
||||
sHalfWidthMap.put('\u30EF', "\uFF9C");
|
||||
sHalfWidthMap.put('\u30F0', "\uFF72");
|
||||
sHalfWidthMap.put('\u30F1', "\uFF74");
|
||||
sHalfWidthMap.put('\u30F2', "\uFF66");
|
||||
sHalfWidthMap.put('\u30F3', "\uFF9D");
|
||||
sHalfWidthMap.put('\u30F4', "\uFF73\uFF9E");
|
||||
sHalfWidthMap.put('\u30F5', "\uFF76");
|
||||
sHalfWidthMap.put('\u30F6', "\uFF79");
|
||||
sHalfWidthMap.put('\u30FB', "\uFF65");
|
||||
sHalfWidthMap.put('\u30FC', "\uFF70");
|
||||
sHalfWidthMap.put('\uFF01', "!");
|
||||
sHalfWidthMap.put('\uFF02', "\"");
|
||||
sHalfWidthMap.put('\uFF03', "#");
|
||||
sHalfWidthMap.put('\uFF04', "$");
|
||||
sHalfWidthMap.put('\uFF05', "%");
|
||||
sHalfWidthMap.put('\uFF06', "&");
|
||||
sHalfWidthMap.put('\uFF07', "'");
|
||||
sHalfWidthMap.put('\uFF08', "(");
|
||||
sHalfWidthMap.put('\uFF09', ")");
|
||||
sHalfWidthMap.put('\uFF0A', "*");
|
||||
sHalfWidthMap.put('\uFF0B', "+");
|
||||
sHalfWidthMap.put('\uFF0C', ",");
|
||||
sHalfWidthMap.put('\uFF0D', "-");
|
||||
sHalfWidthMap.put('\uFF0E', ".");
|
||||
sHalfWidthMap.put('\uFF0F', "/");
|
||||
sHalfWidthMap.put('\uFF10', "0");
|
||||
sHalfWidthMap.put('\uFF11', "1");
|
||||
sHalfWidthMap.put('\uFF12', "2");
|
||||
sHalfWidthMap.put('\uFF13', "3");
|
||||
sHalfWidthMap.put('\uFF14', "4");
|
||||
sHalfWidthMap.put('\uFF15', "5");
|
||||
sHalfWidthMap.put('\uFF16', "6");
|
||||
sHalfWidthMap.put('\uFF17', "7");
|
||||
sHalfWidthMap.put('\uFF18', "8");
|
||||
sHalfWidthMap.put('\uFF19', "9");
|
||||
sHalfWidthMap.put('\uFF1A', ":");
|
||||
sHalfWidthMap.put('\uFF1B', ";");
|
||||
sHalfWidthMap.put('\uFF1C', "<");
|
||||
sHalfWidthMap.put('\uFF1D', "=");
|
||||
sHalfWidthMap.put('\uFF1E', ">");
|
||||
sHalfWidthMap.put('\uFF1F', "?");
|
||||
sHalfWidthMap.put('\uFF20', "@");
|
||||
sHalfWidthMap.put('\uFF21', "A");
|
||||
sHalfWidthMap.put('\uFF22', "B");
|
||||
sHalfWidthMap.put('\uFF23', "C");
|
||||
sHalfWidthMap.put('\uFF24', "D");
|
||||
sHalfWidthMap.put('\uFF25', "E");
|
||||
sHalfWidthMap.put('\uFF26', "F");
|
||||
sHalfWidthMap.put('\uFF27', "G");
|
||||
sHalfWidthMap.put('\uFF28', "H");
|
||||
sHalfWidthMap.put('\uFF29', "I");
|
||||
sHalfWidthMap.put('\uFF2A', "J");
|
||||
sHalfWidthMap.put('\uFF2B', "K");
|
||||
sHalfWidthMap.put('\uFF2C', "L");
|
||||
sHalfWidthMap.put('\uFF2D', "M");
|
||||
sHalfWidthMap.put('\uFF2E', "N");
|
||||
sHalfWidthMap.put('\uFF2F', "O");
|
||||
sHalfWidthMap.put('\uFF30', "P");
|
||||
sHalfWidthMap.put('\uFF31', "Q");
|
||||
sHalfWidthMap.put('\uFF32', "R");
|
||||
sHalfWidthMap.put('\uFF33', "S");
|
||||
sHalfWidthMap.put('\uFF34', "T");
|
||||
sHalfWidthMap.put('\uFF35', "U");
|
||||
sHalfWidthMap.put('\uFF36', "V");
|
||||
sHalfWidthMap.put('\uFF37', "W");
|
||||
sHalfWidthMap.put('\uFF38', "X");
|
||||
sHalfWidthMap.put('\uFF39', "Y");
|
||||
sHalfWidthMap.put('\uFF3A', "Z");
|
||||
sHalfWidthMap.put('\uFF3B', "[");
|
||||
sHalfWidthMap.put('\uFF3C', "\\");
|
||||
sHalfWidthMap.put('\uFF3D', "]");
|
||||
sHalfWidthMap.put('\uFF3E', "^");
|
||||
sHalfWidthMap.put('\uFF3F', "_");
|
||||
sHalfWidthMap.put('\uFF41', "a");
|
||||
sHalfWidthMap.put('\uFF42', "b");
|
||||
sHalfWidthMap.put('\uFF43', "c");
|
||||
sHalfWidthMap.put('\uFF44', "d");
|
||||
sHalfWidthMap.put('\uFF45', "e");
|
||||
sHalfWidthMap.put('\uFF46', "f");
|
||||
sHalfWidthMap.put('\uFF47', "g");
|
||||
sHalfWidthMap.put('\uFF48', "h");
|
||||
sHalfWidthMap.put('\uFF49', "i");
|
||||
sHalfWidthMap.put('\uFF4A', "j");
|
||||
sHalfWidthMap.put('\uFF4B', "k");
|
||||
sHalfWidthMap.put('\uFF4C', "l");
|
||||
sHalfWidthMap.put('\uFF4D', "m");
|
||||
sHalfWidthMap.put('\uFF4E', "n");
|
||||
sHalfWidthMap.put('\uFF4F', "o");
|
||||
sHalfWidthMap.put('\uFF50', "p");
|
||||
sHalfWidthMap.put('\uFF51', "q");
|
||||
sHalfWidthMap.put('\uFF52', "r");
|
||||
sHalfWidthMap.put('\uFF53', "s");
|
||||
sHalfWidthMap.put('\uFF54', "t");
|
||||
sHalfWidthMap.put('\uFF55', "u");
|
||||
sHalfWidthMap.put('\uFF56', "v");
|
||||
sHalfWidthMap.put('\uFF57', "w");
|
||||
sHalfWidthMap.put('\uFF58', "x");
|
||||
sHalfWidthMap.put('\uFF59', "y");
|
||||
sHalfWidthMap.put('\uFF5A', "z");
|
||||
sHalfWidthMap.put('\uFF5B', "{");
|
||||
sHalfWidthMap.put('\uFF5C', "|");
|
||||
sHalfWidthMap.put('\uFF5D', "}");
|
||||
sHalfWidthMap.put('\uFF5E', "~");
|
||||
sHalfWidthMap.put('\uFF61', "\uFF61");
|
||||
sHalfWidthMap.put('\uFF62', "\uFF62");
|
||||
sHalfWidthMap.put('\uFF63', "\uFF63");
|
||||
sHalfWidthMap.put('\uFF64', "\uFF64");
|
||||
sHalfWidthMap.put('\uFF65', "\uFF65");
|
||||
sHalfWidthMap.put('\uFF66', "\uFF66");
|
||||
sHalfWidthMap.put('\uFF67', "\uFF67");
|
||||
sHalfWidthMap.put('\uFF68', "\uFF68");
|
||||
sHalfWidthMap.put('\uFF69', "\uFF69");
|
||||
sHalfWidthMap.put('\uFF6A', "\uFF6A");
|
||||
sHalfWidthMap.put('\uFF6B', "\uFF6B");
|
||||
sHalfWidthMap.put('\uFF6C', "\uFF6C");
|
||||
sHalfWidthMap.put('\uFF6D', "\uFF6D");
|
||||
sHalfWidthMap.put('\uFF6E', "\uFF6E");
|
||||
sHalfWidthMap.put('\uFF6F', "\uFF6F");
|
||||
sHalfWidthMap.put('\uFF70', "\uFF70");
|
||||
sHalfWidthMap.put('\uFF71', "\uFF71");
|
||||
sHalfWidthMap.put('\uFF72', "\uFF72");
|
||||
sHalfWidthMap.put('\uFF73', "\uFF73");
|
||||
sHalfWidthMap.put('\uFF74', "\uFF74");
|
||||
sHalfWidthMap.put('\uFF75', "\uFF75");
|
||||
sHalfWidthMap.put('\uFF76', "\uFF76");
|
||||
sHalfWidthMap.put('\uFF77', "\uFF77");
|
||||
sHalfWidthMap.put('\uFF78', "\uFF78");
|
||||
sHalfWidthMap.put('\uFF79', "\uFF79");
|
||||
sHalfWidthMap.put('\uFF7A', "\uFF7A");
|
||||
sHalfWidthMap.put('\uFF7B', "\uFF7B");
|
||||
sHalfWidthMap.put('\uFF7C', "\uFF7C");
|
||||
sHalfWidthMap.put('\uFF7D', "\uFF7D");
|
||||
sHalfWidthMap.put('\uFF7E', "\uFF7E");
|
||||
sHalfWidthMap.put('\uFF7F', "\uFF7F");
|
||||
sHalfWidthMap.put('\uFF80', "\uFF80");
|
||||
sHalfWidthMap.put('\uFF81', "\uFF81");
|
||||
sHalfWidthMap.put('\uFF82', "\uFF82");
|
||||
sHalfWidthMap.put('\uFF83', "\uFF83");
|
||||
sHalfWidthMap.put('\uFF84', "\uFF84");
|
||||
sHalfWidthMap.put('\uFF85', "\uFF85");
|
||||
sHalfWidthMap.put('\uFF86', "\uFF86");
|
||||
sHalfWidthMap.put('\uFF87', "\uFF87");
|
||||
sHalfWidthMap.put('\uFF88', "\uFF88");
|
||||
sHalfWidthMap.put('\uFF89', "\uFF89");
|
||||
sHalfWidthMap.put('\uFF8A', "\uFF8A");
|
||||
sHalfWidthMap.put('\uFF8B', "\uFF8B");
|
||||
sHalfWidthMap.put('\uFF8C', "\uFF8C");
|
||||
sHalfWidthMap.put('\uFF8D', "\uFF8D");
|
||||
sHalfWidthMap.put('\uFF8E', "\uFF8E");
|
||||
sHalfWidthMap.put('\uFF8F', "\uFF8F");
|
||||
sHalfWidthMap.put('\uFF90', "\uFF90");
|
||||
sHalfWidthMap.put('\uFF91', "\uFF91");
|
||||
sHalfWidthMap.put('\uFF92', "\uFF92");
|
||||
sHalfWidthMap.put('\uFF93', "\uFF93");
|
||||
sHalfWidthMap.put('\uFF94', "\uFF94");
|
||||
sHalfWidthMap.put('\uFF95', "\uFF95");
|
||||
sHalfWidthMap.put('\uFF96', "\uFF96");
|
||||
sHalfWidthMap.put('\uFF97', "\uFF97");
|
||||
sHalfWidthMap.put('\uFF98', "\uFF98");
|
||||
sHalfWidthMap.put('\uFF99', "\uFF99");
|
||||
sHalfWidthMap.put('\uFF9A', "\uFF9A");
|
||||
sHalfWidthMap.put('\uFF9B', "\uFF9B");
|
||||
sHalfWidthMap.put('\uFF9C', "\uFF9C");
|
||||
sHalfWidthMap.put('\uFF9D', "\uFF9D");
|
||||
sHalfWidthMap.put('\uFF9E', "\uFF9E");
|
||||
sHalfWidthMap.put('\uFF9F', "\uFF9F");
|
||||
sHalfWidthMap.put('\uFFE5', "\u005C\u005C");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return half-width version of that character if possible. Return null if not possible
|
||||
* @param ch input character
|
||||
* @return CharSequence object if the mapping for ch exists. Return null otherwise.
|
||||
*/
|
||||
public static CharSequence tryGetHalfWidthText(char ch) {
|
||||
if (sHalfWidthMap.containsKey(ch)) {
|
||||
return sHalfWidthMap.get(ch);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,8 @@
|
||||
package com.android.unit_tests.vcard;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.pim.vcard.ContactStruct;
|
||||
import android.pim.vcard.VCardEntry;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -28,7 +29,7 @@ import java.util.Set;
|
||||
* Previously used in main vCard handling code but now exists only for testing.
|
||||
*
|
||||
* Especially useful for testing parser code (VCardParser), since all properties can be
|
||||
* checked via this class unlike {@link ContactStruct}, which only emits the result of
|
||||
* checked via this class unlike {@link VCardEntry}, which only emits the result of
|
||||
* interpretation of the content of each vCard. We cannot know whether vCard parser or
|
||||
* ContactStruct is wrong withouth this class.
|
||||
*/
|
||||
@@ -123,7 +124,10 @@ public class PropertyNode {
|
||||
return false;
|
||||
} else if (!paramMap.equals(node.paramMap)) {
|
||||
return false;
|
||||
} else if (!paramMap_TYPE.equals(node.paramMap_TYPE)) {
|
||||
} else if (!(paramMap_TYPE.size() == node.paramMap_TYPE.size()) &&
|
||||
!paramMap_TYPE.equals(node.paramMap_TYPE)) {
|
||||
Log.d("@@@", "paramMap_Type: " + paramMap_TYPE.size() + ", "
|
||||
+ node.paramMap_TYPE.size());
|
||||
return false;
|
||||
} else if (!propGroupSet.equals(node.propGroupSet)) {
|
||||
return false;
|
||||
@@ -154,10 +158,33 @@ public class PropertyNode {
|
||||
builder.append(propName);
|
||||
builder.append(", paramMap: ");
|
||||
builder.append(paramMap.toString());
|
||||
builder.append(", propmMap_TYPE: ");
|
||||
builder.append(paramMap_TYPE.toString());
|
||||
builder.append(", propGroupSet: ");
|
||||
builder.append(propGroupSet.toString());
|
||||
builder.append(", paramMap_TYPE: [");
|
||||
boolean first = true;
|
||||
for (String elem : paramMap_TYPE) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append('"');
|
||||
builder.append(elem);
|
||||
builder.append('"');
|
||||
}
|
||||
builder.append("]");
|
||||
if (!propGroupSet.isEmpty()) {
|
||||
builder.append(", propGroupSet: [");
|
||||
for (String elem : propGroupSet) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append('"');
|
||||
builder.append(elem);
|
||||
builder.append('"');
|
||||
}
|
||||
builder.append("]");
|
||||
}
|
||||
if (propValue_vector != null && propValue_vector.size() > 1) {
|
||||
builder.append(", propValue_vector size: ");
|
||||
builder.append(propValue_vector.size());
|
||||
|
||||
@@ -419,6 +419,62 @@ public class VCardExporterTests extends VCardTestsBase {
|
||||
testPhonePrefHandlingCommon(V30);
|
||||
}
|
||||
|
||||
private void testMiscPhoneTypeHandling(int vcardType) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContactEntry entry = resolver.buildContactEntry();
|
||||
entry.buildData(Phone.CONTENT_ITEM_TYPE)
|
||||
.put(Phone.NUMBER, "1")
|
||||
.put(Phone.TYPE, Phone.TYPE_CUSTOM)
|
||||
.put(Phone.LABEL, "Modem");
|
||||
entry.buildData(Phone.CONTENT_ITEM_TYPE)
|
||||
.put(Phone.NUMBER, "2")
|
||||
.put(Phone.TYPE, Phone.TYPE_CUSTOM)
|
||||
.put(Phone.LABEL, "MSG");
|
||||
entry.buildData(Phone.CONTENT_ITEM_TYPE)
|
||||
.put(Phone.NUMBER, "3")
|
||||
.put(Phone.TYPE, Phone.TYPE_CUSTOM)
|
||||
.put(Phone.LABEL, "BBS");
|
||||
entry.buildData(Phone.CONTENT_ITEM_TYPE)
|
||||
.put(Phone.NUMBER, "4")
|
||||
.put(Phone.TYPE, Phone.TYPE_CUSTOM)
|
||||
.put(Phone.LABEL, "VIDEO");
|
||||
entry.buildData(Phone.CONTENT_ITEM_TYPE)
|
||||
.put(Phone.NUMBER, "5")
|
||||
.put(Phone.TYPE, Phone.TYPE_CUSTOM);
|
||||
entry.buildData(Phone.CONTENT_ITEM_TYPE)
|
||||
.put(Phone.NUMBER, "6")
|
||||
.put(Phone.TYPE, Phone.TYPE_CUSTOM)
|
||||
.put(Phone.LABEL, "_AUTO_CELL"); // The old indicator for the type mobile.
|
||||
entry.buildData(Phone.CONTENT_ITEM_TYPE)
|
||||
.put(Phone.NUMBER, "7")
|
||||
.put(Phone.TYPE, Phone.TYPE_CUSTOM)
|
||||
.put(Phone.LABEL, "\u643A\u5E2F"); // Mobile phone in Japanese Kanji
|
||||
entry.buildData(Phone.CONTENT_ITEM_TYPE)
|
||||
.put(Phone.NUMBER, "8")
|
||||
.put(Phone.TYPE, Phone.TYPE_CUSTOM)
|
||||
.put(Phone.LABEL, "invalid");
|
||||
|
||||
VCardVerifier verifier = new VCardVerifier(resolver, vcardType);
|
||||
PropertyNodesVerifierElem elem = verifier.addPropertyNodesVerifierElemWithEmptyName();
|
||||
elem.addNodeWithoutOrder("TEL", "1", new TypeSet("MODEM"))
|
||||
.addNodeWithoutOrder("TEL", "2", new TypeSet("MSG"))
|
||||
.addNodeWithoutOrder("TEL", "3", new TypeSet("BBS"))
|
||||
.addNodeWithoutOrder("TEL", "4", new TypeSet("VIDEO"))
|
||||
.addNodeWithoutOrder("TEL", "5", new TypeSet("VOICE"))
|
||||
.addNodeWithoutOrder("TEL", "6", new TypeSet("CELL"))
|
||||
.addNodeWithoutOrder("TEL", "7", new TypeSet("CELL"))
|
||||
.addNodeWithoutOrder("TEL", "8", new TypeSet("X-invalid"));
|
||||
verifier.verify();
|
||||
}
|
||||
|
||||
public void testPhoneTypeHandlingV21() {
|
||||
testMiscPhoneTypeHandling(V21);
|
||||
}
|
||||
|
||||
public void testPhoneTypeHandlingV30() {
|
||||
testMiscPhoneTypeHandling(V30);
|
||||
}
|
||||
|
||||
private void testEmailBasicCommon(int version) {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
resolver.buildContactEntry().buildData(Email.CONTENT_ITEM_TYPE)
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.unit_tests.vcard;
|
||||
import android.content.ContentValues;
|
||||
import android.pim.vcard.VCardConfig;
|
||||
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
||||
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
|
||||
|
||||
import com.android.unit_tests.vcard.PropertyNodesVerifierElem.TypeSet;
|
||||
|
||||
@@ -204,4 +205,125 @@ public class VCardJapanizationTests extends VCardTestsBase {
|
||||
.put(StructuredName.DISPLAY_NAME, "\uFF94\uFF8F\uFF80\uFF9E \uFF80\uFF9B\uFF73");
|
||||
verifier.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that only one address field is emitted toward DoCoMo phones.
|
||||
* Prefered type must (should?) be: HOME > WORK > OTHER > CUSTOM
|
||||
*/
|
||||
public void testAdrressFieldEmittionForDoCoMo_1() {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContactEntry entry = resolver.buildContactEntry();
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK)
|
||||
.put(StructuredPostal.POBOX, "1");
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_OTHER)
|
||||
.put(StructuredPostal.POBOX, "2");
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_HOME)
|
||||
.put(StructuredPostal.POBOX, "3");
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
|
||||
.put(StructuredPostal.LABEL, "custom")
|
||||
.put(StructuredPostal.POBOX, "4");
|
||||
|
||||
VCardVerifier verifier = new VCardVerifier(resolver, VCardConfig.VCARD_TYPE_DOCOMO);
|
||||
verifier.addPropertyNodesVerifierElemWithEmptyName()
|
||||
.addNodeWithoutOrder("TEL", "", new TypeSet("HOME"))
|
||||
.addNodeWithoutOrder("EMAIL", "", new TypeSet("HOME"))
|
||||
.addNodeWithoutOrder("X-CLASS", "PUBLIC")
|
||||
.addNodeWithoutOrder("X-REDUCTION", "")
|
||||
.addNodeWithoutOrder("X-NO", "")
|
||||
.addNodeWithoutOrder("X-DCM-HMN-MODE", "")
|
||||
.addNodeWithoutOrder("ADR",
|
||||
Arrays.asList("3", "", "", "", "", "", ""), new TypeSet("HOME"));
|
||||
verifier.verify();
|
||||
}
|
||||
|
||||
public void testAdrressFieldEmittionForDoCoMo_2() {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContactEntry entry = resolver.buildContactEntry();
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_OTHER)
|
||||
.put(StructuredPostal.POBOX, "1");
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK)
|
||||
.put(StructuredPostal.POBOX, "2");
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
|
||||
.put(StructuredPostal.LABEL, "custom")
|
||||
.put(StructuredPostal.POBOX, "3");
|
||||
|
||||
VCardVerifier verifier = new VCardVerifier(resolver, VCardConfig.VCARD_TYPE_DOCOMO);
|
||||
verifier.addPropertyNodesVerifierElemWithEmptyName()
|
||||
.addNodeWithoutOrder("TEL", "", new TypeSet("HOME"))
|
||||
.addNodeWithoutOrder("EMAIL", "", new TypeSet("HOME"))
|
||||
.addNodeWithoutOrder("X-CLASS", "PUBLIC")
|
||||
.addNodeWithoutOrder("X-REDUCTION", "")
|
||||
.addNodeWithoutOrder("X-NO", "")
|
||||
.addNodeWithoutOrder("X-DCM-HMN-MODE", "")
|
||||
.addNodeWithoutOrder("ADR",
|
||||
Arrays.asList("2", "", "", "", "", "", ""), new TypeSet("WORK"));
|
||||
verifier.verify();
|
||||
}
|
||||
|
||||
public void testAdrressFieldEmittionForDoCoMo_3() {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContactEntry entry = resolver.buildContactEntry();
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
|
||||
.put(StructuredPostal.LABEL, "custom1")
|
||||
.put(StructuredPostal.POBOX, "1");
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_OTHER)
|
||||
.put(StructuredPostal.POBOX, "2");
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
|
||||
.put(StructuredPostal.LABEL, "custom2")
|
||||
.put(StructuredPostal.POBOX, "3");
|
||||
|
||||
VCardVerifier verifier = new VCardVerifier(resolver, VCardConfig.VCARD_TYPE_DOCOMO);
|
||||
verifier.addPropertyNodesVerifierElemWithEmptyName()
|
||||
.addNodeWithoutOrder("TEL", "", new TypeSet("HOME"))
|
||||
.addNodeWithoutOrder("EMAIL", "", new TypeSet("HOME"))
|
||||
.addNodeWithoutOrder("X-CLASS", "PUBLIC")
|
||||
.addNodeWithoutOrder("X-REDUCTION", "")
|
||||
.addNodeWithoutOrder("X-NO", "")
|
||||
.addNodeWithoutOrder("X-DCM-HMN-MODE", "")
|
||||
.addNodeWithoutOrder("ADR", Arrays.asList("2", "", "", "", "", "", ""));
|
||||
verifier.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the vCard exporter tolerates null TYPE.
|
||||
*/
|
||||
public void testAdrressFieldEmittionForDoCoMo_4() {
|
||||
ExportTestResolver resolver = new ExportTestResolver();
|
||||
ContactEntry entry = resolver.buildContactEntry();
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.POBOX, "1");
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_OTHER)
|
||||
.put(StructuredPostal.POBOX, "2");
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_HOME)
|
||||
.put(StructuredPostal.POBOX, "3");
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK)
|
||||
.put(StructuredPostal.POBOX, "4");
|
||||
entry.buildData(StructuredPostal.CONTENT_ITEM_TYPE)
|
||||
.put(StructuredPostal.POBOX, "5");
|
||||
|
||||
VCardVerifier verifier = new VCardVerifier(resolver, VCardConfig.VCARD_TYPE_DOCOMO);
|
||||
verifier.addPropertyNodesVerifierElemWithEmptyName()
|
||||
.addNodeWithoutOrder("TEL", "", new TypeSet("HOME"))
|
||||
.addNodeWithoutOrder("EMAIL", "", new TypeSet("HOME"))
|
||||
.addNodeWithoutOrder("X-CLASS", "PUBLIC")
|
||||
.addNodeWithoutOrder("X-REDUCTION", "")
|
||||
.addNodeWithoutOrder("X-NO", "")
|
||||
.addNodeWithoutOrder("X-DCM-HMN-MODE", "")
|
||||
.addNodeWithoutOrder("ADR",
|
||||
Arrays.asList("3", "", "", "", "", "", ""), new TypeSet("HOME"));
|
||||
verifier.verify();
|
||||
}
|
||||
}
|
||||
@@ -33,14 +33,14 @@ import android.net.Uri;
|
||||
import android.os.IBinder;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.pim.vcard.ContactStruct;
|
||||
import android.pim.vcard.EntryCommitter;
|
||||
import android.pim.vcard.EntryHandler;
|
||||
import android.pim.vcard.VCardBuilder;
|
||||
import android.pim.vcard.VCardBuilderCollection;
|
||||
import android.pim.vcard.VCardEntry;
|
||||
import android.pim.vcard.VCardEntryCommitter;
|
||||
import android.pim.vcard.VCardEntryHandler;
|
||||
import android.pim.vcard.VCardInterpreter;
|
||||
import android.pim.vcard.VCardInterPreterCollection;
|
||||
import android.pim.vcard.VCardComposer;
|
||||
import android.pim.vcard.VCardConfig;
|
||||
import android.pim.vcard.VCardDataBuilder;
|
||||
import android.pim.vcard.VCardEntryConstructor;
|
||||
import android.pim.vcard.VCardParser;
|
||||
import android.pim.vcard.VCardParser_V21;
|
||||
import android.pim.vcard.VCardParser_V30;
|
||||
@@ -385,11 +385,11 @@ class CustomMockContext extends MockContext {
|
||||
|
||||
class ImportVerifierElem {
|
||||
private final ImportTestResolver mResolver;
|
||||
private final EntryHandler mHandler;
|
||||
private final VCardEntryHandler mHandler;
|
||||
|
||||
public ImportVerifierElem() {
|
||||
mResolver = new ImportTestResolver();
|
||||
mHandler = new EntryCommitter(mResolver);
|
||||
mHandler = new VCardEntryCommitter(mResolver);
|
||||
}
|
||||
|
||||
public ContentValuesBuilder addExpected(String mimeType) {
|
||||
@@ -411,8 +411,8 @@ class CustomMockContext extends MockContext {
|
||||
} else {
|
||||
vCardParser = new VCardParser_V21();
|
||||
}
|
||||
VCardDataBuilder builder =
|
||||
new VCardDataBuilder(null, null, false, vCardType, null);
|
||||
VCardEntryConstructor builder =
|
||||
new VCardEntryConstructor(null, null, false, vCardType, null);
|
||||
builder.addEntryHandler(mHandler);
|
||||
try {
|
||||
vCardParser.parse(is, builder);
|
||||
@@ -432,19 +432,19 @@ class CustomMockContext extends MockContext {
|
||||
}
|
||||
|
||||
public void onParsingStart() {
|
||||
mHandler.onParsingStart();
|
||||
mHandler.onStart();
|
||||
}
|
||||
|
||||
public void onEntryCreated(ContactStruct entry) {
|
||||
public void onEntryCreated(VCardEntry entry) {
|
||||
mHandler.onEntryCreated(entry);
|
||||
}
|
||||
|
||||
public void onParsingEnd() {
|
||||
mHandler.onParsingEnd();
|
||||
mHandler.onEnd();
|
||||
}
|
||||
}
|
||||
|
||||
class ImportVerifier implements EntryHandler {
|
||||
class ImportVerifier implements VCardEntryHandler {
|
||||
private List<ImportVerifierElem> mImportVerifierElemList =
|
||||
new ArrayList<ImportVerifierElem>();
|
||||
private int mIndex;
|
||||
@@ -476,8 +476,8 @@ class CustomMockContext extends MockContext {
|
||||
|
||||
public void verify(InputStream is, int vCardType, final VCardParser vCardParser)
|
||||
throws IOException, VCardException {
|
||||
VCardDataBuilder builder =
|
||||
new VCardDataBuilder(null, null, false, vCardType, null);
|
||||
VCardEntryConstructor builder =
|
||||
new VCardEntryConstructor(null, null, false, vCardType, null);
|
||||
builder.addEntryHandler(this);
|
||||
try {
|
||||
vCardParser.parse(is, builder);
|
||||
@@ -491,19 +491,19 @@ class CustomMockContext extends MockContext {
|
||||
}
|
||||
}
|
||||
|
||||
public void onParsingStart() {
|
||||
public void onStart() {
|
||||
for (ImportVerifierElem elem : mImportVerifierElemList) {
|
||||
elem.onParsingStart();
|
||||
}
|
||||
}
|
||||
|
||||
public void onEntryCreated(ContactStruct entry) {
|
||||
public void onEntryCreated(VCardEntry entry) {
|
||||
assertTrue(mIndex < mImportVerifierElemList.size());
|
||||
mImportVerifierElemList.get(mIndex).onEntryCreated(entry);
|
||||
mIndex++;
|
||||
}
|
||||
|
||||
public void onParsingEnd() {
|
||||
public void onEnd() {
|
||||
for (ImportVerifierElem elem : mImportVerifierElemList) {
|
||||
elem.onParsingEnd();
|
||||
elem.verifyResolver();
|
||||
@@ -802,6 +802,7 @@ class CustomMockContext extends MockContext {
|
||||
private final ExportTestResolver mResolver;
|
||||
private final int mVCardType;
|
||||
private final boolean mIsV30;
|
||||
private final boolean mIsDoCoMo;
|
||||
|
||||
// To allow duplication, use list instead of set.
|
||||
// When null, we don't need to do the verification.
|
||||
@@ -813,6 +814,7 @@ class CustomMockContext extends MockContext {
|
||||
mVCardVerifierInternal = new VCardVerifierInternal();
|
||||
mResolver = resolver;
|
||||
mIsV30 = VCardConfig.isV30(vcardType);
|
||||
mIsDoCoMo = VCardConfig.isDoCoMo(vcardType);
|
||||
mVCardType = vcardType;
|
||||
}
|
||||
|
||||
@@ -831,6 +833,8 @@ class CustomMockContext extends MockContext {
|
||||
PropertyNodesVerifierElem elem = addPropertyNodesVerifierElem();
|
||||
if (mIsV30) {
|
||||
elem.addNodeWithOrder("N", "").addNodeWithOrder("FN", "");
|
||||
} else if (mIsDoCoMo) {
|
||||
elem.addNodeWithOrder("N", "");
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
@@ -852,14 +856,14 @@ class CustomMockContext extends MockContext {
|
||||
|
||||
private void verifyOneVCard(final String vcard) {
|
||||
// Log.d("@@@", vcard);
|
||||
final VCardBuilder builder;
|
||||
final VCardInterpreter builder;
|
||||
if (mImportVerifier != null) {
|
||||
final VNodeBuilder vnodeBuilder = mPropertyNodesVerifier;
|
||||
final VCardDataBuilder vcardDataBuilder =
|
||||
new VCardDataBuilder(mVCardType);
|
||||
final VCardEntryConstructor vcardDataBuilder =
|
||||
new VCardEntryConstructor(mVCardType);
|
||||
vcardDataBuilder.addEntryHandler(mImportVerifier);
|
||||
if (mPropertyNodesVerifier != null) {
|
||||
builder = new VCardBuilderCollection(Arrays.asList(
|
||||
builder = new VCardInterPreterCollection(Arrays.asList(
|
||||
mPropertyNodesVerifier, vcardDataBuilder));
|
||||
} else {
|
||||
builder = vnodeBuilder;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package com.android.unit_tests.vcard;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.pim.vcard.VCardBuilder;
|
||||
import android.pim.vcard.VCardInterpreter;
|
||||
import android.pim.vcard.VCardConfig;
|
||||
import android.util.CharsetUtils;
|
||||
import android.util.Log;
|
||||
@@ -39,8 +39,8 @@ import java.util.List;
|
||||
*
|
||||
* Previously used in main vCard handling code but now exists only for testing.
|
||||
*/
|
||||
public class VNodeBuilder implements VCardBuilder {
|
||||
static private String LOG_TAG = "VDATABuilder";
|
||||
public class VNodeBuilder implements VCardInterpreter {
|
||||
static private String LOG_TAG = "VNodeBuilder";
|
||||
|
||||
/**
|
||||
* If there's no other information available, this class uses this charset for encoding
|
||||
|
||||
Reference in New Issue
Block a user