Android WebView Video完全詳解(第一篇)-Android開發人員
背景
最近公司某項功能需要WebView載入H5的Video,搜尋很多資料後發現很多問題,都是關鍵程式碼片段,因為每個專案每個人產生的問題不同,Video在webview中載入不出來原因很多,可能是客戶端少了引數,也可能是前端出了問題,經過研究後對Android WebView 載入H5Video標籤做此詳解。
需要注意的幾個點
- video 播放有兩種狀態,在原來元件的位置直接播放,全屏播放。
- IOS客戶端對H5 Video標籤做了特殊處理,即H5直接用video標籤即可,但是Android客戶端需要特殊JS處理,所以前端開發需要注意,在下面程式碼段會劃重點。
- AndroidManifest.xml中Activity需要開加速,需要全屏設定需要設定configChanges
- Video可以在Fragment中或者Activity中,但多個Fragment中共用一個Activity如果全屏播放建議考慮橫屏時生命週期,如果單開Activity載入WebView會更加清爽。
Anroid 客戶端畫重點
- settings相關的設定
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setUpWebViewDefaults(WebView webView) {
WebSettings settings = webView.getSettings();
// Enable Javascript
settings.setJavaScriptEnabled(true);
// Use WideViewport and Zoom out if there is no viewport defined
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
// Enable pinch to zoom without the zoom buttons
settings.setBuiltInZoomControls(false );
// Allow use of Local Storage
settings.setDomStorageEnabled(true);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
// Hide the zoom controls for HONEYCOMB+
settings.setDisplayZoomControls(false);
}
// Enable remote debugging via chrome://inspect
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
webView.setWebViewClient(new WebViewClient());
}
- WebChromeClient 相關設定
void setChromeClient() {
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public Bitmap getDefaultVideoPoster() {
if (this == null) {
return null;
}
//這個地方是載入h5的視訊列表 預設圖 點選前的視訊圖
return BitmapFactory.decodeResource(getApplicationContext().getResources(),
R.mipmap.ic_launcher);
}
@Override
public void onShowCustomView(View view,
WebChromeClient.CustomViewCallback callback) {
// if a view already exists then immediately terminate the new one
if (mCustomView != null) {
onHideCustomView();
return;
}
// 1. Stash the current state
mCustomView = view;
mOriginalSystemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
mOriginalOrientation = getRequestedOrientation();
// 2. Stash the custom view callback
mCustomViewCallback = callback;
// 3. Add the custom view to the view hierarchy
FrameLayout decor = (FrameLayout) getWindow().getDecorView();
decor.addView(mCustomView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
// 4. Change the state of the window
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_IMMERSIVE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
@Override
public void onHideCustomView() {
// 1. Remove the custom view
FrameLayout decor = (FrameLayout) getWindow().getDecorView();
decor.removeView(mCustomView);
mCustomView = null;
// 2. Restore the state to it's original form
getWindow().getDecorView()
.setSystemUiVisibility(mOriginalSystemUiVisibility);
setRequestedOrientation(mOriginalOrientation);
// 3. Call the custom view callback
mCustomViewCallback.onCustomViewHidden();
mCustomViewCallback = null;
}
});
}
如果是Activity中就三步走
initView(); //初始化webview
setUpWebViewDefaults(mWebView); //設定settings
setChromeClient(); //設定chromeClient
mWebView.loadUrl("file:///android_asset/www/index.html");
大功告成
是啊只給程式碼段 ,我怎麼知道往哪裡拼~~~~
我喜歡直接拷貝啦~
走你~
package open.ppdai.com.webviewh5video;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
/**
* Email:[email protected]
*
* @data:17/1/12 上午11:16
* @Description:${todo}
*
*/
public class MainActivity extends Activity {
private WebView mWebView;
private View mCustomView;
private int mOriginalSystemUiVisibility;
private int mOriginalOrientation;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
protected FrameLayout mFullscreenContainer;
private Handler mHandler;
public MainActivity() {
mHandler = new Handler();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
setUpWebViewDefaults(mWebView);
setChromeClient();
mWebView.loadUrl("file:///android_asset/www/index.html"); //這個地方是本地的assets下的h5檔案
//android開發人員直接拿這個標準的檔案去看是否能從當前頁面播放,是否能全屏播放
}
private void initView() {
mWebView = (WebView) findViewById(R.id.webview);
}
void setChromeClient() {
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public Bitmap getDefaultVideoPoster() {
if (this == null) {
return null;
}
//這個地方是載入h5的視訊列表 預設圖 點選前的視訊圖
return BitmapFactory.decodeResource(getApplicationContext().getResources(),
R.mipmap.ic_launcher);
}
@Override
public void onShowCustomView(View view,
WebChromeClient.CustomViewCallback callback) {
// if a view already exists then immediately terminate the new one
if (mCustomView != null) {
onHideCustomView();
return;
}
// 1. Stash the current state
mCustomView = view;
mOriginalSystemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
mOriginalOrientation = getRequestedOrientation();
// 2. Stash the custom view callback
mCustomViewCallback = callback;
// 3. Add the custom view to the view hierarchy
FrameLayout decor = (FrameLayout) getWindow().getDecorView();
decor.addView(mCustomView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
// 4. Change the state of the window
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_IMMERSIVE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
@Override
public void onHideCustomView() {
// 1. Remove the custom view
FrameLayout decor = (FrameLayout) getWindow().getDecorView();
decor.removeView(mCustomView);
mCustomView = null;
// 2. Restore the state to it's original form
getWindow().getDecorView()
.setSystemUiVisibility(mOriginalSystemUiVisibility);
setRequestedOrientation(mOriginalOrientation);
// 3. Call the custom view callback
mCustomViewCallback.onCustomViewHidden();
mCustomViewCallback = null;
}
});
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setUpWebViewDefaults(WebView webView) {
WebSettings settings = webView.getSettings();
// Enable Javascript
settings.setJavaScriptEnabled(true);
// Use WideViewport and Zoom out if there is no viewport defined
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
// Enable pinch to zoom without the zoom buttons
settings.setBuiltInZoomControls(false);
// Allow use of Local Storage
settings.setDomStorageEnabled(true);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
// Hide the zoom controls for HONEYCOMB+
settings.setDisplayZoomControls(false);
}
// Enable remote debugging via chrome://inspect
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
webView.setWebViewClient(new WebViewClient());
}
}
佈局檔案裡面就一個webview 如果不想寫直接去下載程式碼嘮~
看到這裡 ,如果你的webview還是沒有加載出Video來,那你直接把這這個demo執行結果扔給前端,並且把第二篇文章給前端人員看好了
相關推薦
Android WebView Video完全詳解(第一篇)-Android開發人員
背景 最近公司某項功能需要WebView載入H5的Video,搜尋很多資料後發現很多問題,都是關鍵程式碼片段,因為每個專案每個人產生的問題不同,Video在webview中載入不出來原因很多,可能是客戶端少了引數,也可能是前端出了問題,經
jsp詳解(第一篇)
JSP入門 1 JSP概述 1.1什麼是JSP JSP(Java Server Pages)是JavaWeb伺服器端的動態資源。它與html頁面的作用是相同的,顯示資料和獲取資料。 1.2 JSP的組成 JSP=html+Java指令碼(
Mysql主從配置詳解(第一篇,共五篇)
使用Docker容器搭建MySql主從複製 使用Docker容器搭建MySql主從複製 檢視容器ip命令為docker inspect 96fd[id前四位] Master_mysql_ip_172.17.0.4 slave_mysql_ip_172.17.0.5
Android Studio中Git和GitHub使用詳解(上篇)
一、Git和GitHub簡述 1.Git 分散式版本控制系統,最先使用於Linux社群,是一個開源免費的版本控制系統,功能類似於SVN和CVS。Git與其他版本管理工具最大的區別點和優點就是分散式; git是採用分散式版本庫機制,不需要每次都將檔案推送到版本控制伺服
阿里巴巴的Vlayout框架原始碼原理詳解(第一篇流程分析)
先看一下阿里對這個框架留下的Demo的效果: 看效果大體的可以猜測這個框架給我們提供了很多佈局規則,據說淘寶首頁就是用這個框架做的。原始碼地址 好接下來我們就沿著這個Demo這條線開始分析實現原理,從而學習人家的架構搭建方式 先看佈局程式碼 <FrameLayo
Android Mvp模式詳解(Kotlin篇)
mvp簡介與Mvc對比: 相信大家對MVC都是比較熟悉了:M-Model-模型、V-View-檢視、C-Controller-控制器,MVP作為MVC的演化版本,那麼類似的MVP所對應的意義:M-Mo
Android USB Host 使用詳解(U盤)(一)
首先說一下為什麼要寫關於Android USB Host通訊的介紹,對於Android程式原來說不懂硬體做USB通訊確實開頭比較難,但是Google API介紹還是很詳細的,而且網上也有很多例子,不過網上的基本把介紹和例子分開,光介紹不給例子,給個例子又不知道它是幹什麼的或
Python高階程式設計——裝飾器Decorator詳解(上篇)(絕對是我見過最詳細的的教程,沒有之一哦)
一、先從一種情況開始看起 1、裝飾器decorator的由來 裝飾器的定義很是抽象,我們來看一個小例子。 先定義一個簡單的函式: def myfunc: print('我是函式myfunc') myfunc() #呼叫函式 然後呢,我想看看
“全棧2019”Java第二十八章:陣列詳解(上篇)
難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文連結 “全棧2019”Java第二十八章:陣列詳解(上篇) 下一章 “全棧2019”Java第二十九章:陣列詳解(中篇)
史上最簡單MySQL教程詳解(基礎篇)之多表聯合查詢
常用術語 內連線 外連線 左外連線 右外連線 注意事項: 自連線 子查詢 在上篇文章史上最簡單MySQL教程詳解(基礎篇)之資料庫設計正規化及應用舉例我們介紹過,在關係型資料庫中,我們通常為了減少資料的冗餘量將對資料表進行規範,將
TCP協議詳解(理論篇)
1. 與UDP不同的是,TCP提供了一種面向連線的、可靠的位元組流服務。面向連線比較好理解,就是連線雙方在通訊前需要預先建立一條連線,這猶如實際生活中的打電話。助於可靠性,TCP協議中涉及了諸多規則來保障通訊鏈路的可靠性,總結起來,主要有以下幾點: (1
React Native未來導航者:react-navigation 使用詳解(基礎篇)
剛建立的React Native 微信公眾號,歡迎微信掃描關注訂閱號,每天定期會分享react native 技術文章,移動技術乾貨,精彩文章技術推送。同時可以掃描我的微信加入react-native技術交流微信群。歡迎各位大牛,React Native技術愛好者加入交流!上
事件驅動模型例項詳解(Java篇)
這個按鈕的時候,按鈕物件會直接把這次點選感覺傳遞給ButtonEventHandler的actionPerformed方法處理,為養成較好的程式設計習慣,我們中心並不建議學員直接在該委託方法中編寫程式碼,而是需要將該事件處理再次轉發給窗體中的某個方法來處理,這個方法的命名也必須是有規則的,就是事件源名+下劃線
Ping命令詳解(引數篇)
Ping命令詳解對於Windows下ping命令相信大家已經再熟悉不過了,但是能把ping的功能發揮到最大的人卻並不是很多,當然我也並不是說我可以讓ping發揮最大的功能,我也只不過經常用ping這個工具,也總結了一些小經驗,現在和大家分享一下。現在我就參照ping命令的幫助說明來給大家說說我使用ping時會
hadoop之mapreduce詳解(基礎篇)
本篇文章主要從mapreduce執行作業的過程,shuffle,以及mapreduce作業失敗的容錯幾個方面進行詳解。 一、mapreduce作業執行過程 1.1、mapreduce介紹 MapReduce是一種程式設計模型,用於大規模資料集(大於1TB)的並行運
hadoop之mapreduce詳解(優化篇)
一、概述 優化前我們需要知道hadoop適合幹什麼活,適合什麼場景,在工作中,我們要知道業務是怎樣的,能才結合平臺資源達到最有優化。除了這些我們當然還要知道mapreduce的執行過程,比如從檔案的讀取,map處理,shuffle過程,reduce處理,檔案的輸出或者
用ant的build.xml構建自動化打包android apk 完全詳解(打包系列教程之二)
打包系列教程目錄: 通過上一篇文章內容的學習,我們基本已經明白了android打包簽名apk的主要操作與流程,那麼這一篇文章我們就將上一篇文章的打包內容轉化成ant的build.xml檔案進行自動化打包,這樣可以避免我們上一篇文章的敲打命令列的繁瑣操作,從而
python3多線程應用詳解(第一卷:線程的本質概念)
本質 函數 解釋 style height auto 進行 mage pla 之前我用過多線程的方式執行了爬蟲程序,爬取了糗事百科的數據可以看到速率非常之快,就像正常一個人他要完一個漢堡,再吃喝一瓶水才能走,結果他邊吃漢堡邊喝水,速率一下加快了一樣。首先我們看看什麽是線程:
Android EventBus3.x 使用詳解(一)
led AC target 分解 感覺 div activit .org android事 ?(^∇^*) 五一假期在家無事,新項目中用的是RxJava2+EventBus感覺還不錯,趁這閑暇總結下EventBus 一、概要簡述 EventBus
Android應用程式啟動詳解(二)從原始碼瞭解App的啟動過程
本文承接《Android應用程式啟動詳解(一)》繼續來學習應用程式的啟動的那些事。上文提到startActivity()方法啟動一個app後經過一翻過程就到了app的入口方法ActivityThread.main()。其實我們在之前的文章中《Android的訊息機制(二)之L