WebView 播放https 視訊 無法播放 顯示一片白色的問題
阿新 • • 發佈:2019-02-11
佈局檔案如下:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="@+id/fl_video"
android:layout_width="match_parent"
android:layout_height="match_parent"
></FrameLayout >
</FrameLayout>
程式碼如下:
public class VideoActivity extends BaseActivity {
private FrameLayout frameLayout = null;
private WebView webView = null;
private WebChromeClient chromeClient = null;
private View myView = null;
private WebChromeClient.CustomViewCallback myCallBack = null ;
private View customView;
private FrameLayout videolayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video);
initView();
webView.getSettings().setJavaScriptEnabled(true);
//解決webview顯示不全的問題
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.setWebViewClient(new MyWebviewCient());
chromeClient = new MyChromeClient();
webView.setWebChromeClient(chromeClient );
webView.setVisibility(View.VISIBLE);
HttpsTrustManager.allowAllSSL();
webView.setScrollBarStyle(0);// 滾動條風格,為0就是不給滾動條留空間,滾動條覆蓋在網頁上
//webView.getSettings().setLoadsImagesAutomatically(true);// 設定可以自動載入圖片
webView.getSettings().setAppCacheEnabled(true);// 應用可以有快取
// 設定可以支援縮放
// webView.getSettings().setSupportZoom(true);
// 設定出現縮放工具
// webView.getSettings().setBuiltInZoomControls(true);
// webView.getSettings().setLoadWithOverviewMode(true);
//自動開啟視窗
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
// 沒有的話會黑屏 支援外掛
webView.setHorizontalScrollBarEnabled(false);//禁止水平滾動
webView.setVerticalScrollBarEnabled(true);//允許垂直滾動
// 為圖片新增放大縮小功能
//webview.getSettings().setUseWideViewPort(true);
//自適應螢幕
//webView.getSettings().setDomStorageEnabled(true);// 設定可以使用localStorage
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);// 優先使用快取
webView.getSettings().setAppCacheMaxSize(10 * 1024 * 1024);// 快取最多可以有10M
webView.getSettings().setAllowFileAccess(true);// 可以讀取檔案快取(manifest生效)
webView.getSettings().setPluginState(PluginState.ON);
webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
// 加速WebView載入的方法
webView.getSettings().setRenderPriority(RenderPriority.HIGH); // 提高渲染的優先順序
// webView.getSettings().setPluginState(true);
webView.loadUrl(getString(R.string.videourl));
if(savedInstanceState != null){
webView.restoreState(savedInstanceState);
}
}
private void initView() {
// TODO Auto-generated method stub
webView = (WebView) findViewById(R.id.webview);
frameLayout = (FrameLayout)findViewById(R.id.framelayout);
videolayout = (FrameLayout)findViewById(R.id.fl_video);
}
long timeSpace = 0;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (System.currentTimeMillis() - timeSpace > 2000) {
timeSpace = System.currentTimeMillis();
if(chromeClient != null){
chromeClient.onHideCustomView();
}
Toast.makeText(this, "再按一次退出視訊播放介面", Toast.LENGTH_SHORT).show();
}
else {
finish();
}
return true;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
webView.saveState(outState);
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
AnimationUtil.setLayout(R.anim.deflaut, R.anim.slide_right_out);
super.onPause();
webView.onPause();
webView.pauseTimers();
}
public void addJavaScriptMap(Object obj, String objName){
webView.addJavascriptInterface(obj, objName);
}
public class MyWebviewCient extends WebViewClient{
@Override
public WebResourceResponse shouldInterceptRequest(WebView view,
String url) {
WebResourceResponse response = null;
response = super.shouldInterceptRequest(view, url);
Logger.e(TAG, "shouldInterceptRequest");
return response;
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// TODO Auto-generated method stub
handler.proceed();
Logger.e(TAG, "onReceivedSslError");
}
@Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
Logger.e(TAG, "onPageFinished");
}
}
@Override
protected void onResume() {
super.onResume();
super.onResume();
webView.onResume();
webView.resumeTimers();
/**
* 設定為橫屏
*/
if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
super.onDestroy();
//video_fullView.removeAllViews();
webView.loadUrl("about:blank");
webView.stopLoading();
webView.setWebChromeClient(null);
webView.setWebViewClient(null);
webView.destroy();
webView = null;
}
public class MyChromeClient extends WebChromeClient{
// 一個回撥介面使用的主機應用程式通知當前頁面的自定義檢視已被撤職
CustomViewCallback customViewCallback;
int mOriginalOrientation ;
// 進入全屏的時候
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
if (customView != null) {
callback.onCustomViewHidden();
return;
}
customView = view;
customViewCallback = callback;
mOriginalOrientation = getRequestedOrientation();
webView.setVisibility(View.GONE);
videolayout.addView(customView);
videolayout.setVisibility(View.VISIBLE);
videolayout.bringToFront();
//設定橫屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//設定全屏
setFullScreen();
}
// 退出全屏的時候
@Override
public void onHideCustomView() {
if (customView == null) {
return;
}
videolayout.removeView(customView);
customView = null;
videolayout.setVisibility(View.GONE);
try {
customViewCallback.onCustomViewHidden();
} catch (Exception e) {
}
// 設定豎屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
quitFullScreen();
// 設定WebView可見
webView.setVisibility(View.VISIBLE);
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
}
private void setFullScreen() {
// 設定全屏的相關屬性,獲取當前的螢幕狀態,然後設定全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// 全屏下的狀態碼:1098974464
// 視窗下的狀態嗎:1098973440
}
/**
* 退出全屏
*/
private void quitFullScreen() {
// 聲明當前螢幕狀態的引數並獲取
final WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attrs);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
}
主要是因為需要信任https 連結,需要在Activity中呼叫 HttpsTrustManager.allowAllSSL();
這個類的程式碼如下:
public class HttpsTrustManager implements X509TrustManager {
private static TrustManager[] trustManagers;
private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};
@Override
public void checkClientTrusted(
X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
@Override
public void checkServerTrusted(
X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
public boolean isClientTrusted(X509Certificate[] chain) {
return true;
}
public boolean isServerTrusted(X509Certificate[] chain) {
return true;
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return _AcceptedIssuers;
}
public static void allowAllSSL() {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
SSLContext context = null;
if (trustManagers == null) {
trustManagers = new TrustManager[]{new HttpsTrustManager()};
}
try {
context = SSLContext.getInstance("TLS");
context.init(null, trustManagers, new SecureRandom());
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultSSLSocketFactory(context != null ? context.getSocketFactory() : null);
}
}