简介

在树莓派小车控制软件项目中,遇到了需要在WebView中播放视频的需求,本文主要讲解如何在WebView中播放来自树莓派摄像头的视频流。

使用方法

声明联网权限

<uses-permission android:name="android.permission.INTERNET" />

声明使用明文传输信息

用于解决Android WebView 加载失败(net::ERR_CLEARTEXT_NOT_PERMITTED)的问题

原因:从Android 9.0(API级别28)开始,默认情况下限制了明文流量的网络请求,对未加密流量不再信任,直接放弃请求,因此http的url均无法在webview中加载,https 不受影响。

解决方案1:在Mainfest.xml的Application中声明使用明文传输

<manifest ...>
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>

解决方案2:改用https

解决方案3:将targetSdkVersion 降级回到 27

关于修改后还提示 ERR_ACCESS_DENIED的解决方案

卸载并重新安装app即可解决

相关链接:https://stackoverflow.com/questions/57131662/err-access-denied-in-webview-in-android

开启硬件加速

开启硬件加速,在 AndroidManifest.xml 中声明 HardwareAccelerate 属性,可在 application、activity 或代码中任意选一种方式设置。

// 在application中
<application android:hardwareAccelerated ="true">

// 在activity中
<activity android:hardwareAccelerated="true" >

// 在代码中
getWindow.setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

编写activity布局

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="top.hash070.myvideoview">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyVideoView"
        android:usesCleartextTraffic="true"
        android:hardwareAccelerated ="true"
        >
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:screenOrientation="landscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

编写activity代码

package top.hash070.myvideoview;

import androidx.appcompat.app.AppCompatActivity;

import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.MediaController;
import android.widget.VideoView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //去除标题栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //去除状态栏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);//要放到加载布局文件代码之前

        WebView myWebView =(WebView) findViewById(R.id.webview);
        myWebView = (WebView) findViewById(R.id.webview);//获取view

        WebSettings WebSet = myWebView.getSettings();    //获取webview设置
        WebSet.setJavaScriptEnabled(true);              //设置JavaScript支持

        WebSet.setSupportZoom(true);            // 设置可以支持缩放

        WebSet.setBuiltInZoomControls(true);    // 设置出现缩放工具

        WebSet.setUseWideViewPort(true);        //扩大比例的缩放

        WebSet.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);   //自适应屏幕
        WebSet.setLoadWithOverviewMode(true);

        myWebView.loadUrl("http://192.168.1.180:8080/?action=stream");

    }
}

Q.E.D.