android webview 视频横竖屏切换,下载视频功能

1.webview加载视频,横竖屏切换

Activity内嵌WebView,加载有视频的页面时,视频无法全屏播放。全屏按钮不显示或者灰显。
页面布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff">

    <include
            android:id="@+id/include_toolbar"
            layout="@layout/toolbar"/>

    <FrameLayout
            android:id="@+id/fl_video"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"
            android:layout_below="@+id/include_toolbar"/>

    <WebView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/webView"
            android:layout_below="@+id/include_toolbar"
            android:layout_centerHorizontal="true"/>

    <LinearLayout
            android:id="@+id/llty_pbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:visibility="gone"
            android:gravity="center"
            android:orientation="horizontal">

        <ProgressBar
                android:id="@+id/pbar_more"
                android:layout_width="32dp"
                android:layout_height="32dp"/>

        <TextView
                android:id="@+id/loading_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8dp"
                android:text="加载中..."
                android:textSize="14sp"/>
    </LinearLayout>
</RelativeLayout>

主要就是fl_video和webView,这两个是需要横竖屏切换的。WebView在点击全屏按钮后,会调用onShowCustomView方法。而全屏的视频会在其参数View view中进行渲染。在onShowCustomView触发后,将其view传入fl_video,使APP横屏,fl_video全屏显示。

先设置硬件加速和横竖屏切换

 <activity
                android:name=".activity.WebViewActivity"
                android:screenOrientation="portrait"
                android:configChanges="keyboardHidden|orientation|screenSize"
                android:hardwareAccelerated = "true"/>

WebViewActivity里相关代码

   private FrameLayout mLayout;    // 用来显示视频的布局
    private View mCustomView;	//用于全屏渲染视频的View
    private WebChromeClient.CustomViewCallback mCustomViewCallback;
...
  public class MyWebChromeClient extends WebChromeClient
    {

        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result)
        {
            Log.i(TAG, "onJsAlert: " + message);
            return super.onJsAlert(view, url, message, result);
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message, JsResult result)
        {
            Log.i(TAG, "onJsConfirm: " + message);
            return super.onJsConfirm(view, url, message, result);
        }

        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
        {
            Log.i(TAG, "onJsPrompt: " + message);
            return super.onJsPrompt(view, url, message, defaultValue, result);
        }

        @Override
        public void onReceivedTitle(WebView view, String title)
        {
            super.onReceivedTitle(view, title);
        }
        @Override
        public void onShowCustomView(View view, CustomViewCallback callback) {
            super.onShowCustomView(view, callback);
            //如果view 已经存在,则隐藏
            if (mCustomView != null) {
                callback.onCustomViewHidden();
                return;
            }

            mCustomView = view;
            mCustomView.setVisibility(View.VISIBLE);
            mCustomViewCallback = callback;
            mLayout.addView(mCustomView);
            mLayout.setVisibility(View.VISIBLE);
            mLayout.bringToFront();

            //设置横屏
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        }

        @Override
        public void onHideCustomView() {
            super.onHideCustomView();

            if (mCustomView == null) {
                return;
            }
            mCustomView.setVisibility(View.GONE);
            mLayout.removeView(mCustomView);
            mCustomView = null;
            mLayout.setVisibility(View.GONE);
            try {
                mCustomViewCallback.onCustomViewHidden();
            } catch (Exception e) {
            }
//                titleView.setVisibility(View.VISIBLE);
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏

        }


    }

...

 /**
     * 横竖屏切换监听
     */
    @Override
    public void onConfigurationChanged(Configuration config) {
        super.onConfigurationChanged(config);
        switch (config.orientation) {
            case Configuration.ORIENTATION_LANDSCAPE:
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                toolbar.setVisibility(View.GONE);
                break;
            case Configuration.ORIENTATION_PORTRAIT:
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
                toolbar.setVisibility(View.VISIBLE);
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //清空所有cookie
        CookieSyncManager.createInstance(WebViewActivity.this);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.removeAllCookie();
        CookieSyncManager.getInstance().sync();
        webView.setWebChromeClient(null);
        webView.setWebViewClient(null);
        webView.getSettings().setJavaScriptEnabled(false);
        webView.clearCache(true);
        webView.destroy();

        if(receiver!=null){
            unregisterReceiver(receiver);
        }
    }

2.点击视频下载没反应

需要监听setDownloadListener,然后使用系统默认的下载管理器下载

   private   DownloadCompleteReceiver receiver;
  ...
  webView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
                // TODO: 2017-5-6 处理下载事件
                downloadBySystem(url,contentDisposition,mimeType);
                ToastUtil.showLongToast("正在下载中...");
            }
        });
   if(receiver!=null){
            unregisterReceiver(receiver);
        }
        // 使用
         receiver = new DownloadCompleteReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        registerReceiver(receiver, intentFilter);

 private void downloadBySystem(String url, String contentDisposition, String mimeType) {
        // 指定下载地址
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
        // 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库
        request.allowScanningByMediaScanner();
        // 设置通知的显示类型,下载进行时和完成后显示通知
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        // 设置通知栏的标题,如果不设置,默认使用文件名
//        request.setTitle("This is title");
        // 设置通知栏的描述
//        request.setDescription("This is description");
        // 允许在计费流量下下载
        request.setAllowedOverMetered(false);
        // 允许该记录在下载管理界面可见
        request.setVisibleInDownloadsUi(false);
        // 允许漫游时下载
        request.setAllowedOverRoaming(true);
        // 允许下载的网路类型
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
        // 设置下载文件保存的路径和文件名
        String fileName  = URLUtil.guessFileName(url, contentDisposition, mimeType);
        Log.d("fileName:{}", fileName);
        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
//        另外可选一下方法,自定义下载路径
//        request.setDestinationUri()
//        request.setDestinationInExternalFilesDir()
        final DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        // 添加一个下载任务
        long downloadId = downloadManager.enqueue(request);
         Log.d("downloadId:{}", downloadId+"");
    }

    private class DownloadCompleteReceiver extends BroadcastReceiver
    {

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("onReceive. intent:{}", intent != null ? intent.toUri(0) : null);
            if (intent != null) {
                if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
                    long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
                    Log.d("downloadId:{}", downloadId+"");
                    DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
                    String type = downloadManager.getMimeTypeForDownloadedFile(downloadId);
                    Log.d("getMimeTypeForDownloadedFile:{}", type);
                    if (TextUtils.isEmpty(type)) {
                        type = "*/*";
                    }
                    Uri uri = downloadManager.getUriForDownloadedFile(downloadId);
                    Log.d("UriForDownloadedFile:{}", uri+"");
                    if (uri != null) {
                        Intent handlerIntent = new Intent(Intent.ACTION_VIEW);
                        handlerIntent.setDataAndType(uri, type);
                        context.startActivity(handlerIntent);
                    }
                }
            }
        }
    }

别忘了在ondestroy中释放receiver

  if(receiver!=null){
            unregisterReceiver(receiver);
        }

完整代码

public class WebViewActivity extends BaseNeedContactActivity
{
    private static final String TAG = WebViewActivity.class.getSimpleName();

    public static final String WEBVIEW_TITLE = "webview_title";

    public static final String WEBVIEW_URL = "webview_url";

    public static final String WEBVIEW_ACTION = "webview_action";

    public static final String WEBVIEW_ACTION_PATTEN = "webview_action_patten";

    private WebAction action = null;

    private String actionPatten = null;

    @BindView(R.id.toolbar)
    Toolbar toolbar;

    @BindView(R.id.webView)
    WebView webView = null;

    @BindView(R.id.llty_pbar)
    LinearLayout llty_pbar;

    private String title = "";

    private ContactData contactData = null;
    private   DownloadCompleteReceiver receiver;
    private FrameLayout mLayout;    // 用来显示视频的布局
    private View mCustomView;	//用于全屏渲染视频的View
    private WebChromeClient.CustomViewCallback mCustomViewCallback;
    public static void start(Context context, String title, String url, String iM_ID)
    {
        Intent intent = new Intent(context, WebViewActivity.class);
        intent.putExtra(WEBVIEW_TITLE, title);
        intent.putExtra(WEBVIEW_URL, url);
        intent.putExtra(Extras.EXTRA_DATA, iM_ID);

        context.startActivity(intent);
    }

    public static void start(Context context, String title, String url, String actionPatten, WebAction action, String iM_ID)
    {
        Intent intent = new Intent(context, WebViewActivity.class);
        intent.putExtra(WEBVIEW_TITLE, title);
        intent.putExtra(WEBVIEW_URL, url);

        intent.putExtra(WEBVIEW_ACTION_PATTEN, actionPatten);
        intent.putExtra(WEBVIEW_ACTION, action);
        intent.putExtra(Extras.EXTRA_DATA, iM_ID);

        context.startActivity(intent);
    }

    public static void startForResult(Activity activity, String title, String url, int requestCode, String actionPatten, WebAction action)
    {
        Intent intent = new Intent(activity, WebViewActivity.class);
        intent.putExtra(WEBVIEW_TITLE, title);
        intent.putExtra(WEBVIEW_URL, url);

        intent.putExtra(WEBVIEW_ACTION_PATTEN, actionPatten);
        intent.putExtra(WEBVIEW_ACTION, action);

        activity.startActivityForResult(intent, requestCode);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view);

        //using butter knife
        ButterKnife.bind(this);
        mLayout = findViewById(R.id.fl_video);
        setToolBar(R.id.toolbar, true);
        initWebView();
        initData();

    }

    private void initData()
    {
        Intent intent = getIntent();
        if (intent == null)
        {
            ToastUtil.showToast("地址不能为空");
            return;
        }

        title = intent.getStringExtra(WEBVIEW_TITLE);
        if (TextUtils.isEmpty(title))
        {
            toolbar.setTitle("");
        }
        else
        {
            if (title.contains("("))
            {
                SpannableStringBuilder builder = new SpannableStringBuilder(title);
                AbsoluteSizeSpan span = new AbsoluteSizeSpan(15, true);
                builder.setSpan(span, title.indexOf("("), title.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                toolbar.setTitle(builder);
            }
            else
            {
                toolbar.setTitle(title);
            }
        }

        action = (WebAction) intent.getSerializableExtra(WEBVIEW_ACTION);
        actionPatten = intent.getStringExtra(WEBVIEW_ACTION_PATTEN);
        if (action == null || actionPatten == null)
        {
            action = null;
            actionPatten = null;
        }

        String url = intent.getStringExtra(WEBVIEW_URL);
        if (TextUtils.isEmpty(url))
        {
            ToastUtil.showToast("地址错误,地址不能为空");
            return;
        }
        else
        {
            webView.loadUrl(url);
            llty_pbar.setVisibility(View.VISIBLE);
        }


        String account = intent.getStringExtra(Extras.EXTRA_DATA);
        if(!TextUtils.isEmpty(account))
        {
            contactData = MyContactManager.getInstance().getContactByIm(account);
        }
    }

    private void initWebView()
    {
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        // 设置字符编码
        webSettings.setDefaultTextEncodingName("utf-8");
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setAllowFileAccess(true);
        webSettings.setLoadsImagesAutomatically(true);
        // webSettings.setAppCacheEnabled(true);
        // webSettings.setBlockNetworkImage(true);
        // webSettings.setGeolocationEnabled(true);
        webSettings.setSupportZoom(true);
        // webSettings.setBuiltInZoomControls(true);
        // webSettings.setPluginsEnabled(true);
        //webView.addJavascriptInterface(this, "AppInterface");
        webView.setWebChromeClient(new MyWebChromeClient());
        webView.setWebViewClient(new MyWebViewClient());
        webView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
                // TODO: 2017-5-6 处理下载事件
                downloadBySystem(url,contentDisposition,mimeType);
                ToastUtil.showLongToast("正在下载中...");
            }
        });

        if(receiver!=null){
            unregisterReceiver(receiver);
        }
        // 使用
         receiver = new DownloadCompleteReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        registerReceiver(receiver, intentFilter);
    }

    private void downloadBySystem(String url, String contentDisposition, String mimeType) {
        // 指定下载地址
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
        // 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库
        request.allowScanningByMediaScanner();
        // 设置通知的显示类型,下载进行时和完成后显示通知
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        // 设置通知栏的标题,如果不设置,默认使用文件名
//        request.setTitle("This is title");
        // 设置通知栏的描述
//        request.setDescription("This is description");
        // 允许在计费流量下下载
        request.setAllowedOverMetered(false);
        // 允许该记录在下载管理界面可见
        request.setVisibleInDownloadsUi(false);
        // 允许漫游时下载
        request.setAllowedOverRoaming(true);
        // 允许下载的网路类型
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
        // 设置下载文件保存的路径和文件名
        String fileName  = URLUtil.guessFileName(url, contentDisposition, mimeType);
        Log.d("fileName:{}", fileName);
        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
//        另外可选一下方法,自定义下载路径
//        request.setDestinationUri()
//        request.setDestinationInExternalFilesDir()
        final DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        // 添加一个下载任务
        long downloadId = downloadManager.enqueue(request);
         Log.d("downloadId:{}", downloadId+"");
    }

    private class DownloadCompleteReceiver extends BroadcastReceiver
    {

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("onReceive. intent:{}", intent != null ? intent.toUri(0) : null);
            if (intent != null) {
                if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
                    long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
                    Log.d("downloadId:{}", downloadId+"");
                    DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
                    String type = downloadManager.getMimeTypeForDownloadedFile(downloadId);
                    Log.d("getMimeTypeForDownloadedFile:{}", type);
                    if (TextUtils.isEmpty(type)) {
                        type = "*/*";
                    }
                    Uri uri = downloadManager.getUriForDownloadedFile(downloadId);
                    Log.d("UriForDownloadedFile:{}", uri+"");
                    if (uri != null) {
                        Intent handlerIntent = new Intent(Intent.ACTION_VIEW);
                        handlerIntent.setDataAndType(uri, type);
                        context.startActivity(handlerIntent);
                    }
                }
            }
        }
    }


    public class MyWebViewClient extends WebViewClient
    {

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
            // 如果不是url地址 我就不调用此跳转页面方法
            if (null != url && !"".equals(url) && (url.indexOf("/") < 0))
            {
                return false;
            }

            if (actionPatten != null && url.lastIndexOf(actionPatten) != -1)
            {
                if (title.equals("随访表单"))
                {
                    if (ManagerPlanDetailActivity.instance != null)
                    {
                        ManagerPlanDetailActivity.instance.finish();
                    }

                    if (VisitFormActivity.instance != null)
                    {
                        VisitFormActivity.instance.finish();
                    }

                    finish();
                }
                else
                {
                    action.doAction(WebViewActivity.this);
                }

                return true;
            }

            try
            {
                view.loadUrl(url);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return true;
        }

        @Override
        public void onPageFinished(WebView view, String url)
        {
            Log.i(TAG, "onPageFinished: url=" + url);

            llty_pbar.setVisibility(View.GONE);

        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)
        {
            //handler.cancel(); // Android默认的处理方式
            handler.proceed();  // 接受所有网站的证书
            //handleMessage(Message msg); // 进行其他处理
        }
    }

    public class MyWebChromeClient extends WebChromeClient
    {

        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result)
        {
            Log.i(TAG, "onJsAlert: " + message);
            return super.onJsAlert(view, url, message, result);
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message, JsResult result)
        {
            Log.i(TAG, "onJsConfirm: " + message);
            return super.onJsConfirm(view, url, message, result);
        }

        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
        {
            Log.i(TAG, "onJsPrompt: " + message);
            return super.onJsPrompt(view, url, message, defaultValue, result);
        }

        @Override
        public void onReceivedTitle(WebView view, String title)
        {
            super.onReceivedTitle(view, title);
        }
        @Override
        public void onShowCustomView(View view, CustomViewCallback callback) {
            super.onShowCustomView(view, callback);
            //如果view 已经存在,则隐藏
            if (mCustomView != null) {
                callback.onCustomViewHidden();
                return;
            }

            mCustomView = view;
            mCustomView.setVisibility(View.VISIBLE);
            mCustomViewCallback = callback;
            mLayout.addView(mCustomView);
            mLayout.setVisibility(View.VISIBLE);
            mLayout.bringToFront();

            //设置横屏
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        }

        @Override
        public void onHideCustomView() {
            super.onHideCustomView();

            if (mCustomView == null) {
                return;
            }
            mCustomView.setVisibility(View.GONE);
            mLayout.removeView(mCustomView);
            mCustomView = null;
            mLayout.setVisibility(View.GONE);
            try {
                mCustomViewCallback.onCustomViewHidden();
            } catch (Exception e) {
            }
//                titleView.setVisibility(View.VISIBLE);
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏

        }


    }

    public static interface WebAction extends Serializable
    {
        public void doAction(WebViewActivity webViewActivity);
    }

    @Override
    protected ContactData getCurrContactData()
    {
        return contactData;
    }
    /**
     * 横竖屏切换监听
     */
    @Override
    public void onConfigurationChanged(Configuration config) {
        super.onConfigurationChanged(config);
        switch (config.orientation) {
            case Configuration.ORIENTATION_LANDSCAPE:
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                toolbar.setVisibility(View.GONE);
                break;
            case Configuration.ORIENTATION_PORTRAIT:
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
                toolbar.setVisibility(View.VISIBLE);
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //清空所有cookie
        CookieSyncManager.createInstance(WebViewActivity.this);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.removeAllCookie();
        CookieSyncManager.getInstance().sync();
        webView.setWebChromeClient(null);
        webView.setWebViewClient(null);
        webView.getSettings().setJavaScriptEnabled(false);
        webView.clearCache(true);
        webView.destroy();

        if(receiver!=null){
            unregisterReceiver(receiver);
        }
    }


}

参考文章
三种方式让 Android WebView 支持文件下载
Android WebView 视频播放,全屏按钮不显示或灰显解决方案

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值