├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── huang │ │ └── videoview │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── 404.html │ │ └── empty_none.png │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── huang │ │ │ └── videoview │ │ │ ├── MainActivity.java │ │ │ ├── utils │ │ │ ├── NetUtils.java │ │ │ └── StatusUtils.java │ │ │ └── webview │ │ │ ├── MeWebView.java │ │ │ ├── WebHelper.java │ │ │ └── WebViewCallback.java │ └── res │ │ ├── layout │ │ ├── activity_esw_video.xml │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── ids.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── example │ └── huang │ └── videoview │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.example.huang.videoview" 8 | minSdkVersion 15 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'io.reactivex:rxandroid:1.1.0' 28 | compile 'io.reactivex:rxjava:1.1.0' 29 | compile 'com.android.support:appcompat-v7:25.3.1' 30 | testCompile 'junit:junit:4.12' 31 | } 32 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\huang\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/huang/videoview/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.huang.videoview; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.example.huang.videoview", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 68 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /app/src/main/assets/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 网络异常 6 | 7 | 8 | 9 |
10 |
11 |
该页面飞到月球了!
12 |
13 |
请检查网络连接
14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/assets/empty_none.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangyanbin/androidVideoWebView/f0d7ee9bff52669f787be39c55c1a850b1972715/app/src/main/assets/empty_none.png -------------------------------------------------------------------------------- /app/src/main/java/com/example/huang/videoview/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.huang.videoview; 2 | 3 | import android.content.Intent; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.os.Bundle; 6 | import android.view.KeyEvent; 7 | import android.view.View; 8 | import android.widget.Button; 9 | import android.widget.EditText; 10 | 11 | import com.example.huang.videoview.webview.MeWebView; 12 | import com.example.huang.videoview.webview.WebHelper; 13 | import com.example.huang.videoview.webview.WebViewCallback; 14 | 15 | public class MainActivity extends AppCompatActivity implements WebViewCallback,View.OnClickListener{ 16 | private MeWebView webView; 17 | private Button mBtn; 18 | private EditText mEt; 19 | private Button mOpenBtn; 20 | 21 | @Override 22 | protected void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.activity_main); 25 | webView = (MeWebView) findViewById(R.id.webView); 26 | mBtn = (Button)findViewById(R.id.button); 27 | mOpenBtn = (Button)findViewById(R.id.button2); 28 | mEt = (EditText)findViewById(R.id.et); 29 | mBtn.setOnClickListener(this); 30 | 31 | mOpenBtn.setOnClickListener(this); 32 | webView.setWebHelper(new WebHelper()); 33 | webView.setWebViewCallback(this); 34 | webView.loadUrl("http://193.28.20.62:8889/artVideo"); 35 | } 36 | 37 | @Override 38 | public void onPageStart(String url) { 39 | mEt.setText(url); 40 | } 41 | 42 | @Override 43 | public void onPageEnd() { 44 | 45 | } 46 | 47 | @Override 48 | public void onPageProgress(int progress) { 49 | 50 | } 51 | 52 | @Override 53 | public void onLoadUrl(String url) { 54 | 55 | } 56 | 57 | @Override 58 | public void onReceivedTitle(String title) { 59 | 60 | } 61 | 62 | @Override 63 | protected void onDestroy() { 64 | super.onDestroy(); 65 | webView.onDestroy(); 66 | } 67 | 68 | @Override 69 | public void onClick(View v) { 70 | if(v.getId() == R.id.button) { 71 | webView.loadUrl(mEt.getText().toString()); 72 | }else { 73 | Intent i = new Intent(this,EswVideoActivity.class); 74 | startActivity(i); 75 | } 76 | } 77 | 78 | @Override 79 | public boolean onKeyDown(int keyCode, KeyEvent event) { 80 | if (event.getAction() == KeyEvent.ACTION_DOWN) { 81 | if (keyCode == KeyEvent.KEYCODE_BACK) { //表示按返回键 时的操作 82 | // 监听到返回按钮点击事件 83 | if(webView.goWebBack()){ 84 | return true; 85 | } 86 | } 87 | } 88 | return super.onKeyDown(keyCode,event); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/huang/videoview/utils/NetUtils.java: -------------------------------------------------------------------------------- 1 | package com.example.huang.videoview.utils; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.ConnectivityManager; 6 | import android.net.NetworkInfo; 7 | import android.os.Build; 8 | 9 | public class NetUtils { 10 | 11 | // 判断网络连接状态 12 | public static boolean isNetworkConnected(Context context) { 13 | if (context != null) { 14 | ConnectivityManager mConnectivityManager = (ConnectivityManager) context 15 | .getSystemService(Context.CONNECTIVITY_SERVICE); 16 | NetworkInfo mNetworkInfo = mConnectivityManager 17 | .getActiveNetworkInfo(); 18 | if (mNetworkInfo != null) { 19 | return mNetworkInfo.isAvailable(); 20 | } 21 | } 22 | return false; 23 | } 24 | 25 | // 判断wifi状态 26 | public static boolean isWifiConnected(Context context) { 27 | if (context != null) { 28 | ConnectivityManager mConnectivityManager = (ConnectivityManager) context 29 | .getSystemService(Context.CONNECTIVITY_SERVICE); 30 | NetworkInfo mWiFiNetworkInfo = mConnectivityManager 31 | .getNetworkInfo(ConnectivityManager.TYPE_WIFI); 32 | if (mWiFiNetworkInfo != null) { 33 | return mWiFiNetworkInfo.isAvailable(); 34 | } 35 | } 36 | return false; 37 | } 38 | 39 | // 判断移动网络 40 | public static boolean isMobileConnected(Context context) { 41 | if (context != null) { 42 | ConnectivityManager mConnectivityManager = (ConnectivityManager) context 43 | .getSystemService(Context.CONNECTIVITY_SERVICE); 44 | NetworkInfo mMobileNetworkInfo = mConnectivityManager 45 | .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); 46 | if (mMobileNetworkInfo != null) { 47 | return mMobileNetworkInfo.isAvailable(); 48 | } 49 | } 50 | return false; 51 | } 52 | 53 | // 获取连接类型 54 | public static int getConnectedType(Context context) { 55 | if (context != null) { 56 | ConnectivityManager mConnectivityManager = (ConnectivityManager) context 57 | .getSystemService(Context.CONNECTIVITY_SERVICE); 58 | NetworkInfo mNetworkInfo = mConnectivityManager 59 | .getActiveNetworkInfo(); 60 | if (mNetworkInfo != null && mNetworkInfo.isAvailable()) { 61 | return mNetworkInfo.getType(); 62 | } 63 | } 64 | return -1; 65 | } 66 | 67 | /** 68 | * 设置网络 69 | * 70 | * @param paramContext 71 | */ 72 | public static void startToSettings(Context paramContext) { 73 | if (paramContext == null) 74 | return; 75 | try { 76 | if (Build.VERSION.SDK_INT > 16) { 77 | paramContext.startActivity(new Intent( 78 | "android.settings.SETTINGS")); 79 | return; 80 | } 81 | } catch (Exception localException) { 82 | localException.printStackTrace(); 83 | return; 84 | } 85 | paramContext.startActivity(new Intent( 86 | "android.settings.WIRELESS_SETTINGS")); 87 | } 88 | 89 | /** 90 | * 获取当前网络状态 91 | **/ 92 | public static String getNetState(Context context){ 93 | try { 94 | ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 95 | //mobile 3G Data Network 96 | NetworkInfo.State mobile = conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState(); 97 | String mobilestate = mobile.toString(); //3G网络连接状态 98 | //wifi 99 | NetworkInfo.State wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState(); 100 | String wifistate = wifi.toString(); //wifi连接状态 101 | if(mobilestate.equals("CONNECTED")) { 102 | return "mobile"; 103 | } else if(wifistate.equals("CONNECTED")) { 104 | return "wifi"; 105 | } else { 106 | return "null"; 107 | } 108 | } catch (Exception e) { 109 | return "avd"; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/huang/videoview/utils/StatusUtils.java: -------------------------------------------------------------------------------- 1 | package com.example.huang.videoview.utils; 2 | 3 | import android.annotation.TargetApi; 4 | import android.app.Activity; 5 | import android.os.Build; 6 | import android.view.View; 7 | import android.view.Window; 8 | import android.view.WindowManager; 9 | 10 | import java.lang.reflect.Field; 11 | import java.lang.reflect.Method; 12 | 13 | /** 14 | * Created by David on 2017/1/4. 15 | */ 16 | 17 | public class StatusUtils { 18 | 19 | //白色可以替换成其他浅色系 20 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 21 | public static void setBarStatusWhite(Activity activity, int statusColor) { 22 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 23 | if (MIUISetStatusBarLightMode(activity.getWindow(), true)) {//MIUI 24 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 25 | activity.getWindow().setStatusBarColor(statusColor); 26 | } 27 | } else if (FlymeSetStatusBarLightMode(activity.getWindow(), true)) {//Flyme 28 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 29 | activity.getWindow().setStatusBarColor(statusColor); 30 | } 31 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//6.0 32 | activity.getWindow().setStatusBarColor(statusColor); 33 | activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); 34 | } 35 | } 36 | } 37 | 38 | /** 39 | * 隐藏状态栏 40 | * @param activity 41 | */ 42 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 43 | public static void hideStatusBar(Activity activity){ 44 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 45 | View decorView = activity.getWindow().getDecorView(); 46 | decorView.setSystemUiVisibility( 47 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE 48 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 49 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 50 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 51 | | View.SYSTEM_UI_FLAG_FULLSCREEN 52 | | View.SYSTEM_UI_FLAG_IMMERSIVE); 53 | } 54 | } 55 | 56 | 57 | 58 | /** 59 | * 显示状态栏 60 | * @param activity 61 | */ 62 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 63 | public static void showStatusBar(Activity activity){ 64 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 65 | View decorView = activity.getWindow().getDecorView(); 66 | if(decorView != null && decorView.getSystemUiVisibility() != View.SYSTEM_UI_FLAG_VISIBLE) { 67 | decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); 68 | } 69 | } 70 | } 71 | 72 | 73 | /** 74 | * 设置状态栏字体图标为深色,需要MIUIV6以上 75 | * 76 | * @param window 需要设置的窗口 77 | * @param dark 是否把状态栏字体及图标颜色设置为深色 78 | * @return boolean 成功执行返回true 79 | */ 80 | public static boolean MIUISetStatusBarLightMode(Window window, boolean dark) { 81 | boolean result = false; 82 | if (window != null) { 83 | Class clazz = window.getClass(); 84 | try { 85 | int darkModeFlag = 0; 86 | Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams"); 87 | Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE"); 88 | darkModeFlag = field.getInt(layoutParams); 89 | Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class); 90 | if (dark) { 91 | extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体 92 | } else { 93 | extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体 94 | } 95 | result = true; 96 | } catch (Exception e) { 97 | 98 | } 99 | } 100 | return result; 101 | } 102 | 103 | /** 104 | * 设置状态栏图标为深色和魅族特定的文字风格 105 | * 可以用来判断是否为Flyme用户 106 | * 107 | * @param window 需要设置的窗口 108 | * @param dark 是否把状态栏字体及图标颜色设置为深色 109 | * @return boolean 成功执行返回true 110 | */ 111 | public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) { 112 | boolean result = false; 113 | if (window != null) { 114 | try { 115 | WindowManager.LayoutParams lp = window.getAttributes(); 116 | Field darkFlag = WindowManager.LayoutParams.class 117 | .getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON"); 118 | Field meizuFlags = WindowManager.LayoutParams.class 119 | .getDeclaredField("meizuFlags"); 120 | darkFlag.setAccessible(true); 121 | meizuFlags.setAccessible(true); 122 | int bit = darkFlag.getInt(null); 123 | int value = meizuFlags.getInt(lp); 124 | if (dark) { 125 | value |= bit; 126 | } else { 127 | value &= ~bit; 128 | } 129 | meizuFlags.setInt(lp, value); 130 | window.setAttributes(lp); 131 | result = true; 132 | } catch (Exception e) { 133 | 134 | } 135 | } 136 | return result; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/huang/videoview/webview/MeWebView.java: -------------------------------------------------------------------------------- 1 | package com.example.huang.videoview.webview; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.app.Activity; 5 | import android.content.Context; 6 | import android.content.pm.ActivityInfo; 7 | import android.graphics.Bitmap; 8 | import android.os.Build; 9 | import android.util.AttributeSet; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.webkit.CookieManager; 13 | import android.webkit.JavascriptInterface; 14 | import android.webkit.WebChromeClient; 15 | import android.webkit.WebSettings; 16 | import android.webkit.WebView; 17 | import android.webkit.WebViewClient; 18 | 19 | 20 | 21 | public class MeWebView extends WebView { 22 | 23 | private WebViewCallback callback; 24 | private boolean isPauseVideo; // webView onPause 是否暂停了视频播放 25 | private boolean isError; 26 | private WebHelper mWebHelper; 27 | 28 | @SuppressLint("SetJavaScriptEnabled") 29 | public MeWebView(Context arg0, AttributeSet arg1) { 30 | super(arg0, arg1); 31 | 32 | initWebViewSettings(); 33 | setWebChromeClient(new CustomWebViewChromeClient()); 34 | setWebViewClient(new CustomWebClient()); 35 | addJavascriptInterface(new JsObject(), "onClick"); 36 | 37 | } 38 | 39 | public WebHelper getWebHelper() { 40 | return mWebHelper; 41 | } 42 | 43 | public void setWebHelper(WebHelper webHelper) { 44 | this.mWebHelper = webHelper; 45 | 46 | } 47 | 48 | @Override 49 | public void loadUrl(String s) { 50 | if(this.callback !=null){ 51 | callback.onLoadUrl(s); 52 | } 53 | super.loadUrl(s); 54 | } 55 | 56 | private class JsObject { 57 | 58 | 59 | @JavascriptInterface 60 | public void videoPause(){ 61 | //activity暂停时是否Video也暂停了 62 | isPauseVideo = true; 63 | } 64 | 65 | } 66 | 67 | private class CustomWebViewChromeClient extends WebChromeClient { 68 | 69 | @Override 70 | public void onShowCustomView(View view, CustomViewCallback callback) { 71 | // fullScreen(); 72 | if(mWebHelper != null && getContext() != null){ 73 | mWebHelper.showContainerView(MeWebView.this,(Activity) getContext(),view); 74 | // 横屏显示 75 | ((Activity) getContext()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 76 | // 设置全屏 77 | mWebHelper.setFullScreen((Activity) getContext()); 78 | } 79 | 80 | 81 | super.onShowCustomView(view, callback); 82 | } 83 | 84 | @Override 85 | public void onProgressChanged(WebView webView, int i) { 86 | super.onProgressChanged(webView, i); 87 | if (callback != null) { 88 | callback.onPageProgress(i); 89 | } 90 | } 91 | 92 | @Override 93 | public void onReceivedTitle(WebView arg0, final String title) { 94 | super.onReceivedTitle(arg0, title); 95 | if (callback != null) { 96 | callback.onReceivedTitle(title); 97 | } 98 | 99 | } 100 | 101 | 102 | @Override 103 | public void onHideCustomView() { 104 | fullScreen(); 105 | if(mWebHelper != null && getContext() != null){ 106 | ((Activity) getContext()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 107 | mWebHelper.hideContainerView((Activity) getContext()); 108 | // 横屏显示 109 | // 设置全屏 110 | mWebHelper.quitFullScreen((Activity) getContext()); 111 | } 112 | super.onHideCustomView(); 113 | } 114 | } 115 | 116 | private void fullScreen() { 117 | /* if(mWebHelper != null&& getContext() != null){ 118 | mWebHelper.fullScreen((Activity) getContext()); 119 | }*/ 120 | /*String fullScreenJs = TagUtils.onFullScreenJs(getUrl()); 121 | if( fullScreenJs !=null){ 122 | loadUrl(fullScreenJs); 123 | }*/ 124 | } 125 | 126 | 127 | 128 | private class CustomWebClient extends WebViewClient { 129 | 130 | @Override 131 | public void onPageFinished(WebView view, String url) { 132 | super.onPageFinished(view, url); 133 | String js = WebHelper.getPlayVideoJS(); 134 | view.loadUrl(js); 135 | 136 | if (callback != null) { 137 | callback.onPageEnd(); 138 | } 139 | } 140 | 141 | 142 | @Override 143 | public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { 144 | loadUrl("file:///android_asset/404.html"); 145 | isError = true; 146 | } 147 | 148 | @Override 149 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 150 | return (!url.startsWith("http") && !url.startsWith("javascript")); //暂时屏蔽掉打开外部请求 151 | } 152 | 153 | 154 | @Override 155 | public void onPageStarted(WebView webView, String s, Bitmap bitmap) { 156 | super.onPageStarted(webView, s, bitmap); 157 | if (callback != null) { 158 | callback.onPageStart(s); 159 | } 160 | } 161 | } 162 | 163 | 164 | private void initWebViewSettings() { 165 | WebSettings ws = getSettings(); 166 | ws.setJavaScriptEnabled(true); 167 | ws.setJavaScriptCanOpenWindowsAutomatically(true); 168 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 169 | ws.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); 170 | } 171 | ws.setPluginState(WebSettings.PluginState.ON); 172 | ws.setRenderPriority(WebSettings.RenderPriority.HIGH); 173 | ws.setLoadWithOverviewMode(true); 174 | ws.setBuiltInZoomControls(true);// 隐藏缩放按钮 175 | ws.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);// 排版适应屏幕 176 | ws.setUseWideViewPort(true);// 可任意比例缩放 177 | ws.setSavePassword(true); 178 | ws.setSaveFormData(true);// 保存表单数据 179 | ws.setDomStorageEnabled(true); 180 | setSaveEnabled(true); 181 | ws.setSupportZoom(false); 182 | ws.setAppCacheMaxSize(1024 * 1024 * 8); 183 | ws.setAllowFileAccess(true); 184 | ws.setAppCacheEnabled(true); 185 | ws.setCacheMode(WebSettings.LOAD_DEFAULT); 186 | ws.setGeolocationEnabled(true); 187 | ws.setDatabaseEnabled(true); 188 | setAcceptThirdPartyCookies(); 189 | 190 | } 191 | 192 | /** 193 | * 设置跨域cookie读取 194 | */ 195 | public final void setAcceptThirdPartyCookies() { 196 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 197 | CookieManager.getInstance().setAcceptThirdPartyCookies(this, true); 198 | } 199 | } 200 | 201 | 202 | 203 | public void onDestroy() { 204 | stopLoading(); 205 | loadUrl(WebHelper.getPauseAudioJS()); 206 | if(mWebHelper != null){ 207 | mWebHelper.cancel(); 208 | } 209 | try { 210 | if(getParent() != null){ 211 | ((ViewGroup) getParent()).removeView(this); 212 | } 213 | destroy(); 214 | }catch (Exception ignored){ 215 | 216 | } 217 | } 218 | 219 | public boolean goWebBack() { 220 | if (!isError && canGoBack()) { 221 | goBack(); 222 | return true; 223 | } 224 | return false; 225 | } 226 | 227 | 228 | 229 | 230 | @Override 231 | public boolean canGoBack() { 232 | return !isError && super.canGoBack(); 233 | } 234 | 235 | @Override 236 | public void onPause() { 237 | loadUrl(WebHelper.getPauseVideoJS()); 238 | super.onPause(); 239 | } 240 | 241 | @Override 242 | public void onResume() { 243 | if(isPauseVideo) { 244 | loadUrl(WebHelper.getPlayVideoJS()); 245 | isPauseVideo = false; 246 | } 247 | super.onResume(); 248 | } 249 | 250 | 251 | 252 | public WebViewCallback getWebViewCallback() { 253 | return callback; 254 | } 255 | 256 | public void setWebViewCallback(WebViewCallback webViewCallback) { 257 | callback = webViewCallback; 258 | 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/huang/videoview/webview/WebHelper.java: -------------------------------------------------------------------------------- 1 | package com.example.huang.videoview.webview; 2 | 3 | import android.annotation.TargetApi; 4 | import android.app.Activity; 5 | import android.os.Build; 6 | import android.support.v4.content.ContextCompat; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.view.Window; 10 | import android.view.WindowManager; 11 | import android.webkit.WebView; 12 | import android.widget.FrameLayout; 13 | 14 | 15 | 16 | 17 | import com.example.huang.videoview.R; 18 | 19 | 20 | /** 21 | * Created by David on 2017/3/31. 22 | */ 23 | 24 | public class WebHelper implements View.OnSystemUiVisibilityChangeListener { 25 | 26 | private static final int AUTO_HIDE_DELAY_SECOND = 2; 27 | private FrameLayout mContainerView; 28 | private boolean isFullScreen; 29 | 30 | 31 | 32 | public WebHelper() { 33 | 34 | } 35 | 36 | 37 | 38 | /** 39 | * 得到视频全屏播放View 40 | */ 41 | private FrameLayout getContainerView(Activity activity) { 42 | 43 | if (mContainerView == null) { 44 | FrameLayout decorView = getDecorView(activity); 45 | if (decorView != null) { 46 | decorView.setOnSystemUiVisibilityChangeListener(this); 47 | FrameLayout container = (FrameLayout) decorView.findViewById(R.id.videoContainer); 48 | if (container == null) { 49 | container = new FrameLayout(activity); 50 | FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 51 | ViewGroup.LayoutParams.MATCH_PARENT); 52 | container.setBackgroundColor(ContextCompat.getColor(activity, R.color.black)); 53 | container.setId(R.id.videoContainer); 54 | container.setLayoutParams(lp); 55 | decorView.addView(container); 56 | } 57 | mContainerView = container; 58 | } 59 | } 60 | return mContainerView; 61 | } 62 | 63 | /** 64 | * 显示WebView播放视频界面 65 | * 66 | * @param activity 67 | * @param videoView 68 | * @return 69 | */ 70 | public boolean showContainerView(WebView webView, Activity activity, View videoView) { 71 | FrameLayout container = getContainerView(activity); 72 | if (container != null) { 73 | container.setVisibility(View.VISIBLE); 74 | FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 75 | ViewGroup.LayoutParams.MATCH_PARENT); 76 | videoView.setLayoutParams(lp); 77 | container.addView(videoView); 78 | // hideStatusBar(activity); 79 | isFullScreen = true; 80 | return true; 81 | } 82 | return false; 83 | } 84 | 85 | 86 | /** 87 | * 隐藏WebView播放视频界面 88 | * 89 | * @param activity 90 | * @return 91 | */ 92 | public boolean hideContainerView(Activity activity) { 93 | 94 | FrameLayout container = getContainerView(activity); 95 | if (container != null) { 96 | isFullScreen = false; 97 | container.removeAllViews(); 98 | container.setVisibility(View.GONE); 99 | //showStatusBar(activity); 100 | return true; 101 | } 102 | return false; 103 | } 104 | 105 | /* *//** 106 | * 全屏回调 107 | * 108 | * @param activity 109 | *//* 110 | public void fullScreen(Activity activity) { 111 | if (activity != null) { 112 | if (activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { 113 | activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 114 | } else { 115 | activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 116 | } 117 | } 118 | }*/ 119 | 120 | /** 121 | * 设置全屏 122 | */ 123 | public void setFullScreen(Activity activity) { 124 | // 设置全屏的相关属性,获取当前的屏幕状态,然后设置全屏 125 | if (activity != null) { 126 | activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 127 | WindowManager.LayoutParams.FLAG_FULLSCREEN); 128 | } 129 | } 130 | 131 | /** 132 | * 退出全屏 133 | */ 134 | public void quitFullScreen(Activity activity) { 135 | // 声明当前屏幕状态的参数并获取 136 | if (activity != null) { 137 | final WindowManager.LayoutParams attrs =activity.getWindow().getAttributes(); 138 | attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN); 139 | activity.getWindow().setAttributes(attrs); 140 | activity.getWindow() 141 | .clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); 142 | } 143 | } 144 | /** 145 | * 得到Activity根View 146 | * 147 | * @param activity 148 | * @return 149 | */ 150 | private FrameLayout getDecorView(Activity activity) { 151 | 152 | if (activity != null && activity.getWindow() != null) { 153 | Window window = activity.getWindow(); 154 | ViewGroup decorView = (ViewGroup) window.getDecorView().findViewById(android.R.id.content); 155 | if (decorView == null) { 156 | decorView = (ViewGroup) window.getDecorView(); 157 | } 158 | if (decorView != null && decorView instanceof FrameLayout) { 159 | return (FrameLayout) decorView; 160 | } 161 | } 162 | return null; 163 | } 164 | 165 | 166 | 167 | 168 | public void cancel() { 169 | //解绑 170 | 171 | isFullScreen = false; 172 | } 173 | 174 | //状态栏发生变化时 175 | @Override 176 | public void onSystemUiVisibilityChange(int visibility) { 177 | 178 | if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { 179 | if (isFullScreen && mContainerView != null) { 180 | /*hideStatusBarSub = Observable.timer(AUTO_HIDE_DELAY_SECOND, TimeUnit.SECONDS) 181 | .observeOn(AndroidSchedulers.mainThread()) 182 | .subscribeOn(Schedulers.io()) 183 | .subscribe(new Action1() { 184 | @Override 185 | public void call(Long aLong) { 186 | final Activity activity = (Activity) mContainerView.getContext(); 187 | if (activity != null && !activity.isFinishing()) { 188 | StatusUtils.hideStatusBar(activity); 189 | } 190 | } 191 | }); 192 | */ 193 | } 194 | } 195 | } 196 | 197 | 198 | /** 199 | * 隐藏状态栏 200 | * @param activity 201 | */ 202 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 203 | public static void hideStatusBar(Activity activity){ 204 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 205 | View decorView = activity.getWindow().getDecorView(); 206 | decorView.setSystemUiVisibility( 207 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE 208 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 209 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 210 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 211 | | View.SYSTEM_UI_FLAG_FULLSCREEN 212 | | View.SYSTEM_UI_FLAG_IMMERSIVE); 213 | } 214 | } 215 | 216 | 217 | 218 | /** 219 | * 显示状态栏 220 | * @param activity 221 | */ 222 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 223 | public static void showStatusBar(Activity activity){ 224 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 225 | View decorView = activity.getWindow().getDecorView(); 226 | if(decorView != null && decorView.getSystemUiVisibility() != View.SYSTEM_UI_FLAG_VISIBLE) { 227 | decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); 228 | } 229 | } 230 | } 231 | 232 | /** 233 | * 暂停 视频 js(如果暂停了视频则回调,在OnResume时候根据回调判断是否需要继续播放视频) 234 | * @return 235 | */ 236 | public static String getPauseVideoJS() { 237 | return "javascript: var video = document.getElementsByTagName('video'); if(!Array.prototype.isPrototypeOf(video) && video.length != 0){ if(!video[0].paused){video[0].pause();onClick.videoPause();}}"; 238 | } 239 | 240 | /** 241 | * 暂停 audio js 242 | * @return 243 | */ 244 | public static String getPauseAudioJS() { 245 | return "javascript: var audio = document.getElementsByTagName('audio'); if(!Array.prototype.isPrototypeOf(audio) && audio.length != 0){ audio[0].pause();}"; 246 | } 247 | 248 | 249 | 250 | 251 | /** 252 | * 播放视频 js 253 | * @return 254 | */ 255 | public static String getPlayVideoJS() { 256 | return "javascript: var video = document.getElementsByTagName('video'); if(!Array.prototype.isPrototypeOf(video) && video.length != 0){ video[0].play();}"; 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/huang/videoview/webview/WebViewCallback.java: -------------------------------------------------------------------------------- 1 | package com.example.huang.videoview.webview; 2 | 3 | 4 | /** 5 | * Created by David on 2017/2/23. 6 | */ 7 | 8 | public interface WebViewCallback { 9 | 10 | 11 | void onPageStart(String url); 12 | void onPageEnd(); 13 | void onPageProgress(int progress); 14 | void onLoadUrl(String url); 15 | void onReceivedTitle(String title); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_esw_video.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 13 | 14 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 |