"开放失败:EACCES(权限被拒绝)"用Xamarin录制音频

时间:2016-09-01 06:42:04

标签: c# xamarin xamarin.android xamarin.forms

我试图跟随this recipe使用Xamarin录制音频。它是一个Xamarin.Forms解决方案,但目前我只为Android开发。我不得不说我是C#/ .NET开发人员,这是我与Android的第一次联系。我创建了"服务" MicTest.Droid项目中的文件夹,我把服务放在那里:

[assembly: Dependency(typeof(MicrophoneService))]
namespace MicTest.Droid.Services
{
    public class MicrophoneService : IMicrophoneService
    {
        public string FileName { get; private set; }
        public string FilePath { get { return Path.Combine("data", $"{this.FileName}.3gpp"); } }

        private MediaRecorder recorder;

        public MicrophoneService() { }

        public void StartRecording(string fileName)
        {
            try
            {
                this.FileName = fileName;
                //bool exist = Directory.Exists("data");

                this.recorder = new MediaRecorder();
                this.recorder.SetAudioSource(AudioSource.Mic);
                this.recorder.SetOutputFormat(OutputFormat.ThreeGpp);
                this.recorder.SetAudioEncoder(AudioEncoder.AmrNb);
                this.recorder.SetOutputFile(this.FilePath);
                this.recorder.Prepare(); // It crashes here
                this.recorder.Start();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
        }

        public void StopRecording()
        {
            try
            {
                this.recorder.Stop();
                this.recorder.Reset();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
        }
    }
}

IMicrophoneService接口位于共享项目中:

namespace MicTest.Services
{
    public interface IMicrophoneService
    {
        void StartRecording(string fileName);
        void StopRecording();
    }
}

这就是例外:

data/2016-08-31 16.22.58.3gpp: open failed: EACCES(Permission denied)
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] in /Users/builder/data/lanes/2923/52635947/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
  at Java.Interop.JniEnvironment+InstanceMethods.CallVoidMethod (JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00084] in /Users/builder/data/lanes/3340/4e275588/source/Java.Interop/src/Java.Interop/Java.Interop/JniEnvironment.g.cs:11643 
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00031] in /Users/builder/data/lanes/3340/4e275588/source/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:26 
  at Android.Media.MediaRecorder.Prepare() [0x00000] in /Users/builder/data/lanes/3340/4e275588/source/monodroid/src/Mono.Android/platforms/android-23/src/generated/Android.Media.MediaRecorder.cs:476 
  at MicTest.Droid.Services.MicrophoneService.StartRecording(System.String fileName) [0x0006f] in F:\Probak\Xamarin\MicTest\MicTest\MicTest.Droid\Services\MicrophoneService.cs:53       --- End of managed exception stack trace ---
java.io.FileNotFoundException: data/2016-08-31 16.22.58.3gpp: open failed: EACCES(Permission denied)
    at libcore.io.IoBridge.open(IoBridge.java:456)
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:117)
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:149)
    at android.media.MediaRecorder.prepare(MediaRecorder.java:750)
    at md5b60ffeb829f638581ab2bb9b1a7f4f3f.ButtonRenderer_ButtonClickListener.n_onClick(Native Method)
    at md5b60ffeb829f638581ab2bb9b1a7f4f3f.ButtonRenderer_ButtonClickListener.onClick(ButtonRenderer_ButtonClickListener.java:30)
    at android.view.View.performClick(View.java:4763)
    at android.view.View$PerformClick.run(View.java:19821)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5272)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
Caused by: android.system.ErrnoException: open failed: EACCES(Permission denied)
    at libcore.io.Posix.open(Native Method)
    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
    at libcore.io.IoBridge.open(IoBridge.java:442)
    ... 15 more

最后,这是清单文件(将来我想使用位置服务):

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto">
    <uses-sdk android:minSdkVersion="15" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <application android:label="$safeprojectname$"></application>
</manifest>

我不知道我是否可以使用&#34;数据&#34;文件夹与否,我尝试使用其他文件夹,如Android.OS.Environment.DirectoryDownloads,结果相同。我忘记了什么吗?

1 个答案:

答案 0 :(得分:0)

您可以尝试保存到应用的缓存目录以验证您的权限:

var fileName = "audio.3gpp";
fileName = Path.Combine(Android.Content.Context.CacheDir.Path, fileName)
this.FileName = fileName;