• 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>





  • 相关阅读:
    docker4dotnet #1 – 前世今生 & 世界你好
    DockerCon 2016 – 微软带来了什么?
    TFS 2015 敏捷开发实践 – 看板的使用
    几款Git GUI客户端工具
    (视频)Erich Gamma 与 Visual Studio Online 的一点野史
    GitHub + VSTS 开源代码双向同步
    UDAD 用户故事驱动的敏捷开发 – 演讲实录
    用户故事驱动的敏捷开发 – 2. 创建backlog
    算法 之 简单选择排序法
    算法 之 冒泡排序法
  • 原文地址:https://www.cnblogs.com/baiqiantao/p/5433292.html
Copyright © 2020-2023  润新知