在 Xamarin Android 中请求许可 CaptureAudioOutput 时出现问题

问题描述

我在 Xamarin Android 中开发的应用遇到了困难。 我需要捕获设备的音频输出以对音频流做一些奇特的事情。 但是当应用程序要求用户权限 Manifest.Permission.CaptureAudioOutput 没有弹出窗口显示并且权限返回被拒绝。 这个问题对于权限 RecordAudio 显示得很好。

我在运行 Android 10 的华为 P20 上对其进行了测试。

这是相关的代码。 MainActivaty.cs:

namespace TestApp
{
    [Activity(Label = "@string/app_name",Theme = "@style/AppTheme.NoActionBar",MainLauncher = true)]
    public class MainActivity : AppCompatActivity
    {
        private readonly int REQUEST_AUdio_RECORD = 2;
        private readonly int REQUEST_CAPTURE_AUdio = 3;
        private bool AudioRecordGranded = false;
        private bool AudioCaptureGranded = false;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this,savedInstanceState);
            SetContentView(Resource.Layout.activity_main);

            //Some setting up the view
        }

        public override void OnAttachedToWindow()
        {
            base.OnAttachedToWindow();
            CheckAudioCapturePermission();
        }

        private void CheckAudioCapturePermission()
        {
            if (ContextCompat.CheckSelfPermission(this,Manifest.Permission.RecordAudio) == (int)Permission.Granted)
            {
                AudioRecordGranded = true;
            }
            else
            {
                var requiredPermissions = new String[] { Manifest.Permission.RecordAudio };
                ActivityCompat.RequestPermissions(this,requiredPermissions,REQUEST_AUdio_RECORD);
            }

            if (ContextCompat.CheckSelfPermission(this,Manifest.Permission.CaptureAudioOutput) == (int)Permission.Granted)
            {
                AudioCaptureGranded = true;
            }
            else
            {
                var requiredPermissions = new String[] { Manifest.Permission.CaptureAudioOutput };
                ActivityCompat.RequestPermissions(this,REQUEST_CAPTURE_AUdio);
            }
        }

        public override void OnRequestPermissionsResult(int requestCode,string[] permissions,Permission[] grantResults)
        {
            if (requestCode == REQUEST_AUdio_RECORD)
            {
                if ((grantResults.Length == 1) && (grantResults[0] == Permission.Granted))
                {
                    AudioRecordGranded = true;
                }
                else
                {
                    AudioRecordGranded = false;
                }
            }
            else if (requestCode == REQUEST_CAPTURE_AUdio)
            {
                if ((grantResults.Length == 1) && (grantResults[0] == Permission.Granted))
                {
                    AudioCaptureGranded = true;
                }
                else
                {
                    AudioCaptureGranded = false;
                }
            }
            else
            {
                base.OnRequestPermissionsResult(requestCode,permissions,grantResults);
            }
        }
    }
}

AndroidManifest.xml:

?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
          android:versionCode="1" 
          android:versionName="1.0" 
          package="com.companyname.testapp">
  <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="30" />
  <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/AppTheme">
  </application>
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.CAPTURE_AUdio_OUTPUT" />
  <uses-permission android:name="android.permission.RECORD_AUdio" />
</manifest>

在我寻求获得许可的过程中,我发现要获得此许可,您必须签署 APK。 (找不到我找到的链接) 所以我自己创建了一个密钥库。 这是 .csproj 中的一个片段:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Anycpu' ">
    <DebugSymbols>True</DebugSymbols>
    <DebugType>portable</DebugType>
    <Optimize>False</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
    <AndroidLinkMode>None</AndroidLinkMode>
    <EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk>
    <AndroidKeyStore>true</AndroidKeyStore>
    <AndroidSigningKeyStore>C:\Users\****\AppData\Local\Xamarin\Mono for Android\Keystore\DM\DM.keystore</AndroidSigningKeyStore>
    <AndroidSigningStorePass>****</AndroidSigningStorePass>
    <AndroidSigningKeyAlias>TestApp</AndroidSigningKeyAlias>
    <AndroidSigningKeyPass>****</AndroidSigningKeyPass>
  </PropertyGroup>

这是请求权限时的调试输出

[Mono] DllImport searching in: '__Internal' ('(null)').
[Mono] Searching for 'java_interop_jnienv_new_object_array'.
[Mono] Probing 'java_interop_jnienv_new_object_array'.
[Mono] Found as 'java_interop_jnienv_new_object_array'.
[Mono] DllImport searching in: '__Internal' ('(null)').
[Mono] Searching for 'java_interop_jnienv_set_object_array_element'.
[Mono] Probing 'java_interop_jnienv_set_object_array_element'.
[Mono] Found as 'java_interop_jnienv_set_object_array_element'.
[Mono] DllImport searching in: '__Internal' ('(null)').
[Mono] Searching for 'java_interop_jnienv_call_static_void_method_a'.
[Mono] Probing 'java_interop_jnienv_call_static_void_method_a'.
[Mono] Found as 'java_interop_jnienv_call_static_void_method_a'.
[Mono] DllImport searching in: '__Internal' ('(null)').
[Mono] Searching for 'java_interop_jnienv_get_object_array_element'.
[Mono] Probing 'java_interop_jnienv_get_object_array_element'.
[Mono] Found as 'java_interop_jnienv_get_object_array_element'.
[HiTouch_PressGestureDetector] onAttached,package=com.companyname.TestApp,windowType=1,mHiTouchRestricted=false
[iGraphics] [0020080c] pn: com.companyname.TestApp,p: 7920
[iGraphics] [0030080c] no spt app: com.companyname.TestApp
[mali_winsys] EGLint new_window_surface(egl_winsys_display *,void *,EGLSurface,EGLConfig,egl_winsys_surface **,EGLBoolean) returns 0x3000
[Gralloc3] mapper 3.x is not supported
[] APS:IFLoad:importExternalFunctions,search function createNewHwApsUtils Failed,dlsym err:undefined symbol: createNewHwApsUtils
[] APS:importExternalFunctions OK
[Openglrenderer] Davey! duration=13226ms; Flags=1,IntendedVsync=45779746174646,Vsync=45779746174646,OldestInputEvent=9223372036854775807,NewestInputEvent=0,HandleInputStart=45779746937284,AnimationStart=45779747036763,PerformTraversalsstart=45779747039888,DrawStart=45792915065928,SyncQueued=45792925641449,SyncStart=45792926460720,IssueDrawCommandsstart=45792926662282,SwapBuffers=45792966599261,FrameCompleted=45792973046136,DequeueBufferDuration=171000,QueueBufferDuration=2534000,[AwareBitmapCacher] handleInit switch not opened pid=7920
[HwViewRootImpl] removeInvalidNode jank list is null
[Mono] DllImport searching in: '__Internal' ('(null)').
[Mono] Searching for 'java_interop_jnienv_get_int_array_region'.
[Mono] Probing 'java_interop_jnienv_get_int_array_region'.
[Mono] Found as 'java_interop_jnienv_get_int_array_region'.

谁能告诉我正确的方向,我被卡住了......

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)