在 WebView [Android Studio] [Java] 中允许麦克风访问(权限)

Posted

技术标签:

【中文标题】在 WebView [Android Studio] [Java] 中允许麦克风访问(权限)【英文标题】:Allowing microphone access(permission) in WebView [Android Studio] [Java] 【发布时间】:2017-03-07 07:45:25 【问题描述】:

我目前正在开发一个使用 html5 和 webview 来显示“应用程序”的音乐调谐器。我已经在清单中编写了所需的所有权限,我认为对于 webview 还需要另一个权限。

我现在使用这个https://jbergknoff.github.io/guitar-tuner/ 作为重定向页面示例

这是我的 manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.raynordev.projectrosin">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MICROPHONE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.audio.low_latency" />
<uses-feature android:name="android.hardware.audio.pro" />
<uses-feature android:name="android.hardware.microphone" android:required="true"/>


<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name="com.raynordev.projectrosin.HomeActivity">        

  </activity>
 </application>
</manifest>

这是我的 .java

public class HomeActivity extends AppCompatActivity 

private WebView wv;
private String TAG = "HomeActivity";
private static final int REQUEST_INTERNET = 200;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);
    WebView wv = (WebView) findViewById(R.id.webView);
    wv.getSettings().setjavascriptEnabled(true);
    wv.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);


    wv.setWebViewClient(new WebViewClient());
    wv.setWebChromeClient(new WebChromeClient());

    wv.loadUrl("https://jbergknoff.github.io/guitar-tuner/");
 

如果需要我提供更多信息,请告诉我。

谢谢大家!!

【问题讨论】:

【参考方案1】:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

例子:

主活动

public class MainActivity extends AppCompatActivity 
    private static final int MY_PERMISSIONS_REQUEST_RECORD_AUDIO = 101;
    private ActivityMainBinding mBinding;
    private PermissionRequest myRequest;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        setWebView();
    

    private void setWebView() 
        mBinding.webView.getSettings().setJavaScriptEnabled(true);
        mBinding.webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        mBinding.webView.setWebViewClient(new WebViewClient());

        mBinding.webView.getSettings().setSaveFormData(true);
        mBinding.webView.getSettings().setSupportZoom(false);
        mBinding.webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
        mBinding.webViemBinding.webView.getSettings().setPluginState(WebSettings.PluginState.ON);


        mBinding.webView.setWebChromeClient(new WebChromeClient() 
            @Override
            public void onPermissionRequest(final PermissionRequest request) 
                myRequest = request;

                for (String permission : request.getResources()) 
                    switch (permission) 
                        case "android.webkit.resource.AUDIO_CAPTURE": 
                            askForPermission(request.getOrigin().toString(), Manifest.permission.RECORD_AUDIO, MY_PERMISSIONS_REQUEST_RECORD_AUDIO);
                            break;
                        
                    
                
            
        );

        mBinding.webView.loadUrl("<your url");
    

    @Override
    public void onBackPressed() 
        if (mBinding.webView.canGoBack()) 
            mBinding.webView.goBack();
         else 
            super.onBackPressed();
        
    

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) 
        switch (requestCode) 
            case MY_PERMISSIONS_REQUEST_RECORD_AUDIO: 
                Log.d("WebView", "PERMISSION FOR AUDIO");
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) 


                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                    myRequest.grant(myRequest.getResources());
                    mBinding.webView.loadUrl("<your url>");

                 else 

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                
            
            // other 'case' lines to check for other
            // permissions this app might request
        
    
    public void askForPermission(String origin, String permission, int requestCode) 
        Log.d("WebView", "inside askForPermission for" + origin + "with" + permission);

        if (ContextCompat.checkSelfPermission(getApplicationContext(),
                permission)
                != PackageManager.PERMISSION_GRANTED) 

            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                    permission)) 

                // Show an expanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.

             else 

                // No explanation needed, we can request the permission.

                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]permission,
                        requestCode);
            
         else 
            myRequest.grant(myRequest.getResources());
        
    


Mainfest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MICROPHONE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.audio.low_latency" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-feature android:name="android.hardware.audio.pro" />
<uses-feature android:name="android.hardware.microphone"/>      

Build.gradle:

android 
    compileSdkVersion 26
    defaultConfig 
        applicationId "myapp.example.com.myapplication"
        minSdkVersion 21
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    
    buildTypes 
        release 
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        
    

【讨论】:

为你的答案添加一些解释。 它可能没有任何解释,但它是唯一对我有用的。 request.getResources() 在 api 级别 19 以下不可用。我们有什么解决方案吗? 添加到Mainfest.xml 是使用 getUserMedia() 的关键 私有 ActivityMainBinding mBinding; mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);在这些行上面临错误【参考方案2】:

总结一下,你需要以下组件:

    MODIFY_AUDIO_SETTINGS 权限。 WebChromeClient 并监听 onPermissionRequest 的回调 在此回调中,检查request 对象中的资源,创建此request 对象的全局变量,迭代并在PermissionRequest 类中查找特定权限,例如。 PermissionRequest.RESOURCE_VIDEO_CAPTURE 转换为 Manifest.permission.CAMERA 权限,检查您的应用是否具有此权限,如果没有,请使用您希望的任何机制,如果是,请执行 4。 在权限回调中或者如果权限被授予,使用请求对象授予权限ex。 request.grant(new String[]PermissionRequest.RESOURCE_VIDEO_CAPTURE) 你很高兴。

sn-p:

webView.webChromeClient = object: WebChromeClient()
            override fun onPermissionRequest(request: PermissionRequest?) 
                super.onPermissionRequest(request)

                webkitPermissionRequest = request

                request?.resources?.forEach 
                    when(it)
                        PermissionRequest.RESOURCE_AUDIO_CAPTURE-> 
                            askForWebkitPermission(it, Manifest.permission.RECORD_AUDIO, REQUEST_CODE_PERMISSION_AUDIO)
                        
                        PermissionRequest.RESOURCE_VIDEO_CAPTURE->
                            askForWebkitPermission(it, Manifest.permission.CAMERA, REQUEST_CODE_PERMISSION_CAMERA)
                        
                    
                
            
        

private fun askForWebkitPermission(webkitPermission: String, androidPermission: String, requestCode: Int)
        val context = activity?: return
        if (context.hasPermission(androidPermission))
            webkitPermissionRequest!!.grant(arrayOf(webkitPermission))
        else
            requestPermissions(arrayOf(androidPermission), requestCode)
        
    

希望这会有所帮助。

Google 的相同示例:https://github.com/googlesamples/android-PermissionRequest

【讨论】:

为什么需要为请求创建全局变量?请求肯定是“通过引用”传递的,可以直接使用吗? 这是正确的答案,像这样的一些权限也需要通过 "webkitPermissionRequest!!.grant(arrayOf(webkitPermission))" 授予

以上是关于在 WebView [Android Studio] [Java] 中允许麦克风访问(权限)的主要内容,如果未能解决你的问题,请参考以下文章

android studio创建assets目录并且利用webView加载其html

Android Studio - 如何在 webview Lollipop 中上传文件 (Android 5.0)

Webview 在 Fragment Android Studio 中不起作用

通过 WebView (Android Studio) 导航到时,Youtube 在应用程序中启动

在 WebView [Android Studio] [Java] 中允许麦克风访问(权限)

Android Studio:地理定位不起作用。无法在 Webview 中获取地理位置