我正在拼凑一个廉价的应用程序,其中包括“框架”我们的一些网站......非常简单 WebViewClient. 。直到我点击视频。

视频完成为 HTML5 元素,这些在 Chrome、iPhone 上工作得很好,现在我们修复了编码问题,它在上面工作得很好 Android 在本机浏览器中。

现在是摩擦: WebView 不喜欢它。完全没有。我可以点击海报图像,但没有任何反应。

谷歌搜索,我发现 这很接近,但似乎基于“链接”(如 href...)而不是视频元素。(onDownloadListener 似乎没有在视频元素上调用...)

我还看到了对重写 onShowCustomView 的引用,但这似乎没有在视频元素上调用......也不应该OverrideUrlLoading..

我不想进入“从服务器提取 xml,在应用程序中重新格式化它”的情况。通过将故事布局保留在服务器上,我可以更好地控制内容,而无需强迫人们不断更新应用程序。因此,如果我能够说服 WebView 像本机浏览器一样处理标签,那就最好了。

我显然错过了一些明显的东西..但我不知道是什么。

有帮助吗?

解决方案

我回答这个话题,以防万一有人读它,有兴趣的结果。 它可以查看一个网页视图内的视频元素(HTML5视频标签),但我必须说,我必须处理它几天。这些是步骤我不得不跟随到目前为止:

- 查找正确编码的视频

- 当初始化所述web视图,设置的JavaScript,插件的WebViewClient和WebChromeClient。

url = new String("http://broken-links.com/tests/video/"); 
mWebView = (WebView) findViewById(R.id.webview);
mWebView.setWebChromeClient(chromeClient);
mWebView.setWebViewClient(wvClient);
mWebView.getSettings().setJavaScriptEnabled(true);
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事件,为了得到回Web视图。

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框架内发挥,而不是打开媒体播放器窗口,但是这对我来说是次要的问题。

我希望它可以帮助别人,我也将感谢任何意见或建议。

Saludos,terrícolas。

其他提示

经过长期的研究,我得到了这件事情的工作。请参见下面的代码:

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

东西剩下期待你能理解。

mdelolmo 的回答非常有帮助,但正如他所说,视频只播放一次,然后你就无法再次打开它。

我对此进行了一些研究,这就是我的发现,以防像我这样疲惫的 WebView 旅行者将来偶然发现这篇文章。

首先,我看了 视频查看媒体播放器的文档并更好地了解它们是如何工作的。我强烈推荐这些。

然后,我看了看 源码看看Android浏览器如何 可以。进行页面查找并看看他们如何处理 onShowCustomView(). 。他们保留了对 CustomViewCallback并转到自定义视图。

考虑到所有这些,并考虑到 mdelolmo 的答案,当您完成视频后,您需要做的就是两件事。首先,关于 VideoView 您保存了参考,调用 stopPlayback() 这将释放 MediaPlayer 稍后在其他地方使用。您可以在 视频查看 源代码。其次,关于 CustomViewCallback 您保存了呼叫参考 CustomViewCallback.onCustomViewHidden().

完成这两件事后,您可以单击同一视频或任何其他视频,它将像以前一样打开。无需重新启动整个WebView。

希望有帮助。

实际上,似乎足以仅附加一个股票WebChromeClient到客户端视图,阿拉

mWebView.setWebChromeClient(new WebChromeClient());

和你需要有硬件加速开启!

至少,如果你并不需要发挥全屏幕视频,没有必要拉VideoView出的WebView,并将其推入活动的看法。它会在视频元素的分配矩形玩。

任何想法如何截取扩大视频按钮?

我知道这个线程是好几个月了,但我发现了一个解决方案,用以播放的WebView里面的视频,而无需做全屏(但仍然在媒体播放器...)。到目前为止,我没有发现在这个互联网上的任何暗示,所以也许这也是对别人感兴趣。 我仍然在努力对一些问题(即放置在屏幕的右侧部分的媒体播放器,不知道为什么,我做错了,但它是一个相对较小的问题,我认为...)。

在自定义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();
         }
     }
 }

所以,我希望我能帮助......我也曾经有过玩弄视频编码和锯不同类型的使用与HTML5视频的WebView的 - 到底我的工作代码是不同的代码部分的野生搭配我在互联网上,有些事情我不得不自己找出找到。这真的是在一个*疼痛。

此方法效果非常好,直到2.3 并通过添加硬件加速=真它甚至从3.0到ICS 有一个问题我面临的是目前在第二次发射的媒体播放器应用程序崩溃得到,因为我从来没有停止播放并发布了媒体播放器。 作为VideoSurfaceView对象,这是我们在onShowCustomView功能从3.0 OS获得,是特定的浏览器,而不是一个VideoView对象中,直到2.3 OS 我怎样才能访问它和stopPlayback和释放资源?

A-M 类似于 浏览器活动 做。对于framelayout.layoutparams layoutparameters = new Framelayout.layoutparams(768,512);

我想我们可以使用

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

反而。

我遇到的另一个问题是,如果视频正在播放,并且用户单击后退按钮,下次您转到此活动(单顶活动)并且无法播放视频。为了解决这个问题,我打电话给

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

在活动的 onBackPressed 方法中。

我知道这是一个很老的问题,但你有没有尝试过的hardwareAccelerated="true"清单标志为您的应用或活动?

通过这个集合,它似乎工作而没有任何修改WebChromeClient(我期望从一个DOM-元素。)

我用 html5webview 来解决这个problem.Download并把它放到你的项目,那么你可以代码就这样。

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);
}

让视频旋转,把机器人:configChanges =“方向”的代码到你的活动 例如(AndroidManifest.xml中)

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

和覆盖onConfigurationChanged方法。

@Override
public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);
}

此问题是岁,但也许我的回答将帮助我这样的人谁也支持老版本的Android。我尝试了很多的这部分Android版本的工作不同的方法,但不是所有的。我发现最好的解决办法是使用人行横道网页视图这是对HTML5特性的支持和优化工作在Android 4.1更高。这是因为简单易用作为默认的Android的WebView。你只需要包括图书馆。在这里,你可以找到关于如何使用它的一个简单的教程: https://diego.org/2015/01/07/embedding-crosswalk-in-android-studio/

显然,如果不使用 JNI 注册插件来获取视频事件,这是不可能的。(就我个人而言,我避免使用 JNI,因为我真的不想在未来几个月内出现基于 Atom 的 Android 平板电脑时陷入混乱,从而失去 Java 的可移植性。)

唯一真正的替代方案似乎是仅为 WebView 创建一个新网页,并使用上面 Codelark url 中引用的 A HREF 链接以老式方式制作视频。

恶心。

在蜂窝使用hardwareaccelerated=truepluginstate.on_demand似乎工作

我也有类似的问题。我曾在我的应用程序的资产文件夹的HTML文件和视频。

因此,视频是位于APK的内部。因为APK确实是一个ZIP文件,web视图无法读取视频文件。

复制所有的HTML和视频文件到SD卡为我工作。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top