Samsung Galaxy S6 可导入的 vCard 的 format/version/encoding 限制是什么
What is format/version/encoding limitations of vCards importable by Samsung Galaxy S6
我在尝试将使用 vCard 格式的联系人导入 Samsung Galaxy S6 时遇到问题 - see here。
我正在使用以下 C# 代码创建 vCard 文件:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using Thought.vCards; //https://www.nuget.org/packages/Thought.vCards/
namespace VCardGen
{
class Program
{
const string INPUT_FILE = @"C:\VSProjects\VCardGen\in.txt";
const string OUTPUT_FILE = @"C:\VSProjects\VCardGen\Files5\{0}.vcf";
//What encoding comes here? This worked but national characters displayed as ?
static Encoding ENCODING = Encoding.GetEncoding("Windows-1250");
/// <summary>
/// Removes special characters
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
static String RemoveDiacritics(String s)
{
String normalizedString = s.Normalize(NormalizationForm.FormD);
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < normalizedString.Length; i++)
{
Char c = normalizedString[i];
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark && CharUnicodeInfo.GetUnicodeCategory(c)!=UnicodeCategory.OtherSymbol)
stringBuilder.Append(c);
}
return stringBuilder.ToString();
}
/// <summary>
/// Saves one vCard
/// </summary>
/// <param name="c"></param>
static void SaveVCard(vCard c, Encoding e)
{
if (c == null) return;
string fn = RemoveDiacritics(c.FamilyName + c.GivenName).Trim().Replace(" ", ""); ;
vCardStandardWriter writer = new vCardStandardWriter();
{
writer.EmbedInternetImages = false;
writer.EmbedLocalImages = false;
writer.Options = vCardStandardWriterOptions.IgnoreCommas;
using (var file = File.OpenWrite(String.Format(OUTPUT_FILE, fn)))
using (var fwriter = new StreamWriter(file, e))
{
writer.Write(c, fwriter);
}
writer = null;
}
}
static void Main(string[] args)
{
//Load file outputed by Qontact
string text = System.IO.File.ReadAllText(INPUT_FILE, ENCODING);
List<string> l = text.Split('\n').ToList();
vCard c= null;
//Process Qontact file line by line
foreach (string s in l)
{
string x = s.Trim();
if (x.Length == 0) continue;
if (x.StartsWith("-"))
{
SaveVCard(c,ENCODING);
string[] np = x.Substring(1).Split(',');
c = new vCard();
c.FamilyName = np[0].Trim();
if (np.Length>1) c.GivenName = np[1].Trim();
}
else if (x.StartsWith("NAME: "))
c.DisplayName = x.Replace("NAME: ", "").Trim() ;
else if (x.StartsWith("MOB: "))
c.Phones.Add(new vCardPhone(x.Replace("MOB: ", "").Trim(), vCardPhoneTypes.Cellular));
else if (x.StartsWith("ORG:"))
c.Organization = x.Replace("ORG:", "").Trim();
else if (x.StartsWith("ADDR:"))
{
string n = x.Replace("ADDR:", "");
vCardDeliveryAddress a = new vCardDeliveryAddress();
a.Street = n.Trim();
c.DeliveryAddresses.Add(a);
}
else if (x.StartsWith("EMAIL:"))
c.EmailAddresses.Add(new vCardEmailAddress(x.Replace("EMAIL:", "").Trim()));
else if (x.StartsWith("HOME :"))
c.Phones.Add(new vCardPhone(x.Replace("HOME :", "").Trim(), vCardPhoneTypes.Home));
else if (x.StartsWith("TEL:"))
c.Phones.Add(new vCardPhone(x.Replace("TEL:", "").Trim(), vCardPhoneTypes.Work));
}
SaveVCard(c, ENCODING);
}
}
}
我有一个问题,当我使用编码 Encoding.GetEncoding("Windows-1250")
时,vCards 可以很好地导入 phone,但所有国家特定字符都被转换为 ?
.
当我使用 Encoding.UTF8
时,它会产生如下内容:
BEGIN:VCARD
VERSION:3.0
NAME:XXXXX GĂĽnzel
N:GĂĽnzel;XXXXX;;;
TEL;CELL:+XXXXXXXXXX
END:VCARD
导入失败。
当我使用 Windows-1250
时,它会产生如下内容:
BEGIN:VCARD
VERSION:3.0
NAME:XXXX Günzel
N:Günzel;XXXXX;;;
TEL;CELL:+XXXXXXXXX
END:VCARD
导入成功,但没有国家特定的字符。
导入文件如下所示:
-AAA Taxi
MOB: 11111111111
-Adam
MOB: 1111111111111
EMAIL:info@aaaaa.aa
我总是在 运行 程序之前用 PSPad 文本编辑器将它转换为相应的编码。
我应该解决什么问题才能生成具有正确字符编码的可导入 vCard,并且在 Samsung Galaxy S6 上显示正常?
当你使用内置常量Encoding.UTF8
时,它总是在开头添加一个字节顺序标记。这就是导致问题的原因。使用 false
作为参数创建 UTF8Encoding class 的新实例。然后你会得到它以UTF8编码,但开头没有写字节顺序标记。
我在尝试将使用 vCard 格式的联系人导入 Samsung Galaxy S6 时遇到问题 - see here。
我正在使用以下 C# 代码创建 vCard 文件:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using Thought.vCards; //https://www.nuget.org/packages/Thought.vCards/
namespace VCardGen
{
class Program
{
const string INPUT_FILE = @"C:\VSProjects\VCardGen\in.txt";
const string OUTPUT_FILE = @"C:\VSProjects\VCardGen\Files5\{0}.vcf";
//What encoding comes here? This worked but national characters displayed as ?
static Encoding ENCODING = Encoding.GetEncoding("Windows-1250");
/// <summary>
/// Removes special characters
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
static String RemoveDiacritics(String s)
{
String normalizedString = s.Normalize(NormalizationForm.FormD);
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < normalizedString.Length; i++)
{
Char c = normalizedString[i];
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark && CharUnicodeInfo.GetUnicodeCategory(c)!=UnicodeCategory.OtherSymbol)
stringBuilder.Append(c);
}
return stringBuilder.ToString();
}
/// <summary>
/// Saves one vCard
/// </summary>
/// <param name="c"></param>
static void SaveVCard(vCard c, Encoding e)
{
if (c == null) return;
string fn = RemoveDiacritics(c.FamilyName + c.GivenName).Trim().Replace(" ", ""); ;
vCardStandardWriter writer = new vCardStandardWriter();
{
writer.EmbedInternetImages = false;
writer.EmbedLocalImages = false;
writer.Options = vCardStandardWriterOptions.IgnoreCommas;
using (var file = File.OpenWrite(String.Format(OUTPUT_FILE, fn)))
using (var fwriter = new StreamWriter(file, e))
{
writer.Write(c, fwriter);
}
writer = null;
}
}
static void Main(string[] args)
{
//Load file outputed by Qontact
string text = System.IO.File.ReadAllText(INPUT_FILE, ENCODING);
List<string> l = text.Split('\n').ToList();
vCard c= null;
//Process Qontact file line by line
foreach (string s in l)
{
string x = s.Trim();
if (x.Length == 0) continue;
if (x.StartsWith("-"))
{
SaveVCard(c,ENCODING);
string[] np = x.Substring(1).Split(',');
c = new vCard();
c.FamilyName = np[0].Trim();
if (np.Length>1) c.GivenName = np[1].Trim();
}
else if (x.StartsWith("NAME: "))
c.DisplayName = x.Replace("NAME: ", "").Trim() ;
else if (x.StartsWith("MOB: "))
c.Phones.Add(new vCardPhone(x.Replace("MOB: ", "").Trim(), vCardPhoneTypes.Cellular));
else if (x.StartsWith("ORG:"))
c.Organization = x.Replace("ORG:", "").Trim();
else if (x.StartsWith("ADDR:"))
{
string n = x.Replace("ADDR:", "");
vCardDeliveryAddress a = new vCardDeliveryAddress();
a.Street = n.Trim();
c.DeliveryAddresses.Add(a);
}
else if (x.StartsWith("EMAIL:"))
c.EmailAddresses.Add(new vCardEmailAddress(x.Replace("EMAIL:", "").Trim()));
else if (x.StartsWith("HOME :"))
c.Phones.Add(new vCardPhone(x.Replace("HOME :", "").Trim(), vCardPhoneTypes.Home));
else if (x.StartsWith("TEL:"))
c.Phones.Add(new vCardPhone(x.Replace("TEL:", "").Trim(), vCardPhoneTypes.Work));
}
SaveVCard(c, ENCODING);
}
}
}
我有一个问题,当我使用编码 Encoding.GetEncoding("Windows-1250")
时,vCards 可以很好地导入 phone,但所有国家特定字符都被转换为 ?
.
当我使用 Encoding.UTF8
时,它会产生如下内容:
BEGIN:VCARD
VERSION:3.0
NAME:XXXXX GĂĽnzel
N:GĂĽnzel;XXXXX;;;
TEL;CELL:+XXXXXXXXXX
END:VCARD
导入失败。
当我使用 Windows-1250
时,它会产生如下内容:
BEGIN:VCARD
VERSION:3.0
NAME:XXXX Günzel
N:Günzel;XXXXX;;;
TEL;CELL:+XXXXXXXXX
END:VCARD
导入成功,但没有国家特定的字符。
导入文件如下所示:
-AAA Taxi
MOB: 11111111111
-Adam
MOB: 1111111111111
EMAIL:info@aaaaa.aa
我总是在 运行 程序之前用 PSPad 文本编辑器将它转换为相应的编码。
我应该解决什么问题才能生成具有正确字符编码的可导入 vCard,并且在 Samsung Galaxy S6 上显示正常?
当你使用内置常量Encoding.UTF8
时,它总是在开头添加一个字节顺序标记。这就是导致问题的原因。使用 false
作为参数创建 UTF8Encoding class 的新实例。然后你会得到它以UTF8编码,但开头没有写字节顺序标记。