zoukankan      html  css  js  c++  java
  • VideoView 视频播放 示例


    介绍
    实现的功能:
    • 可播放本地视频或网络视频,可控制播放或暂停
    • 最小化时保存播放位置及播放状态,resume时恢复所有状态;
    • 横竖屏切换时保持切换前的位置及状态
    • 在屏幕上竖直滑动可调节屏幕亮度和音量
    • 可改变视频显示样式(有bug)
    • 可获取视频缩略图及视频大小

    Activity
    import android.app.Activity;
    import android.content.pm.ActivityInfo;
    import android.content.res.Configuration;
    import android.media.MediaPlayer;
    import android.media.MediaPlayer.OnCompletionListener;
    import android.media.MediaPlayer.OnErrorListener;
    import android.media.MediaPlayer.OnPreparedListener;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Environment;
    import android.util.Log;
    import android.view.GestureDetector;
    import android.view.GestureDetector.OnGestureListener;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.View.OnTouchListener;
    import android.widget.Button;
    import android.widget.MediaController;
    import android.widget.ProgressBar;
    import android.widget.RelativeLayout;
    import android.widget.Toast;
    import android.widget.VideoView;
    public class MainActivity extends Activity implements OnCompletionListener, OnErrorListener, OnPreparedListener, OnTouchListener, OnClickListener,
            OnGestureListener {
        private Button btn_switch;
        private Button btn_start;
        private Button btn_fullscreen;
        private VideoView mVideoView;
        //在 VidioView 外层套一个容器,以在切换屏幕方向的时候对 rl_vv 进行拉伸,而内部的 mVideoView 会依据视频尺寸重新计算宽高。
        //若是直接具体指定了view的宽高,则视频会被拉伸。
        private RelativeLayout rl_vv;
        private ProgressBar progressBar//加载进度条
        private int positionWhenPause = 0;//标记当视频暂停时的播放位置
        private boolean isPlayingWhenPause = false;//标记最小化或横竖屏时是否正在播放
        private GestureDetector mGestureDetector;//手势识别器,用户控制屏幕亮度和音量
        private Uri mVideoUri;
        public static final String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/b.rmvb";//本地路径
        public static final String url = "http://7xt0mj.com1.z0.glb.clouddn.com/lianaidaren.v.640.480.mp4";//网络路径
        public static final String url2 = "http://7xt0mj.com1.z0.glb.clouddn.com/xia.v.1280.720.f4v";
        public static final String url3 = "http://112.253.22.157/17/z/z/y/u/zzyuasjwufnqerzvyxgkuigrkcatxr/hc.yinyuetai.com   /D046015255134077DDB3ACA0D7E68D45.flv";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            progressBar = (ProgressBar) findViewById(R.id.progressBar);
            rl_vv = (RelativeLayout) findViewById(R.id.rl_vv);
            mVideoView = (VideoView) findViewById(R.id.mVideoView);
            btn_switch = (Button) findViewById(R.id.btn_switch);
            btn_start = (Button) findViewById(R.id.btn_start);
            btn_fullscreen = (Button) findViewById(R.id.btn_fullscreen);
            //设置显示控制条
            mVideoView.setMediaController(new MediaController(this));
            mVideoUri = Uri.parse(filePath);
            mVideoView.setVideoURI(mVideoUri);//mVideoView.setVideoPath(url);//这两个方法都可以用来播放网络视频或本地视频
            btn_switch.setOnClickListener(this);
            btn_start.setOnClickListener(this);
            btn_fullscreen.setOnClickListener(this);
            mVideoView.setOnCompletionListener(this);
            mVideoView.setOnErrorListener(this);
            mVideoView.setOnPreparedListener(this);
            mVideoView.setOnTouchListener(this);
            mVideoView.setOnClickListener(this);
            mGestureDetector = new GestureDetector(thisthis);
        }
        @Override
        protected void onResume() {
            super.onResume();
            //如果有保存位置,则跳转到暂停时所保存的那个位置
            if (positionWhenPause > 0) {
                mVideoView.seekTo(positionWhenPause);
                //如果暂停前正在播放,则继续播放,并将播放位置置为0
                if (isPlayingWhenPause) {
                    mVideoView.start();
                    mVideoView.requestFocus();
                    positionWhenPause = 0;
                }
            }
        }
        @Override
        protected void onPause() {
            //如果当前页面暂定,则保存当前播放位置,并记录之前mVideoView是否正在播放
            isPlayingWhenPause = mVideoView.isPlaying();
            positionWhenPause = mVideoView.getCurrentPosition();
            //停止回放视频文件,先获取再stopPlayback()
            mVideoView.stopPlayback();
            super.onPause();
        }
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (null != mVideoViewmVideoView = null;
        }
        @Override
        //横竖屏切换时更改mVideoView的大小
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            if (mVideoView == null) {
                return;
            }
            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {//横屏
                VideoUtils.setActivityFullScreenMode(this);//设置为全屏模式
                getWindow().getDecorView().invalidate();
                //rl_vv.getLayoutParams().width = VideoUtils.getScreenWidth(this);
                rl_vv.getLayoutParams().height = VideoUtils.getScreenHeight(this);
            } else {//竖屏
                VideoUtils.setActivityWindowScreenMode(this);
                rl_vv.getLayoutParams().width = VideoUtils.getScreenWidth(this);
                //rl_vv.getLayoutParams().height = VideoUtils.dp2px(this, 400);
            }
        }
        //***************************************************************************************************************************
        @Override
        public void onPrepared(MediaPlayer mp) {
            try {
                long timeLong = Long.valueOf(VideoUtils.getVideoLength(mVideoUri.toString()));
                Toast.makeText(this"准备好了,时长为 " + VideoUtils.long2Time(timeLong), Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
            }
            //如果文件加载成功,隐藏加载进度条
            progressBar.setVisibility(View.GONE);
        }
        @Override
        public void onCompletion(MediaPlayer mp) {
        }
        @Override
        //视频播放发生错误时回调。如果未指定回调, 或回调函数返回false,mVideoView 会通知用户发生了错误。
        public boolean onError(MediaPlayer mp, int what, int extra) {
            switch (what) {
            case MediaPlayer.MEDIA_ERROR_UNKNOWN:
                Log.e("text""发生未知错误");
                break;
            case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
                Log.e("text""媒体服务器死机");
                break;
            default:
                Log.e("text""onError+" + what);
                break;
            }
            switch (extra) {
            case MediaPlayer.MEDIA_ERROR_IO:
                Log.e("text""文件或网络相关的IO操作错误");
                break;
            case MediaPlayer.MEDIA_ERROR_MALFORMED:
                Log.e("text""比特流编码标准或文件不符合相关规范");
                break;
            case MediaPlayer.MEDIA_ERROR_TIMED_OUT:
                Log.e("text""操作超时");
                break;
            case MediaPlayer.MEDIA_ERROR_UNSUPPORTED:
                Log.e("text""比特流编码标准或文件符合相关规范,但媒体框架不支持该功能");
                break;
            default:
                Log.e("text""onError+" + extra);
                break;
            }
            return true;//经常会碰到视频编码格式不支持的情况,若不想弹出提示框就返回true
        }
        //************************************************************************************************************************************
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return mGestureDetector.onTouchEvent(event);//把Touch事件传递给手势识别器,这一步非常重要!
        }
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btn_start:
                if (mVideoView.isPlaying()) {
                    mVideoView.pause();
                } else {
                    mVideoView.start();//启动视频播放
                    mVideoView.requestFocus();//获取焦点
                }
                break;
            case R.id.btn_switch:
                //横竖屏切换
                if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                } else {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                }
                //            btn_switch.setVisibility(View.INVISIBLE);
                break;
            case R.id.btn_fullscreen:
                VideoUtils.setVideoViewLayoutParams(thismVideoView, VideoUtils.FULL_SCREEN);
                break;
            }
        }
        //************************************************************************************************************************************
        @Override
        //e1代表触摸时的事件,是不变的,e2代表滑动过程中的事件,是时刻变化的
        //distance是当前event2与上次回调时的event2之间的距离,代表上次回调之后到这次回调之前移动的距离
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            float FLING_MIN_BRIGHTNESS = 1.0f * VideoUtils.dp2px(MainActivity.this, 1f);//调节亮度时的敏感度,
            float FLING_MIN_VOICE = 1.0f * VideoUtils.dp2px(MainActivity.this, 5f);//调节声音时的敏感度
            float distance = Math.abs(distanceY);//竖直方向移动范围
            //在屏幕左侧滑动调节亮度,在屏幕右侧滑动调节声音
            if (e1.getX() < VideoUtils.getScreenWidth(this) / 2) {//左侧
                if (distance > FLING_MIN_BRIGHTNESS) {//移动范围满足
                    if (e1.getY() - e2.getY() > 0) {//上滑
                        VideoUtils.setScreenBrightness(this, 15);//亮度增加,第二参数的大小代表着敏感度
                    } else {//下滑
                        VideoUtils.setScreenBrightness(this, -15);
                    }
                }
            } else {//右侧
                if (distance > FLING_MIN_VOICE) {//移动范围满足
                    if (e1.getY() - e2.getY() > 0) {//上滑
                        //VideoUtils.setVoiceVolume(this, 1);//音量增加
                        VideoUtils.setVoiceVolumeAndShowNotification(thistrue);//系统自动控制音量增加减小级别
                    } else {//下滑
                        //    VideoUtils.setVoiceVolume(this, -1);
                        VideoUtils.setVoiceVolumeAndShowNotification(thisfalse);
                    }
                }
            }
            return true;
        }
        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return true;
        }
        @Override
        public void onLongPress(MotionEvent e) {
        }
        @Override
        public void onShowPress(MotionEvent e) {
        }
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return false;
        }
    }

    工具
    import java.lang.reflect.Method;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.PixelFormat;
    import android.graphics.drawable.Drawable;
    import android.media.AudioManager;
    import android.media.MediaMetadataRetriever;
    import android.media.ThumbnailUtils;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.os.Build;
    import android.provider.MediaStore.Video;
    import android.provider.Settings;
    import android.provider.Settings.SettingNotFoundException;
    import android.util.Log;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.RelativeLayout;
    import android.widget.RelativeLayout.LayoutParams;
    import android.widget.VideoView;
    public class VideoUtils {
        /** 
         * 根据手机的分辨率从 dp或 sp 的单位 转成为 px
         */
        public static int dp2px(Context context, float dpValue) {
            float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
        /** 
        * 根据手机的分辨率从 px 的单位转成为 dp 或 sp
        */
        public static int px2dp(Context context, float pxValue) {
            float scale = context.getResources().getDisplayMetrics().density;
            return (int) (pxValue / scale + 0.5f);
        }
        /**
        * 获取屏幕高度
        */
        public static int getScreenHeight(Context context) {
            return context.getResources().getDisplayMetrics().heightPixels;
        }
        /**
         * 获取屏幕宽度
         */
        public static int getScreenWidth(Context context) {
            return context.getResources().getDisplayMetrics().widthPixels;
        }
        /**
         * 设置Activity为全屏模式
         */
        public static void setActivityFullScreenMode(Activity context) {
            context.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }
        /**
         * 设置Activity为窗口模式???
         */
        public static void setActivityWindowScreenMode(Activity context) {
            WindowManager.LayoutParams attrs = context.getWindow().getAttributes();
            attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
            context.getWindow().setAttributes(attrs);
            context.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
        }
        //********************************************************************************************************************
        public static final int FULL_SCREEN = 1;//全屏拉伸模式
        public static final int SCREEN_WINDOW = 2;//指定大小模式
        public static final int SCREEN_WINDOW_ADAPT = 3;//自适应宽高模式
        /**
         * 设置VideoView的全屏和窗口模式。<br>
         * 全屏拉伸模式 : {@link #FULL_SCREEN} <br>
         * 指定大小模式: {@link #SCREEN_WINDOWE}<br>
         * 自适应宽高模式 : {@link #SCREEN_WINDOW_ADAPT}
         * 这里有很多bug******************************************************************************************************************************************************
         */
        public static void setVideoViewLayoutParams(Activity context, VideoView mVideoView, int paramsType) {
            int width, height;
            switch (paramsType) {
            case FULL_SCREEN:
                setActivityFullScreenMode(context);
                RelativeLayout.LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                ((View) mVideoView.getParent()).setLayoutParams(layoutParams);//布局里我们给VideoView设置了一个父布局
                mVideoView.setLayoutParams(layoutParams);
                break;
            case SCREEN_WINDOW:
                width = getScreenWidth(context) * 2 / 3;
                height = VideoUtils.getScreenHeight(context) * 2 / 3;
                RelativeLayout.LayoutParams LayoutParams = new LayoutParams(width, height);
                LayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
                mVideoView.setLayoutParams(LayoutParams);
                break;
            default://先获取VideoView中资源的大小,然后分别和VideoView控件的大小作对比,当资源宽高大于控件时,缩小,否则放大。
                //和加载图片一个样,但是VideoView没有scaleType塑性
                int videoWidth = mVideoView.getWidth();
                int videoHeight = mVideoView.getHeight();
                break;
            }
        }
        //********************************************************************************************************************
        /**
         * 获取屏幕亮度模式,返回-1代表没有获取到
         * 自动调节:Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC=1
         * 手动调节:SCREEN_BRIGHTNESS_MODE_MANUAL=0
         */
        public static int getScreenBrightnessMode(Context context) {
            int screenMode = -1;
            try {
                screenMode = Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE);
            } catch (SettingNotFoundException e) {
                e.printStackTrace();
            }
            return screenMode;
        }
        /**
         * 设置屏幕亮度模式
         * 自动调节:Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC=1
         * 手动调节:SCREEN_BRIGHTNESS_MODE_MANUAL=0
         */
        public static void setScreenBrightnessMode(Context context, int value) {
            Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, value);
        }
        /**
         * 获取屏幕亮度,获取失败返回-1
         */
        public static int getScreenBrightness(Context context) {
            int bright = -1;
            try {
                bright = Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);
            } catch (SettingNotFoundException e) {
                e.printStackTrace();
            }
            return bright;
        }
        /**
         * 增加或减小当前屏幕亮度,并在整个系统上生效
        */
        public static void setScreenBrightness(Activity context, float value) {
            //设置当前【activity】的屏幕亮度
            Window mWindow = context.getWindow();
            WindowManager.LayoutParams mParams = mWindow.getAttributes();//注意:它的值是从0到1,亮度从暗到全亮
            mParams.screenBrightness += value / 255.0F;
            if (mParams.screenBrightness > 1) {//设置大于1的值后,虽然获取到的此参数的值被改了,但系统并不使用此值而是使用某一指定值设置亮度
                mParams.screenBrightness = 1;
            } else if (mParams.screenBrightness < 0.01) {
                mParams.screenBrightness = 0.01f;
            }
            mWindow.setAttributes(mParams);
            // 保存设置为【系统】屏幕亮度值。注意它的值是0-255
            int newValue = (int) (mParams.screenBrightness * 255.0F + value);// 或者= (int) (getScreenBrightness(context) + value);
            if (newValue > 255) newValue = 255;
            else if (newValue < 0) newValue = 0;
            Log.i("bqt""亮度=" + mParams.screenBrightness + ",亮度=" + newValue);
            Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, newValue);
        }
        //********************************************************************************************************************
        /**
         * 设置铃声模式
         * @param mode 声音模式:AudioManager.RINGER_MODE_NORMAL;静音模式:_SILENT;震动模式:_VIBRATE
         */
        public static void setRingerMode(Context context, int mode) {
            AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            mAudioManager.setRingerMode(mode);
        }
        /**
         * 增加或减小媒体音量
         */
        public static void setVoiceVolume(Context context, int value) {
            AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            // 注意:分为静音(0),震动(0),1--7 共九个等级。从静音调为1时,需要调大两个等级;从1调为0时,手机将调整为“震动模式”
            int currentVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
            //尼玛,我获得的最大值是15
            int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
            int newVolume = currentVolume + value;
            if (newVolume > maxVolume) {
                newVolume = maxVolume;
            } else if (newVolume < 0) {
                newVolume = 0;
            }
            Log.i("bqt""音量=" + newVolume);
            mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, newVolume, 0);
        }
        /**
         * 增加或减小媒体音量,并且显示系统音量控制提示条
         */
        public static void setVoiceVolumeAndShowNotification(Context context, boolean isAddVolume) {
            AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            if (isAddVolume) {
                //参数:声音类型,调整音量的方向(只能是增加、减小、不变),可选的标志位(不知道有卵用)
                //音乐:AudioManager.STREAM_MUSIC;通话:_VOICE_CALL;系统:_SYSTEM;铃声:_RING;提示音:_NOTIFICATION;闹铃:_ALARM
                mAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, AudioManager.FX_FOCUS_NAVIGATION_UP);
            } else {
                mAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, AudioManager.FX_FOCUS_NAVIGATION_UP);
            }
            Log.i("bqt""音量=" + mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
        }
        //********************************************************************************************************************
        /**
         * 获取视频长度,获取网络视频长度时异常!
         */
        public static String getVideoLength(String filePath) {
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            retriever.setDataSource(filePath);
            String length = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
            return length;
        }
        /**
         * 毫秒值装换为时分秒形式
         */
        @SuppressWarnings("deprecation")
        public static String long2Time(long timeLong) {
            Date date = new Date(timeLong);
            date.setHours(date.getHours() - 8); //沃日,我们这里比标准时长快了八个小时
            SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss ");
            return format.format(date);
        }
        /**
         * 获取视频缩略图
         * @param filePath 视频文件的路径
         */
        public static Bitmap createVideoThumbnail(String filePath) {
            return ThumbnailUtils.createVideoThumbnail(filePath, Video.Thumbnails.MINI_KIND);
        }
        /**
        * 获取视频的缩略图
        * 先通过ThumbnailUtils来创建一个视频的缩略图,然后再利用ThumbnailUtils来生成指定大小的缩略图。
        * 如果想要的缩略图的宽和高都小于MICRO_KIND,则类型要使用MICRO_KIND作为kind的值,这样会节省内存。
        * @param videoPath 视频的路径
        * @param width 指定输出视频缩略图的宽度
        * @param height 指定输出视频缩略图的高度度
        * @param kind 参照Thumbnails类中的常量MINI_KIND(512 x 384) 和 MICRO_KIND(96 x 96)
        */
        public static Bitmap getVideoThumbnail(String videoPath, int width, int height, int kind) {
            // 获取视频的缩略图
            Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
            bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
            return bitmap;
        }
        /**
         * 利用反射的方式获取视频缩略图,不建议使用
         * @param filePath 视频文件的路径
         */
        public static Bitmap createVideoThumbnail2(String filePath) {
            Class<?> clazz = null;
            Object instance = null;
            try {
                clazz = Class.forName("android.media.MediaMetadataRetriever");
                instance = clazz.newInstance();
                Method method = clazz.getMethod("setDataSource", String.class);
                method.invoke(instance, filePath);
                if (Build.VERSION.SDK_INT <= 9) {
                    return (Bitmap) clazz.getMethod("captureFrame").invoke(instance);
                } else {
                    byte[] data = (byte[]) clazz.getMethod("getEmbeddedPicture").invoke(instance);
                    if (data != null) {
                        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                        if (bitmap != nullreturn bitmap;
                    }
                    return (Bitmap) clazz.getMethod("getFrameAtTime").invoke(instance);
                }
            } catch (Exception ex) {
            } finally {
                try {
                    if (instance != null) {
                        clazz.getMethod("release").invoke(instance);
                    }
                } catch (Exception ignored) {
                }
            }
            return null;
        }
        /**
         * 将Drawable转化为Bitmap
         */
        public static Bitmap drawableToBitmap(Drawable drawable) {
            // 取 drawable 的长宽,颜色格式  
            int w = drawable.getIntrinsicWidth();
            int h = drawable.getIntrinsicHeight();
            Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
            // 创建对应 bitmap
            Bitmap bitmap = Bitmap.createBitmap(w, h, config);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, w, h);
            drawable.draw(canvas);
            return bitmap;
        }
        //********************************************************************************************************************
        public static final int NETWORK_TYPE_INVALID = 0;
        public static final int NETWORK_TYPE_MOBILE = 1;
        public static final int NETWORK_TYPE_WIFI = 2;
        /**
         * 获取当前网络连接状况
         * 网络不可用 : {@link #NETWORK_TYPE_INVALID} <br>
         * 蜂窝网络(手机流量) : {@link #NETWORK_TYPE_MOBILE}<br>
         * WIFI连接 : {@link #NETWORK_TYPE_WIFI}
         */
        public static int getNetworkType(Context context) {
            ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = manager.getActiveNetworkInfo();
            if (networkInfo != null && networkInfo.isConnected()) {
                String type = networkInfo.getTypeName();
                if (type.equalsIgnoreCase("WIFI")) {
                    return NETWORK_TYPE_WIFI;
                } else if (type.equalsIgnoreCase("MOBILE")) {
                    return NETWORK_TYPE_MOBILE;
                }
            }
            return NETWORK_TYPE_INVALID;
        }
    }

    布局
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#300f"
        android:padding="5dp" >
        <RelativeLayout
            android:id="@+id/rl_vv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_weight="2016"
            android:background="#30f0"
            android:minHeight="200dp"
            android:padding="5dp" >
            <VideoView
                android:id="@+id/mVideoView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:padding="5dp" />
        </RelativeLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:orientation="horizontal" >
            <Button
                android:id="@+id/btn_start"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="播放/暂停" />
            <Button
                android:id="@+id/btn_switch"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="横竖屏切换" />
            <Button
                android:id="@+id/btn_fullscreen"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="全屏" />
        </LinearLayout>
        <ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true" />
    </RelativeLayout>

    清单文件
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.bqt.videoview"
        android:versionCode="1"
        android:versionName="1.0" >
        <uses-sdk
            android:minSdkVersion="17"
            android:targetSdkVersion="21" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <!-- 网络权限 -->
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <!-- 滑动改变屏幕亮度/音量 -->
        <uses-permission android:name="android.permission.WRITE_SETTINGS" />
        <uses-permission android:name="android.permission.VIBRATE" />
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".MainActivity"
                android:configChanges="keyboard|orientation|screenSize"
                android:label="@string/app_name"
                android:theme="@style/Theme.AppCompat.Light.NoActionBar" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN/>
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>





  • 相关阅读:
    (Good Bye 2019) Codeforces 1270B Interesting Subarray
    (Good Bye 2019) Codeforces 1270A Card Game
    Codeforces 1283D Christmas Trees(BFS)
    Codeforces 1283C Friends and Gifts
    Codeforces 1283B Candies Division
    1095 Cars on Campus (30)
    1080 Graduate Admission (30)
    1099 Build A Binary Search Tree (30)
    1018 Public Bike Management (30)
    1087 All Roads Lead to Rome (30)
  • 原文地址:https://www.cnblogs.com/baiqiantao/p/5433292.html
Copyright © 2011-2022 走看看