Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将联系人的照片写入vcf文件,android_Java_Android_Android Contacts_Vcf Vcard - Fatal编程技术网

Java 将联系人的照片写入vcf文件,android

Java 将联系人的照片写入vcf文件,android,java,android,android-contacts,vcf-vcard,Java,Android,Android Contacts,Vcf Vcard,我使用的代码中显示了所有联系人的列表。当我从列表中选择联系人时,联系人的详细信息将显示并以正确的vcard格式保存在.vcf文件中,工作正常。当我选择一个有照片的联系人时,它会在imageView中显示照片,但我不知道如何将照片写入vcf文件。 我用过这些台词 Uri photoUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,Integer.parseInt(item)); Bitmap photoBi

我使用的代码中显示了所有联系人的列表。当我从列表中选择联系人时,联系人的详细信息将显示并以正确的vcard格式保存在.vcf文件中,工作正常。当我选择一个有照片的联系人时,它会在imageView中显示照片,但我不知道如何将照片写入vcf文件。 我用过这些台词

Uri photoUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,Integer.parseInt(item));
Bitmap photoBitmap;
ContentResolver cr = getContentResolver();
InputStream is = ContactsContract.Contacts.openContactPhotoInputStream(cr, photoUri);
photoBitmap = BitmapFactory.decodeStream(is);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
photoBitmap.compress(CompressFormat.JPEG, 100 , bos);
byte[] bitmapdata = bos.toByteArray();
imageEncoded = Base64.encodeToString(bitmapdata,Base64.DEFAULT);

String content = "BEGIN:VCARD\nVERSION:3.0\nCLASS:PUBLIC\nPRODID:-//class_vcard from  TroyWolf.com//NONSGML Version 1//EN\nFN:"+contactName+"\nTEL;TYPE=cell,voice:"+number+"\nPHOTO;TYPE=JPEG;ENCODING=BASE64:"+imageEncoded+"\nTZ:+0000\nEND:VCARD";
但我在读取联系人时出错由于意外原因无法解析vCard,无效行:
谁能帮我解决这个问题

尝试将编码参数的值从BASE64更改为B。B是3.0 vCard中使用的正确值

此外,vCard的正确换行顺序是\r\n,而不是\r\n

您可能对使用vCard库生成vCard感兴趣。这是一个图书馆的免责声明:我是作者

VCard vcard = new VCard();
vcard.setClassification("PUBLIC");
vcard.setProdId("-//class_vcard from  TroyWolf.com//NONSGML Version 1//EN");
vcard.setFormattedName(contactName);

TelephoneType tel = vcard.addTelephoneNumber(number);
tel.addType(TelephoneTypeParameter.CELL);
tel.addType(TelephoneTypeParameter.VOICE);

PhotoType photo = new PhotoType(bitmapdata, ImageTypeParameter.JPEG);
vcard.addPhoto(photo);

vcard.setTimezone(new TimezoneType(0, 0));

String content = Ezvcard.write(vcard).version(VCardVersion.V3_0).prodId(false).go();

这是一篇非常晚的文章,但是我在没有使用库的情况下找不到任何关于StackOverflow的有效解决方案,所以我认为分享我的发现会很好

更改编码参数和更正换行符序列不足以构造带有照片的.vcf文件。在编码到base64之后,我还必须删除换行符

根据需要将Uri转换为base64格式的示例代码替换imageStream初始化

// string you can use to write to vcf file (3.0 vCards)
String.format("PHOTO;ENCODING=B;TYPE=JPEG: ,%s\r\n", convertUriToBase64(context, photoUri));

private String convertUriToBase64(Context context, String photoUri) {
    InputStream imageStream = null;
    try {
        imageStream = context.getContentResolver().openInputStream(Uri.parse(photoUri));

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
    byte[] bitmapData = bos.toByteArray();
    // line break has to be removed, so it is on the same line as PHOTO
    return Base64.encodeToString(bitmapData, Base64.DEFAULT).replaceAll("\n", "");
}

下面是我做了什么来获得一张照片作为vCard的一部分发送。。。 需要考虑的重要事项:

1台设备:运行安卓6.01的中兴Axon 7

2无法使vCard 3.0或4.0正常运行,只能使用vCard 2.1

File vcfFile = new File(DisplayContactActivity.this.getExternalFilesDir(null), "generated.vcf");
                    try
                    {
                        /**Only Version 2.1 worked for me with or without PHOTO**/
                        FileWriter fw = new FileWriter(vcfFile);
                        fw.write("BEGIN:VCARD\r\n");
                        fw.write("VERSION:2.1\r\n");

                        fw.write("FN:" + "Contact 7" + "\r\n");

                        /*Getting the name of the File as I had saved it*/
                        String file_name = ("current_contact_image" + CONTACT_ID);

                        /*Get the bitmap that we stored in a File*/
                        Bitmap bitmap = getContactImage(file_name);

                        /*Convert bitmap to Base64*/
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
                        byte[] b = baos.toByteArray();
                        String image_encoded = Base64.encodeToString(b, Base64.DEFAULT);

                        /*Write the encoded version of image to vCard 2.1, NOTICE that no determining whether the image is GIF or JPEG is needed*/   
                        fw.write("PHOTO;ENCODING=BASE64:" + image_encoded + "\r\n");

                        /*Write some other stuff to the vCard also just trying to give whoever needs this a starting point*/  
                        fw.write("TEL;Primary:" + "(586) 268-3437" + "\r\n");
                        fw.write("TEL;OTHER:" + "(313) 313-4545" + "\r\n");

                        fw.write("ADR;OTHER:" + "12345 AnyLane Dr." + "\r\n");
                        fw.write("ADR;OTHER:" + "54321 AnyPlace Av." + "\r\n");

                        fw.write("EMAIL;OTHER:" + "email@yahoo.com" + "\r\n");
                        fw.write("EMAIL;OTHER:" + "email@wowway.com" + "\r\n");

                        fw.write("END:VCARD\r\n");
                        fw.close();

                        Intent i = new Intent();
                        i.setAction(android.content.Intent.ACTION_VIEW);
                        i.setDataAndType(Uri.fromFile(vcfFile), "text/x-vcard");
                        startActivity(i);
                    }
                    catch (Exception e)
                    {
                        Log.i(TAG, "Exception: " + e);
                    }

public Bitmap getContactImage(String file_name)
{
    Log.i(TAG, "Running getContactImage() with file name: " + file_name);

    Bitmap thumbnail = null;
    //------------------------------------------------------------------------------------------
    try
    {
        File filePath = getBaseContext().getFileStreamPath(file_name);
        FileInputStream fis = new FileInputStream(filePath);
        thumbnail = BitmapFactory.decodeStream(fis);
    }
    catch (Exception e) //Use scaled_bitmap_for_storage instead of the current_contact_image file name
    {
        /*Error getting user-selected image, set boolean to get default image*/
        Log.i(TAG, "Exception while running getContactImage() for file name: " + file_name + " with error message: " + e);
    }
    //------------------------------------------------------------------------------------------

    return thumbnail;
}

我也可以使用android的ez vcard库吗?它给了我一个异常java.lang.NoClassDefFoundError:ezvcard.VCard。我在项目中使用了ez-vcard-0.7.3.jar。另外,你能告诉我什么是“B”吗?正如你所说,你告诉我使用B而不是Base64!我不确定你是否可以在android上使用ez vcard。我认为您可以,因为ez vcard是一个Java库。B与BASE64具有相同的含义。出于某种原因,他们决定在3.0版中使用B。