当前位置: 移动技术网 > IT编程>移动开发>Android > Android实现彩信附件的添加与删除功能

Android实现彩信附件的添加与删除功能

2019年07月24日  | 移动技术网IT编程  | 我要评论

又到中秋月圆时,色一休,windows store

本文实例讲述了android实现彩信附件的添加与删除功能。分享给大家供大家参考,具体如下:

添加附件

在composemessageactivity里

addattachment(int type) 函数

根据type的不同,分成6个case

case a:

mediaselectlistactivity.add_image 用gallery选图片:

messageutils.selectimage(this, request_code_attach_image);

起一个intent:

intent innerintent = new intent(intent.action_get_content);
innerintent.settype(contenttype); //image type
intent wrapperintent = intent.createchooser(innerintent, null);
startactivityforresult(wrapperintent,requestcode);

createchooser 函数new 一个 intent intent = new intent(action_chooser);

也就是起来一个action_chooser的 activity

case b:

mediaselectlistactivity.take_picture

intent intent = new intent(mediastore.action_image_capture);
intent.putextra(mediastore.extra_output, mms.scrapspace.content_uri);
startactivityforresult(intent, request_code_take_picture);

起一个照相机来拍照了,

case c:

mediaselectlistactivity.add_video

很像case a

只有在type那里,从image换成video

case d:

mediaselectlistactivity.record_video

和case b一样起一个录像机,不过这次有空间大小计算:给文本留1024byte。

按一条彩信300k算,录像最多使用299k。也即299*1024byte

intent intent = new intent(mediastore.action_video_capture);
startactivityforresult(intent, request_code_take_video);

case e:

mediaselectlistactivity.add_sound

messageutils.selectaudio(this, request_code_attach_sound);
intent intent = new intent(ringtonemanager.action_ringtone_picker);

case f:

mediaselectlistactivity.record_sound

像b那样,七个录音机。 这次type是aution

intent intent = new intent(intent.action_get_content);
intent.settype(contenttype.audio_amr);
intent.setclassname("com.android.soundrecorder", "com.android.soundrecorder.soundrecorder");

case g:

mediaselectlistactivity.add_slideshow

幻灯片slideshow比较尴尬。因为整个彩信附件也叫slideshow,而这里的slideshow是多张图片拼凑在一起的意思。彩信的附件也经常是若干张图片。。。 这里从起名开始就绕的要死了。

uri datauri = mworkingmessage.saveasmms(false);
intent intent = new intent(this, slideshoweditactivity.class);
intent.setdata(datauri);
startactivityforresult(intent, request_code_create_slideshow);

saveasmms函数里面有几个事情:首先把短信强制变成彩信,把短信的内容封装到pdupersister中(可以理解为彩信body)去,new一个sendreq也就是彩信头。生成包含彩信头和body的uri。
最后起一个尴尬的slideshoweditactivity。 这个东西太麻烦。不看。。

然后是到了onactivityresult函数。 那些从外面的activity读取媒体数据的应用返回的时候都回到这里。

a。图片

图片在onactivityreuslt会得到uri,调用:

addimage(uri, false);

这个函数会调用:

复制代码 代码如下:
mworkingmessage.setattachment(workingmessage.image, uri, false);

也就是非append模式添加图片。

如果图片太大,会启用异步的图片压缩函数。

b 拍照片

也是返回一个uri到onactivityreuslt函数。也是调用 addimage(uri, false),同上。

c 选录像文件 d 拍录像

都是调用:

addvideo(data.getdata(), false);

data.getdata()也是得到uri,addvideo调用:

复制代码 代码如下:
mworkingmessage.setattachment(workingmessage.video, uri, append);

跟图片处理一样的。

e 选录音文件 f 录音

都是addaudio -->
mworkingmessage.setattachment(workingmessage.audio, uri, false);
不多说

删除附件

attachmenteditor里面有个handler,用来给composemessageactivity传消息。

所有删除附件操作的按钮都在attachmenteditor上。对不同的媒体类型有不同的按钮,但是按下之后出口是一样的:

message msg = message.obtain(mhandler, msg_remove_attachment);
msg.sendtotarget();

就是这么个操作。

之所以一样是因为所有的附近都存在slideshowmodel里,而这个slideshowmodel是:

arraylist<slidemodel> mslides; 一列儿slide组成的。

每个slide可以包含video,image,audio,text, 其中前三者一般不能两两同时存在,唯一的例外是image和audio。

(其实我觉得如果,如果每个slide只能包含三者中的一种,即不处理上面那个例外,逻辑可能更清晰)
说回到那个remove操作。。

composemessageactivity的handler里的handlemessage函数,接到这个删除msg之后的操作是:

mworkingmessage.setattachment(workingmessage.text, null, false);

最后一位false表示非append模式,即从新修改附件。

mworkingmessage是什么呢?

是短信(包括彩信)的所有的状态所有操作所有数据的现状,主要有几个成员:

mmmsstate 彩信状态,是不是彩信,为啥是彩信,是有附件有标题,或者强制彩信等

mattachmenttype 附件类型。如果mslideshow是多页:slide类型。 单页:图片|声音|录像|文本。   如果mslideshow是空,就是文本类型。

mslideshow 附件数据数组。就是那个arraylist<slidemodel> mslides。

现在回头看那个删除操作。

setattachment里面最主要的函数是changemedia(type, datauri),这里传入的参数type是text,datauri是null。
这个函数进去:

slidemodel slide = mslideshow.get(0);
mediamodel media;
// remove any previous attachments.
slide.removeimage();
slide.removevideo();
slide.removeaudio();
// if we're changing to text, just bail out.
if (type == text) {
  return;
}
// make a correct mediamodel for the type of attachment.
if (type == image) {
  media = new imagemodel(mcontext, uri, mslideshow.getlayout()
      .getimageregion());
} else if (type == video) {
  media = new videomodel(mcontext, uri, mslideshow.getlayout()
      .getimageregion());
} else if (type == audio) {
  media = new audiomodel(mcontext, uri);
} else {
  throw new illegalargumentexception("changemedia type=" + type
      + ", uri=" + uri);
}
// add it to the slide.
slide.add(media);
// for video and audio, set the duration of the slide to
// that of the attachment.
if (type == video || type == audio) {
  slide.updateduration(media.getduration());
}

看到第一个return我们就可以return了。。

多干净利落!直接把彩信原来的附件看都不堪直接一刀删完,类型回归到workingmessage.text,把uri置空。

另外,说一些题外的。

这个changemedia函数,来来回回,都是改的mslideshow.get(0)那个

在setattachment的时候,如果是用的append模式,到时候就会用appendmedia而不是changemedia函数。

对于append模式,

如果最后一页包含了图片image或者录像vedio, 那么append的时候必须加到下一张。

感觉源码里这个判断有点写复杂了。。你看我一句话就能归纳出来的,他代码写半天~

不过我写不出更好的~~

还有slidemodel的add函数。 很多情况叠在一起了,所以有点复杂。

添加的关键函数是下面这个,第一个参数是对应格式的原来媒体(比如你想添加录像,那这个就是原来的录像,可以是null),第二个是添加的新媒体

private void internaladdorreplace(mediamodel old, mediamodel media) {
  int addsize = media.getmediasize();
  int removesize;
  if (old == null) {
    if (null != mparent) {
      mparent.checkmessagesize(addsize);
    }
    mmedia.add(media);
    increaseslidesize(addsize);
    increasemessagesize(addsize);
  } else {
    removesize = old.getmediasize();
    if (addsize > removesize) {
      if (null != mparent) {
        mparent.checkmessagesize(addsize - removesize);
      }
      increaseslidesize(addsize - removesize);
      increasemessagesize(addsize - removesize);
    } else {
      decreaseslidesize(removesize - addsize);
      decreasemessagesize(removesize - addsize);
    }
    mmedia.set(mmedia.indexof(old), media);
    old.unregisterallmodelchangedobservers();
  }
  for (imodelchangedobserver observer : mmodelchangedobservers) {
    media.registermodelchangedobserver(observer);
  }
}

还有个附件太大时的异步缩小功能,是下面这个函数

public static void resizeimageasync(final context context,
     final uri imageuri, final handler handler,
     final resizeimageresultcallback cb, final boolean append) {
   // show a progress toast if the resize hasn't finished
   // within one second.
   // stash the runnable for showing it away so we can cancel
   // it later if the resize completes ahead of the deadline.
   final runnable showprogress = new runnable() {
     public void run() {
       toast.maketext(context, r.string.compressing,
           toast.length_short).show();
     }
   };
   // schedule it for one second from now.
   handler.postdelayed(showprogress, 1000);
   new thread(new runnable() {
     public void run() {
       final pdupart part;
       try {
         uriimage image = new uriimage(context, imageuri);
         part = image.getresizedimageaspart(mmsconfig
             .getmaximagewidth(), mmsconfig.getmaximageheight(),
             mmsconfig.getmaxmessagesize() - message_overhead);
       } finally {
         // cancel pending show of the progress toast if necessary.
         handler.removecallbacks(showprogress);
       }
       handler.post(new runnable() {
         public void run() {
           cb.onresizeresult(part, append);
         }
       });
     }
   }).start();
}

图片被缩放到最大640*480,如果还是大于300*1024-5000字节(差不多295k),那么缩放到295k。

这个大小是源码编写程序员凭感觉写死的。

这里的cb.onresizeresult是调用的composemessageactivity的resizeimageresultcallback里的函数。

处理大小结束后,会拿新的图片去再次setattachment,也就更新了附件。

更多关于android相关内容感兴趣的读者可查看本站专题:《android数据库操作技巧总结》、《android编程之activity操作技巧总结》、《android文件操作技巧汇总》、《android编程开发之sd卡操作方法汇总》、《android开发入门与进阶教程》、《android资源操作技巧汇总》、《android视图view技巧总结》及《android控件用法总结

希望本文所述对大家android程序设计有所帮助。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网