android vcard 与 vcalendar 需求实现

  
一、背景

Android自带的MMS应用,无论是短信和彩信都显得单调,使用起来比较麻烦,可扩展性不好。MMS应用实际上不支持非媒体附件,所有的附件都必须是可以呈现的媒体文件。

做过feature phone的兄弟应该知道,一般彩信都会有个附件列表功能。在slide中显示的图片或者文字,需要具备“播放”属性。而附件列表中的附件,是追加的,不参与“播放”类似与电子邮件中的附件。而android自带的MMS应用,根本就不支持。

二、可行性

了解可行性,就要先看看协议是怎么规定的。可以参考我的博客的另外一篇文章。

Android mms framework 提供的接口,经过验证,在打包彩信附件,接收解析时候,是不区分文件类型的。这个是很好的信号,即告诉我们,在打包的时候,想方设法把vcard附件和vcalendar附件的路径传进去,这样能打包、发送和解析,UI上面的东西,解析或者适配无非是忽悠忽悠。

三、 解决方案简要描述

我下面描述两种解决方案。

一是参考feature phone,在信息编辑界面加入一个附件列表,可以在附件列表添加很多种类的附件。这样做的优点是功能比较全,比较符合实际情况,缺点是会有很大的UI调整。二是参考HTC和华为手机做的,只添加一次vcard或者vcalendar,然后显示在图片,声音等的预览域;如果添加了可播放的媒体,则不能添加这些附件。这样做的优点是UI调整很少,缺点是功能被砍了不少。

以下介绍第二种方案。

在信息编辑界面加入一个菜单,用于插入vcard。插入后切成彩信,显示在预览域。如果插入了slides或者其他媒体,则不能使用这个菜单。

预览时候显示的图标是小名片,有两个按钮,一个是查看,第二个是删除。删除后切成短信。

在conversation中,判断是否是仅有vcard的彩信,如果是,则显示个小名片图标。其他情况都按照默认显示。

在conversation中,判断是否是仅有Vcard的彩信,如果是,则加入一个菜单,查看vcard详情。

保存接收的彩信,可以支持保存vcard。

四、 设计参考

1、  添加一个OtherAttachmodel类,用于处理非媒体附件。这个类包含附件的Uri,附件的文件名,附件的大小,附件类型,以及上下文等属性。其中Uri和类型是必要属性。

2、在SlideShowModel里面添加一个成员private final ArrayList mOtherAttachModels。由于一条彩信SlideShowModel是基础,打包、解析、显示等都和它相关,所以我把这个附件列表加在这里。设置为Arraylist主要是为了适应接收的多种附件。虽然我们发送和接收时候都只支持显示一条,但是接收还是要保证能保存附件,保证数据不丢失,即使暂时不能处理。

3、Slideshowmodel里面增加接口:

      public boolean hasOtherAttachModel();

      public void addOtherAttachModel(OtherAttachModel object){

        if(object == null){

             return;

         }

          mOtherAttachModels.add(object);

         increaseMessageSize(object.getAttachSize());

     }

     private static void initOtherAttach (Context context, PduBody pb, SlideshowModel slideshow){

         if (pb == null ||slideshow ==null) {

            return;

          }

         int partNum = pb.getPartsNum();

         for(int i = 0; i < partNum; i++) {

             PduPart part = pb.getPart(i);

             String type = new String(part.getContentType());

            

              if (         !ContentType.isImageType(type) &&  !ContentType.isVideoType(type)

                   &&  !ContentType.isAudioType(type)  &&  !type.startsWith("application/")

                  &&  !type.equals(ContentType.TEXT_PLAIN)) {

                   //String Location = new String(part.getContentLocation());

                   Uri uri = part.getDataUri();

                  OtherAttachModel model = new OtherAttachModel(context, type, uri, slideshow);

                   slideshow.addOtherAttachModel(model);

              }

         }

      }

      public void removOtherAttach(){

         for(OtherAttachModel model : mOtherAttachModels){

             decreaseMessageSize(model.getAttachSize());

        }

          mOtherAttachModels.clear();

      }

     public boolean oneVcard();

     public boolean oneVcalendar();

其中initOtherAttach()是在createFromPduBody时候调用的,在创建完slideshowmodel之后,即调用该函数,初始化其他附件。

4、在发送打包,通过在makepdubod()里面添加代码,来实现打包其他类型附件。

        for( OtherAttachModel attachmodel : mOtherAttachModels){

            String location;

            int index;

            String contentId;

            PduPart part = new PduPart();

            part.setContentType(attachmodel.getContentType().getBytes());

            location = attachmodel.getContentLocation();

            part.setContentLocation(location.getBytes());

            index = location.lastIndexOf(".");

            contentId = (index == -1) ? location

                    : location.substring(0, index);

            part.setContentId(contentId.getBytes());

            part.setDataUri(attachmodel.getUri());

            pb.addPart(part);

        }

5、注意,在保存附加到数据库之后,sync()会被调用,这个函数是更新Model里面保存的路径的。需要加

for( OtherAttachModel attachmodel : mOtherAttachModels){

            PduPart part = pb.getPartByContentLocation(attachmodel.getContentLocation());

            if (part != null) {

                attachmodel.setUri(part.getDataUri());

            }

        }

6、contact那边,需要提供一个VCARD类,提供3个接口:生成.vcf文件在指定目录,并回传该文件Uri,保存指定Uri的.VCF格式文件,显示指定uri的.vcf格式文件。

7、在workingmessage.java里面加入3个常数,   

public static final int VCARD = 5;

public static final int VCALENDAR = 6;

public static final int OTHERATTACH = 7;

在contact回传Uri,或者路径之后,

      File file = new File("/mnt/sdcard/mms/scrapSpace/123.vcf");

      Uri uri = Uri.fromFile(file);

      mWorkingMessage.setAttachment(mWorkingMessage.VCARD, uri, false);来添加vcard。

注意,需要在setAttachment函数里面,加入红色标注代码

       try {

            if (append) {

                appendMedia(type, dataUri);

            } else {

                changeMedia(type, dataUri);

                mSlideshow.removOtherAttach();

                if(type == VCARD){

                    addVcard(dataUri);

                }else if(type == VCALENDAR){

                    addVcalendar(dataUri);

                }

            }

        }

8、至于在UI上面的显示和接收时候逻辑处理,以及菜单设置,请配合SlideShowModel::oneVcard()和workingmessage::VCARD = 5来组合和适配吧。

AttachmentEditor::createView()换成你喜欢的UI吧。

 

你可能感兴趣的:(android,android,string,object,null,file,ui)