MMS附件播放查看与附件保存

Android4.2

1. MediaModel    代表一项附件。实现接口EventListener。

2. SlideModel      代表一页幻灯片。实现接口List<MediaModel>, EventListener

3. SlideshowModel  代表所有幻灯片。实现接口List<SlideModel>, IModelChangedObserver。


SlideshowActivity用于播放幻灯片,在Oncreate中SlideshowModel.createFromMessageUri(this, msg)构建SlideshowModel对象:

通过uri获取PduBody对象,通过PduBody获取SMILLayoutElement,接着解析smil文件。利用MediaModelFactory获取MediaMode

    public static MediaModel getMediaModel(Context context,
            SMILMediaElement sme, LayoutModel layouts, PduBody pb)
并给每一个获取到的MediaModel注册EventListener接口(好像没用,注册者没被引用),最后也把SlideModel给注册了。
                    SmilHelper.addMediaElementEventListeners(
                            (EventTarget) sme, media);
获取所有SlideModel后构建SlideshowModel对象,并注册自己的IModelChangedObserver接口,返回SlideshowModel。


接下来

        mSlideView = (SlideView) findViewById(R.id.slide_view);
        PresenterFactory.getPresenter("SlideshowPresenter", this, mSlideView, model);
在SlideshowPresenter类的构造中调用了父类Presenter的构造并在其中
        mModel = model;
        mModel.registerModelChangedObserver(this);
其中model为SlideShowModel,Presenter实现接口IModelChangedObserver,也就是说把SlideshowPresenter注册到SlideShowModel。

Model注册方法如下:

    public void registerModelChangedObserver(IModelChangedObserver observer) {
        if (!mModelChangedObservers.contains(observer)) {
            mModelChangedObservers.add(observer);
            registerModelChangedObserverInDescendants(observer);
        }
    }
在SlideShowModel中的registerModelChangedObserverInDescendants方法内给所有SlideModel注册了接口:
    protected void registerModelChangedObserverInDescendants(
            IModelChangedObserver observer) {
        mLayout.registerModelChangedObserver(observer);

        for (SlideModel slide : mSlides) {
            slide.registerModelChangedObserver(observer);
        }
    }
而在SlideModel内给所有MediaMode注册了这个observer。

也就是说,SlideShowModel与之内所有要显示的对象都注册了SlideshowPresenter的接口。

调用Model的notifyModelChanged则触发接口的调用,调用到SlideshowPresenter的onModelChanged方法。在onModelChanged方法内根据调用的MediaMode不同对SlideView调用不同的显示。


由前面得知每一个MediaModel的EventListener接口都被注册了,接口方法为handleEvent,而在子MediaModel比如ImageMode中的handleEvent方法中都调用了notifyModelChanged方法。


幻灯片播放流程:

构建播放器SmilPlayer对象。由SlideshowModel获取SMILDocument对象

mSmilDoc = SmilHelper.getDocument(model);

获取过程中对每一个MediaMode注册addMediaElementEventListeners((EventTarget) sme, media);接着初始化播放器

 mSmilPlayer.init(mSmilDoc);
    public synchronized void init(ElementTime root) {
        mRoot = root;
        mAllEntries = getTimeline(mRoot, 0, Long.MAX_VALUE);
        mMediaTimeUpdatedEvent = ((DocumentEvent) mRoot).createEvent("Event");
        mMediaTimeUpdatedEvent.initEvent(MEDIA_TIME_UPDATED_EVENT, false, false);
        mActiveElements = new ArrayList<ElementTime>();
    }
调用SmilPlayer的play方法启动子线程,在run方法里依次播放每一页幻灯片,切换时调用waitForEntry(long interval)方法,此方法内
            ((EventTarget) mRoot).dispatchEvent(mMediaTimeUpdatedEvent);
分发所有EventListener接口事件。

二、附件的命名及保存

在MmsProvider中进行命名,在PduPersister中进行附件保存。

以saveDraft为开始流程为例:按流程将调用到SlideShowModel的finalResize方法中,此方法调用

PduPersister.getPduPersister(mContext).updateParts(messageUri, pb, null);
开始附件保存流程,其中第三个参数是InputStream的hashMap。在此方法内调用persistPart方法,persistPart方法内
       Uri res = SqliteWrapper.insert(mContext, mContentResolver, uri, values);
接着调用persistData方法保存数据,如果此前传来的InputStream的hashMap不为空,以uri为key获取流,否则以uri通过openInputStream获取流。

文件命名在insert数据时provider中的insert方法中进行,尾字符串为cl字段内容,名称:parts_时间_cl字段内容。


三、ContentProvider的openInputStream与openOutputStream

重写ContentProvider的openFile方法实现这两个功能。如下Mms的provider

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        // TODO do we even need this anymore?
        ParcelFileDescriptor fd;
        int match = sURLMatcher.match(uri);

        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.d(TAG, "openFile: uri=" + uri + ", mode=" + mode);
        }

        switch (match) {
            default:
                fd = openFileHelper(uri, mode);
        }

        return fd;
    }
openFileHelper方法使用"_data"作为文件路径字段,如果自定义字段存储文件路径,则不使用系统提供的openFileHelper方法或者重写此方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值