Android实现彩信附件的添加与删除功能
本文实例讲述了Android实现彩信附件的添加与删除功能。分享给大家供大家参考,具体如下:
添加附件
在ComposeMessageActivity里
addAttachment(inttype)函数
根据type的不同,分成6个case
caseA:
MediaSelectListActivity.ADD_IMAGE用gallery选图片:
MessageUtils.selectImage(this,REQUEST_CODE_ATTACH_IMAGE);
起一个intent:
IntentinnerIntent=newIntent(Intent.ACTION_GET_CONTENT); innerIntent.setType(contentType);//imagetype IntentwrapperIntent=Intent.createChooser(innerIntent,null); startActivityForResult(wrapperIntent,requestCode);
createChooser函数new一个Intentintent=newIntent(ACTION_CHOOSER);
也就是起来一个ACTION_CHOOSER的activity
caseB:
MediaSelectListActivity.TAKE_PICTURE
Intentintent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT,Mms.ScrapSpace.CONTENT_URI); startActivityForResult(intent,REQUEST_CODE_TAKE_PICTURE);
起一个照相机来拍照了,
caseC:
MediaSelectListActivity.ADD_VIDEO
很像caseA
只有在type那里,从image换成video
caseD:
MediaSelectListActivity.RECORD_VIDEO
和caseB一样起一个录像机,不过这次有空间大小计算:给文本留1024Byte。
按一条彩信300k算,录像最多使用299k。也即299*1024byte
Intentintent=newIntent(MediaStore.ACTION_VIDEO_CAPTURE); startActivityForResult(intent,REQUEST_CODE_TAKE_VIDEO);
caseE:
MediaSelectListActivity.ADD_SOUND
MessageUtils.selectAudio(this,REQUEST_CODE_ATTACH_SOUND); Intentintent=newIntent(RingtoneManager.ACTION_RINGTONE_PICKER);
caseF:
MediaSelectListActivity.RECORD_SOUND
像B那样,七个录音机。这次type是aution
Intentintent=newIntent(Intent.ACTION_GET_CONTENT);
intent.setType(ContentType.AUDIO_AMR);
intent.setClassName("com.android.soundrecorder","com.android.soundrecorder.SoundRecorder");
caseG:
MediaSelectListActivity.ADD_SLIDESHOW
幻灯片slideshow比较尴尬。因为整个彩信附件也叫slideshow,而这里的slideshow是多张图片拼凑在一起的意思。彩信的附件也经常是若干张图片。。。这里从起名开始就绕的要死了。
UridataUri=mWorkingMessage.saveAsMms(false); Intentintent=newIntent(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上。对不同的媒体类型有不同的按钮,但是按下之后出口是一样的:
Messagemsg=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。
这个函数进去:
SlideModelslide=mSlideshow.get(0);
MediaModelmedia;
//Removeanypreviousattachments.
slide.removeImage();
slide.removeVideo();
slide.removeAudio();
//Ifwe'rechangingtotext,justbailout.
if(type==TEXT){
return;
}
//MakeacorrectMediaModelforthetypeofattachment.
if(type==IMAGE){
media=newImageModel(mContext,uri,mSlideshow.getLayout()
.getImageRegion());
}elseif(type==VIDEO){
media=newVideoModel(mContext,uri,mSlideshow.getLayout()
.getImageRegion());
}elseif(type==AUDIO){
media=newAudioModel(mContext,uri);
}else{
thrownewIllegalArgumentException("changeMediatype="+type
+",uri="+uri);
}
//Addittotheslide.
slide.add(media);
//Forvideoandaudio,setthedurationoftheslideto
//thatoftheattachment.
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),第二个是添加的新媒体
privatevoidinternalAddOrReplace(MediaModelold,MediaModelmedia){
intaddSize=media.getMediaSize();
intremoveSize;
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(IModelChangedObserverobserver:mModelChangedObservers){
media.registerModelChangedObserver(observer);
}
}
还有个附件太大时的异步缩小功能,是下面这个函数
publicstaticvoidresizeImageAsync(finalContextcontext,
finalUriimageUri,finalHandlerhandler,
finalResizeImageResultCallbackcb,finalbooleanappend){
//Showaprogresstoastiftheresizehasn'tfinished
//withinonesecond.
//Stashtherunnableforshowingitawaysowecancancel
//itlateriftheresizecompletesaheadofthedeadline.
finalRunnableshowProgress=newRunnable(){
publicvoidrun(){
Toast.makeText(context,R.string.compressing,
Toast.LENGTH_SHORT).show();
}
};
//Scheduleitforonesecondfromnow.
handler.postDelayed(showProgress,1000);
newThread(newRunnable(){
publicvoidrun(){
finalPduPartpart;
try{
UriImageimage=newUriImage(context,imageUri);
part=image.getResizedImageAsPart(MmsConfig
.getMaxImageWidth(),MmsConfig.getMaxImageHeight(),
MmsConfig.getMaxMessageSize()-MESSAGE_OVERHEAD);
}finally{
//Cancelpendingshowoftheprogresstoastifnecessary.
handler.removeCallbacks(showProgress);
}
handler.post(newRunnable(){
publicvoidrun(){
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程序设计有所帮助。