WebView и HTML5 <видео>

123

Я собираю дешевое приложение, которое, помимо прочего, "обрамляет" некоторые из наших веб-сайтов ... Довольно просто с WebViewClient. пока не попал в видео.

Видео выполнено в виде HTML5 элементов, и они отлично работают в Chrome и iPhone, и теперь, когда мы исправили проблемы с кодированием, оно отлично работает Androidв собственном браузере.

Теперь загвоздка: WebViewне нравится. Вообще. Я могу щелкнуть изображение плаката, и ничего не происходит.

Погуглить, я нашел это что близко, но , кажется, на основе «линии» (как в HREF ...) вместо видеоэлемент. (onDownloadListener, похоже, не вызывается для видеоэлементов ...)

Я также вижу ссылки на переопределение onShowCustomView, но, похоже, это не вызывается для видеоэлементов ... и не должноOverrideUrlLoading ..

Я бы предпочел не вдаваться в «вытаскивать xml с сервера, переформатировать его в приложении» ... сохраняя макет истории на сервере, я могу немного лучше контролировать контент, не заставляя людей продолжать обновлять приложение. Так что, если я смогу убедить WebView обрабатывать теги, как собственный браузер, это будет лучше всего.

Я явно упускаю что-то очевидное ... но понятия не имею, что именно.

Брайан Мур
источник
В том же духе я ищу проигрыватель HTML5 для своего сайта. Что мне использовать?
Wolfpack'08,
1
Мой ответ здесь: stackoverflow.com/a/16179544/423171
cprcrack
1
Ничего не сработало, поэтому я заглянул VideoEnabledWebViewсюда stackoverflow.com/questions/15768837/…
EpicPandaForce

Ответы:

93

Отвечаю в этой теме на случай, если кто-то прочитает и заинтересуется результатом. В WebView можно просмотреть элемент видео (тег video html5), но я должен сказать, что мне пришлось иметь дело с этим в течение нескольких дней. Вот шаги, которые я должен был выполнить до сих пор:

-Найти правильно закодированное видео

-При инициализации WebView установите JavaScript, плагины WebViewClient и WebChromeClient.

url = новая строка ("http://broken-links.com/tests/video/"); 
mWebView = (WebView) findViewById (R.id.webview);
mWebView.setWebChromeClient (chromeClient);
mWebView.setWebViewClient (wvClient);
mWebView.getSettings () setJavaScriptEnabled (истина).
. MWebView.getSettings () setPluginState (PluginState.ON);
mWebView.loadUrl (URL);

-Обработка onShowCustomView в объекте WebChromeClient.

@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
    super.onShowCustomView(view, callback);
    if (view instanceof FrameLayout){
        FrameLayout frame = (FrameLayout) view;
        if (frame.getFocusedChild() instanceof VideoView){
            VideoView video = (VideoView) frame.getFocusedChild();
            frame.removeView(video);
            a.setContentView(video);
            video.setOnCompletionListener(this);
            video.setOnErrorListener(this);
            video.start();
        }
    }
}

-Обработать события onCompletion и onError для видео, чтобы вернуться в веб-просмотр.

public void onCompletion(MediaPlayer mp) {
    Log.d(TAG, "Video completo");
    a.setContentView(R.layout.main);
    WebView wb = (WebView) a.findViewById(R.id.webview);
    a.initWebView();
}

Но теперь я должен сказать, что есть еще один важный вопрос. Я могу сыграть в нее только один раз. Второй раз нажимаю на диспетчер видео (либо плакат, либо какую-то кнопку воспроизведения), он ничего не делает.

Я также хотел бы, чтобы видео воспроизводилось внутри кадра WebView, а не открывало окно Media Player, но для меня это второстепенная проблема.

Я надеюсь, что это кому-то поможет, и я также буду благодарен за любой комментарий или предложение.

Салудос, терриколас.

mdelolmo
источник
У меня нет результатов, мой экран черный. Я хочу знать, нужна ли эта реклама. мой код слишком длинный, чтобы писать здесь. Можете ли вы дать мне какой-нибудь контакт или открыть другую тему.
Pengwang
Вы полностью уверены, что проблема не в кодировке? Попробуйте использовать опубликованный мной URL. Очевидно, он должен работать со встроенным браузером
mdelolmo 08
46
что такое "а"? как это было бы?
Коллин Прайс
1
@Collin Price a - это экземпляр Activity, на котором размещается веб-просмотр. @desgraci, я могу предоставить, но кроме этого немногое. Заставьте класс расширить WebChromeClientи переопределить соответствующие методы, которые вам нужны. Если вы настаиваете, я могу загрузить остальную часть класса позже, когда вернусь домой.
mdelolmo
6
Не работает с ICS, поскольку getFocusedChild () - это не VideoView, а HTML5VFullScreen $ SurfaceVideoView. Есть идеи, как это сделать на ICS? (см. stackoverflow.com/questions/13540654/…
Паскаль
61

После долгих исследований эта штука заработала. См. Следующий код:

Test.java

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;

public class Test extends Activity {

    HTML5WebView mWebView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mWebView = new HTML5WebView(this);

        if (savedInstanceState != null) {
            mWebView.restoreState(savedInstanceState);
        } else {    
            mWebView.loadUrl("http://192.168.1.18/xxxxxxxxxxxxxxxx/");
        }

        setContentView(mWebView.getLayout());
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mWebView.saveState(outState);
    }

    @Override
    public void onStop() {
        super.onStop();
        mWebView.stopLoading();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (mWebView.inCustomView()) {
                mWebView.hideCustomView();
            //  mWebView.goBack();
                //mWebView.goBack();
                return true;
            }

        }
        return super.onKeyDown(keyCode, event);
    }
}

HTML% VIDEO.java

package com.ivz.idemandtest;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;

public class HTML5WebView extends WebView {

    private Context                             mContext;
    private MyWebChromeClient                   mWebChromeClient;
    private View                                mCustomView;
    private FrameLayout                         mCustomViewContainer;
    private WebChromeClient.CustomViewCallback  mCustomViewCallback;

    private FrameLayout                         mContentView;
    private FrameLayout                         mBrowserFrameLayout;
    private FrameLayout                         mLayout;

    static final String LOGTAG = "HTML5WebView";

    private void init(Context context) {
        mContext = context;     
        Activity a = (Activity) mContext;

        mLayout = new FrameLayout(context);

        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(a).inflate(R.layout.custom_screen, null);
        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.main_content);
        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.fullscreen_custom_content);

        mLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);

        // Configure the webview
        WebSettings s = getSettings();
        s.setBuiltInZoomControls(true);
        s.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        s.setUseWideViewPort(true);
        s.setLoadWithOverviewMode(true);
      //  s.setSavePassword(true);
        s.setSaveFormData(true);
        s.setJavaScriptEnabled(true);
        mWebChromeClient = new MyWebChromeClient();
        setWebChromeClient(mWebChromeClient);

        setWebViewClient(new WebViewClient());

setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);

        // enable navigator.geolocation 
       // s.setGeolocationEnabled(true);
       // s.setGeolocationDatabasePath("/data/data/org.itri.html5webview/databases/");

        // enable Web Storage: localStorage, sessionStorage
        s.setDomStorageEnabled(true);

        mContentView.addView(this);
    }

    public HTML5WebView(Context context) {
        super(context);
        init(context);
    }

    public HTML5WebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public HTML5WebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public FrameLayout getLayout() {
        return mLayout;
    }

    public boolean inCustomView() {
        return (mCustomView != null);
    }

    public void hideCustomView() {
        mWebChromeClient.onHideCustomView();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if ((mCustomView == null) && canGoBack()){
                goBack();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    private class MyWebChromeClient extends WebChromeClient {
        private Bitmap      mDefaultVideoPoster;
        private View        mVideoProgressView;

        @Override
        public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback)
        {
            //Log.i(LOGTAG, "here in on ShowCustomView");
            HTML5WebView.this.setVisibility(View.GONE);

            // if a view already exists then immediately terminate the new one
            if (mCustomView != null) {
                callback.onCustomViewHidden();
                return;
            }

            mCustomViewContainer.addView(view);
            mCustomView = view;
            mCustomViewCallback = callback;
            mCustomViewContainer.setVisibility(View.VISIBLE);
        }

        @Override
        public void onHideCustomView() {
            System.out.println("customview hideeeeeeeeeeeeeeeeeeeeeeeeeee");
            if (mCustomView == null)
                return;        

            // Hide the custom view.
            mCustomView.setVisibility(View.GONE);

            // Remove the custom view from its container.
            mCustomViewContainer.removeView(mCustomView);
            mCustomView = null;
            mCustomViewContainer.setVisibility(View.GONE);
            mCustomViewCallback.onCustomViewHidden();

            HTML5WebView.this.setVisibility(View.VISIBLE);
            HTML5WebView.this.goBack();
            //Log.i(LOGTAG, "set it to webVew");
        }


        @Override
        public View getVideoLoadingProgressView() {
            //Log.i(LOGTAG, "here in on getVideoLoadingPregressView");

            if (mVideoProgressView == null) {
                LayoutInflater inflater = LayoutInflater.from(mContext);
                mVideoProgressView = inflater.inflate(R.layout.video_loading_progress, null);
            }
            return mVideoProgressView; 
        }

         @Override
         public void onReceivedTitle(WebView view, String title) {
            ((Activity) mContext).setTitle(title);
         }

         @Override
         public void onProgressChanged(WebView view, int newProgress) {
             ((Activity) mContext).getWindow().setFeatureInt(Window.FEATURE_PROGRESS, newProgress*100);
         }

         @Override
         public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
             callback.invoke(origin, true, false);
         }
    }


    static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
        new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}

custom_screen.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android">
    <FrameLayout android:id="@+id/fullscreen_custom_content"
        android:visibility="gone"
        android:background="@color/black"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    />
    <LinearLayout android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout android:id="@+id/error_console"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
        />

        <FrameLayout android:id="@+id/main_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
        />
    </LinearLayout>
</FrameLayout>

video_loading_progress.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/progress_indicator"
         android:orientation="vertical"
         android:layout_centerInParent="true"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content">

       <ProgressBar android:id="@android:id/progress"
           style="?android:attr/progressBarStyleLarge"
           android:layout_gravity="center"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content" />

       <TextView android:paddingTop="5dip"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_gravity="center"
           android:text="@string/loading_video" android:textSize="14sp"
           android:textColor="?android:attr/textColorPrimary" />
 </LinearLayout>

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/assets/res/any/http_authentication_colors.xml
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/
-->
<!-- FIXME: Change the name of this file!  It is now being used generically
    for the browser -->
<resources>
    <color name="username_text">#ffffffff</color>
    <color name="username_edit">#ff000000</color>

    <color name="password_text">#ffffffff</color>
    <color name="password_edit">#ff000000</color>

    <color name="ssl_text_label">#ffffffff</color>
    <color name="ssl_text_value">#ffffffff</color>

    <color name="white">#ffffffff</color>
    <color name="black">#ff000000</color>



    <color name="geolocation_permissions_prompt_background">#ffdddddd</color>
</resources>

manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.test"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Test"
                  android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:configChanges="orientation|keyboardHidden|keyboard">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>  
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
</manifest>

Ожидая того, что вы понимаете.

Сурендра
источник
7
Это должен быть принятый ответ. Сурендра и Маленький, вы оба спасли мне рассудок. Отлично сработал для меня.
Джордж Бейкер,
Я согласен с Джорджем. Именно так работает собственный браузер Android с VideoView. Кажется, это тот же код, что и здесь code.google.com/p/html5webview . Он отлично работает со всеми версиями Android (я тестировал на Android 2.2 и выше). Единственное, на что я хотел обратить внимание: вы должны иметь в виду, что если вы измените целевой SDK на что-то выше 13, ваша активность будет воссоздана при изменении ориентации. Чтобы избежать этого, либо добавьте screenSize в android: configChanges (но в этом случае вам нужно будет использовать min sdk <13) или использовать старый целевой SDK (тогда вы можете сохранить android: configChanges)
Юрий Ашаев
2
Это дает мне белый пустой экран на Nexus 7 (Android 4.1). Есть идеи, как это исправить?
Sahil
Backbutton не останавливает видео, а звук все еще слышен, есть идеи, как это исправить?
CONvid19
Это то, что я искал точно так же, как поток в собственном браузере .. Спасибо Тону Сурендре и Маленькому.
Abhilash
33

Ответ mdelolmo был невероятно полезным, но, как он сказал, видео воспроизводится только один раз, а затем вы не можете открыть его снова.

Я немного изучил это, и вот что я нашел на тот случай, если какие-либо усталые путешественники WebView, такие как я, наткнутся на этот пост в будущем.

Во-первых, я просмотрел документацию VideoView и MediaPlayer и лучше понял, как они работают. Я настоятельно рекомендую их.

Затем я просмотрел исходный код, чтобы узнать, как это делает браузер Android . Сделайте поиск страницы и посмотрите, как они справляются onShowCustomView(). Они хранят ссылку CustomViewCallbackна пользовательский вид и на него.

С учетом всего этого и с учетом ответа mdelolmo, когда вы закончите с видео, все, что вам нужно сделать, это две вещи. Во-первых, на том, на VideoViewчто вы сохранили ссылку, вызовите stopPlayback(), который освободит MediaPlayerдля использования позже в другом месте. Вы можете увидеть это в исходном коде VideoView . Во-вторых, CustomViewCallbackвы сохранили ссылку на звонок CustomViewCallback.onCustomViewHidden().

После выполнения этих двух действий вы можете щелкнуть то же видео или любое другое видео, и оно откроется, как и раньше. Нет необходимости перезапускать весь WebView.

Надеюсь, это поможет.

cottonBallPaws
источник
На самом деле я тоже решил это, я просто не забыл опубликовать решение (позор мне). Как и вам, мне пришлось взглянуть на код браузера Android, и, ну, нечего добавить, вместо этого я использовал прослушиватель onCompletion, чтобы остановить Player, и мне пришлось пару раз установить видимость, но я бы купил ваше решение. С уважением!
mdelolmo
1
Google Code Search был удален, я думаю, что эта версия BrowserActivity.java (от Froyo) примерно соответствует описанной здесь: github.com/android/platform_packages_apps_browser/blob/…
michiakig
Связанный код @ spacemanki не содержит упоминаний VideoView во всем репо. Думаю, теперь BrowserActivity работает по-другому. Я даже вернулся к выпуску Эклера. Не могу найти использования.
mxcl
Проблема, с которой я сталкиваюсь, заключается в том, что я получаю от frame.getFocusedChild (); - это HTml5VideoView вместо ViewView, и поэтому у меня ничего не работает, и я не могу переключиться в полноэкранный
режим
1
В конце концов, я добавил: @Override public void onStop () {super.onStop (); mWebView.destroy (); } к активности ... webview.destroy () имел решающее значение
MacD
8

На самом деле, кажется достаточно просто прикрепить стандартный WebChromeClient к клиентскому представлению, ala

mWebView.setWebChromeClient(new WebChromeClient());

и вам нужно включить аппаратное ускорение!

По крайней мере, если вам не нужно воспроизводить полноэкранное видео, нет необходимости извлекать VideoView из WebView и вставлять его в представление Activity. Он будет воспроизводиться в выделенном прямоугольнике видеоэлемента.

Есть идеи, как перехватить кнопку расширения видео?

Расс Шнапп
источник
вы можете перехватить его, используя WebChromeClient и переопределив onShowCustomView
Фрэнк
Пожалуйста, укажите, какая версия Android. Это работает по-разному для разных версий.
Ethan_AI
7

Я знаю, что этому потоку несколько месяцев, но я нашел решение для воспроизведения видео внутри WebView, не выполняя его в полноэкранном режиме (но все еще в медиаплеере ...). Пока я не нашел намеков на это в Интернете, так что, возможно, это также интересно для других. Я все еще борюсь с некоторыми проблемами (например, размещаю медиаплеер в правой части экрана, не знаю, почему я делаю это неправильно, но это относительно небольшая проблема, я думаю ...).

В Custom ChromeClient укажите LayoutParams:

// 768x512 is the size of my video
FrameLayout.LayoutParams LayoutParameters = 
                                     new FrameLayout.LayoutParams (768, 512); 

Мой метод onShowCustomView выглядит так:

public void onShowCustomView(final View view, final CustomViewCallback callback) {
     // super.onShowCustomView(view, callback);
     if (view instanceof FrameLayout) {
         this.mCustomViewContainer = (FrameLayout) view;
         this.mCustomViewCallback = callback;
         this.mContentView = (WebView) this.kameha.findViewById(R.id.webview);
         if (this.mCustomViewContainer.getFocusedChild() instanceof VideoView) {
             this.mCustomVideoView = (VideoView) 
                                     this.mCustomViewContainer.getFocusedChild();
             this.mCustomViewContainer.setVisibility(View.VISIBLE);
             final int viewWidth = this.mContentView.getWidth();
             final int viewLeft = (viewWidth - 1024) / 2;
             // get the x-position for the video (I'm porting an iPad-Webapp to Xoom, 
             // so I can use those numbers... you have to find your own of course...
             this.LayoutParameters.leftMargin = viewLeft + 256; 
             this.LayoutParameters.topMargin = 128;
             // just add this view so the webview underneath will still be visible, 
             // but apply the LayoutParameters specified above
             this.kameha.addContentView(this.mCustomViewContainer, 
                                             this.LayoutParameters); 
             this.mCustomVideoView.setOnCompletionListener(this);
             this.mCustomVideoView.setOnErrorListener(this);
             // handle clicks on the screen (turning off the video) so you can still
             // navigate in your WebView without having the video lying over it
             this.mCustomVideoView.setOnFocusChangeListener(this); 
             this.mCustomVideoView.start();
         }
     }
 }

Итак, я надеюсь, что смогу помочь ... Мне тоже пришлось поиграть с кодированием видео, и я видел разные виды использования WebView с видео html5 - в конце концов мой рабочий код был дикой смесью разных частей кода, которые я нашел в Интернет и некоторые вещи, которые мне пришлось разобраться самостоятельно. Это действительно было головной болью.

AM
источник
В ICS getFocusedChild () не возвращает VideoView. Есть идеи, как заставить это работать на ICS?
Паскаль
4

Этот подход хорошо работает до 2.3. И добавив hardwareaccelerated = true, он работает даже с 3.0 до ICS. Одна проблема, с которой я сталкиваюсь в настоящее время, заключается в том, что при втором запуске приложения медиаплеера происходит сбой, потому что я не остановил воспроизведение и не выпустил медиаплеер. Поскольку объект VideoSurfaceView, который мы получаем в функции onShowCustomView из ОС 3.0, относится к браузеру, а не к объекту VideoView, как в ОС до версии 2.3, как я могу получить к нему доступ, остановить воспроизведение и освободить ресурсы?

Новая звезда
источник
3

AM похож на то, что делает BrowerActivity . для FrameLayout.LayoutParams LayoutParameters = new FrameLayout.LayoutParams (768, 512);

Я думаю мы можем использовать

FrameLayout.LayoutParams LayoutParameters = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
            FrameLayout.LayoutParams.FILL_PARENT) 

вместо.

Еще одна проблема, с которой я столкнулся, заключается в том, что если видео воспроизводится, и пользователь нажимает кнопку «Назад», в следующий раз вы переходите к этому действию (singleTop) и не можете воспроизвести видео. чтобы исправить это, я позвонил

try { 
    mCustomVideoView.stopPlayback();  
    mCustomViewCallback.onCustomViewHidden();
} catch(Throwable e) { //ignore }

в методе onBackPressed действия.

yincan
источник
2

Я знаю, что это очень старый вопрос, но пробовали ли вы использовать hardwareAccelerated="true"флаг манифеста для своего приложения или действия?

С этим набором, похоже, он работает без какой-либо модификации WebChromeClient (чего я ожидал от DOM-Element).

подгузник
источник
2
hardwareAcceleratedзапускается с Android 3.0
vbence
2

Я использовал html5webview для решения этой проблемы. Загрузите и вставьте его в свой проект, тогда вы можете кодировать точно так же.

private HTML5WebView mWebView;
String url = "SOMEURL";
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mWebView = new HTML5WebView(this);
    if (savedInstanceState != null) {
            mWebView.restoreState(savedInstanceState);
    } else {
            mWebView.loadUrl(url);
    }
    setContentView(mWebView.getLayout());
}
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mWebView.saveState(outState);
}

Чтобы сделать видео вращаемым, поместите код android: configChanges = "Ориентация" в свою активность, например (Androidmanifest.xml).

<activity android:name=".ui.HTML5Activity" android:configChanges="orientation"/>

и переопределить метод onConfigurationChanged.

@Override
public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);
}
Метуз Кэусай-као
источник
2

Этому вопросу много лет, но, возможно, мой ответ поможет таким людям, как я, которые должны поддерживать старую версию Android. Я пробовал много разных подходов, которые работали на некоторых версиях Android, но не на всех. Лучшее решение, которое я нашел, - использовать Crosswalk Webview, который оптимизирован для поддержки функций HTML5 и работает на Android 4.1 и выше. Его так же просто использовать, как и Android WebView по умолчанию. Вам просто нужно включить библиотеку. Здесь вы можете найти простое руководство по его использованию: https://diego.org/2015/01/07/embedding-crosswalk-in-android-studio/

Apfelsaft
источник
Примечание: пешеходный переход больше не поддерживается .
slhck 06
1

Что ж, по-видимому, это невозможно без использования JNI для регистрации плагина для получения видео-события. (Лично я избегаю JNI, потому что я действительно не хочу иметь дело с беспорядком, когда в ближайшие несколько месяцев выйдут планшеты Android на базе Atom, потерявшие переносимость Java.)

Единственной реальной альтернативой, по-видимому, является создание новой веб-страницы только для WebView и видео по старинке со ссылкой A HREF, как указано в URL-адресе Codelark выше.

Icky.

Брайан Мур
источник
1

На сотовом использовании hardwareaccelerated=trueи pluginstate.on_demandвроде работает

user953501
источник
1

У меня была похожая проблема. В папке с ресурсами моего приложения были файлы HTML и видео.

Таким образом, видео были размещены внутри APK. Поскольку APK на самом деле является ZIP-файлом, WebView не мог читать видеофайлы.

У меня сработало копирование всех HTML- и видео-файлов на SD-карту.

RhodanV5500
источник