频道栏目
首页 > 资讯 > 其他 > 正文

videoview实现视频引导页及从assets文件中读取文件到本地SD卡

16-11-15        来源:[db:作者]  
收藏   我要投稿

视频放在assets文件下,这里的文件不会被编辑,但是使用的时候,需要用流转到本地,然后再使用

关于视频的相关测试数据,在文章最后

需要权限:

    
    
    

目录结构:
这里写图片描述
代码:
1、准备工作:
1.1、

import android.os.Environment;

/**
 * 全局变量
 */
public class CHEN {

    // 引导视频存放路径
    public static String GuideVideoSavePath = Environment.getExternalStorageDirectory().getAbsolutePath()
            + "/chen/guide_video/";

    // 引导视频播放路径
    public static String GuideVideoPlayPath = "";

}

1.2、工具类

import android.text.TextUtils;

public class Utils {

    /**
     * 检查字符串是否是空
     *
     * @param str
     * @return true:字符串为空
     */
    public static boolean checkStringIsEmpty(String str) {

        if (TextUtils.isEmpty(str) || "null".equals(str)) {
            return true;
        } else {
            return false;
        }
    }
}

1.3、styles.xml文件下:这个属性给展示视频的activity,让视频全屏播放

2、自定义的videoview(保证能全屏的videoview)

import android.content.Context;
import android.util.AttributeSet;
import android.widget.VideoView;

public class CustomVideoView extends VideoView {

    private Context context;

    public CustomVideoView(Context context) {
        this(context, null);
    }

    public CustomVideoView(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public CustomVideoView(Context context, AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);
        this.context = context;
        init();
    }

    private void init() {
       //do something...
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //重新计算高度。保证全屏显示
        int width = getDefaultSize(0, widthMeasureSpec);
        int height = getDefaultSize(0, heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

}

3、使用:
3.1、一开始的MainActivity,布局文件我不做任何处理,就用新建时默认的就行,核心是下一个展示视频的activity

import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class MainActivity extends Activity {

    private int time = 3000;

    public Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case 100:

                    if (!Utils.checkStringIsEmpty(CHEN.GuideVideoPlayPath)) {
                        //播放视频成功生成了
                        startActivity(new Intent(MainActivity.this, VideoGuideActivity.class));
                        MainActivity.this.finish();
                    } else {
                        //引导视频没有生成
                        //do something...
                    }
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        creatGuideVideo();

        //sendEmptyMessageDelayed(int what, long delayMillis)
        //延时time,发送一个what=100的值
        mHandler.sendEmptyMessageDelayed(100, time);

    }

    /**
     * 创建视频引导页文件
     */
    private void creatGuideVideo() {

        new Thread() {
            public void run() {
                try {

                    File path_file = new File(CHEN.GuideVideoSavePath);
                    if (!path_file.exists()) {
                        try {
                            path_file.mkdirs();
                        } catch (Exception e) {
                            CHEN.GuideVideoPlayPath = "";
                        }
                    }

                    long start = System.currentTimeMillis();

                    //第二个参数是生成的文件的名字(包括后缀名),一般和assets文件中要打开的一致
                    File file = new File(CHEN.GuideVideoSavePath, "../201510/GridViewLiveTiles.html");
                    if (!file.exists()) {
                        AssetManager assetManager = getAssets();// 获取asset管理者
                        InputStream in = null;
                        FileOutputStream out = null;
                        try {
                            //assets文件中要打开的文件的名字(包括后缀名)
                            in = assetManager.open("../201510/GridViewLiveTiles.html");
                            out = new FileOutputStream(file);
                            byte[] b = new byte[1024];
                            int len = -1;
                            while ((len = in.read(b)) != -1) {
                                out.write(b, 0, len);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                            CHEN.GuideVideoPlayPath = "";
                        } finally {
                            if (out != null) {
                                out.close();
                            }
                            if (in != null) {
                                in.close();
                            }

                        }
                    }
                    long end = System.currentTimeMillis();
                    Log.e("创建视频引导页播放视频用时===", "" + (end - start));
                    CHEN.GuideVideoPlayPath = file.getAbsolutePath();
                } catch (Exception e) {
                    CHEN.GuideVideoPlayPath = "";
                }
            }
        }.start();
    }
}

3.2、VideoGuideActivity(为了保证全屏,在清单文件中)

    
    
    
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

/**
 * 视频引导页
 */
public class VideoGuideActivity extends Activity {

    CustomVideoView video_view;
    private int videoIndex = -1;

    /**
     * 监听是否点击了home键将客户端推到后台
     */
    private BroadcastReceiver homeAndLockReceiver = new BroadcastReceiver() {
        String SYSTEM_REASON = "reason";
        String SYSTEM_HOME_KEY = "homekey";

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
                String reason = intent.getStringExtra(SYSTEM_REASON);
                if (TextUtils.equals(reason, SYSTEM_HOME_KEY)) {
                    //表示按了home键,程序到了后台
                    video_view.pause();
                    //得到当前视频播放的位置。单位是毫秒
                    videoIndex = video_view.getCurrentPosition();
                    Log.e("videoIndex", videoIndex + "");
                }
            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                //按下锁屏键
                video_view.pause();
                //得到当前视频播放的位置。单位是毫秒
                videoIndex = video_view.getCurrentPosition();
                Log.e("videoIndex", videoIndex + "");
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.video_guide_layout);

        try {

            //注册广播,监听home键及锁屏键的按下
            IntentFilter filter = new IntentFilter();
            //锁屏广播,由系统发出
            filter.addAction(Intent.ACTION_SCREEN_ON);
            //锁屏广播,由系统发出
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            //点击home键广播,由系统发出
            filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
            registerReceiver(homeAndLockReceiver, filter);
            //注册广播结束

            video_view = (CustomVideoView) findViewById(R.id.video_view);

            /**
             * 视频或者音频到结尾时触发的方法
             */
            video_view.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    doSomething();
                }
            });

            /**
             * 视频或者音频播放出错触发的方法
             */
            video_view.setOnErrorListener(new MediaPlayer.OnErrorListener() {

                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) {
                    doSomething();
                    return false;
                }
            });


            video_view.setVideoURI(Uri.parse(CHEN.GuideVideoPlayPath));
            //播放
            video_view.start();

        } catch (Exception e) {

            doSomething();

        }

    }

    @Override
    protected void onRestart() {
       super.onRestart();
       Log.e("onRestart", videoIndex + "");
       //video_view.start();
       video_view.seekTo(videoIndex == -1 ? 0 : videoIndex);
       //先start,再seekTo,home键回来是重播;先seekTo,再start,都是续播。但是如果距离开始时间较短(经测试,大约10以内,可能有误差),还是会出现重播现象。这些细节,在用的时候,多测试测试。对效果影响不大
       video_view.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (homeAndLockReceiver != null) {
            unregisterReceiver(homeAndLockReceiver);
        }
    }

    //对返回键的监听
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        doSomething();
    }

    /**
     * 播放失败、异常时做的事。一般都是跳转到下个页面
     */
    private void doSomething() {
        //do something...
        Toast.makeText(this, "do something...", Toast.LENGTH_SHORT).show();
    }

}

4、测试数据:
一般的使用视频引导页,之前还会有一个图片启动页,最好在图启动页展示的时候,在本地创建视频,然后在视频引导页直接展示。时间上有要求,既要展示启动页,还要尽可能的给本地生成视频文件留下时间:
我测试了3组数据(单位毫秒):

assets中视频文件大小为5.6M时:
创建视频引导页播放视频用时===: 570

assets中视频文件大小为6.6M时:
创建视频引导页播放视频用时===: 648

assets中视频文件大小为16M时:
创建视频引导页播放视频用时===: 1697

注:我使用的是小米Note,我再使用魅族系列的一个低配手机的时候,出现过一次6.6M视频,在本地创建,时间为2700毫秒左右的情况。同一个手机,每次创建也会有差距,以上数据仅供参考

相关TAG标签
上一篇:Gradle 介绍(二)
下一篇:Gradle 介绍(一)
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站