【问题标题】:Xamarin forms play sound with CrossSimpleAudioPlayerXamarin 使用 CrossSimpleAudioPlayer 播放声音
【发布时间】:2019-03-07 10:22:52
【问题描述】:

我想播放我使用 CrossSimpleAudioPlayer 插件下载的声音。

我实例化并初始化插件,在 IOS 上一切正常,但在 android 上,当我加载文件“Java.IO.FileNotFoundException”时,它给了我这个错误 但文件存在且有读取权限

并且在控制台上出现这个“[MediaPlayer] error (1, -2147483648)”。

我以这种方式加载剪辑

ISimpleAudioPlayer player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
player.Load("/data/user/0/com.my.app/files/20.wav");

当我使用 Stream 加载时,向我抛出错误“Java.IO.IOException: Prepare failed.: status=0x1”

var temp = new MemoryStream(DependencyService.Get<IFileHelper>().GetFileAsByte(path));
//This works fine and loads the file
player.Load(temp); //throws the error

如果我加载链接而不是本地文件,这可以正常工作,但我需要一个本地文件。

我不知道为什么在 Android 上会发生这种情况

【问题讨论】:

  • 您的文件在哪里?在模拟器、真实设备或 VS 项目中。
  • 如果音频文件是从Android本地资源文件夹加载的,请确保音频文件通过属性选择设置到Bundle Resource中
  • @CGPA6.4 文件在真机中,路径正确
  • 可能 CrossSimpleAudioPlayer 没有那么强大,在 Android 中无法获得这样的路径。尝试使用原生 android 方法 MediaPlayer 来做。 DependencyService 可能有用。docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/…
  • @JuniorJiang-MSFT 这也不起作用。出现同样的错误

标签: xamarin xamarin.forms


【解决方案1】:

您正在从内部存储(文件目录)读取您的声音文件。 Files 目录是一个私有目录,只能由您的应用程序访问。用户或操作系统都无法访问此文件。

这个路径是这样的:

/data/user/0/com.my.app/files/20.wav

您必须从Public External StoragePrivate External Storage 读取文件。这取决于您是否希望 MediaStore 内容提供商可以访问您的声音文件。

这里的声音文件可以从公共外部存储中读取,路径如下:

/storage/emulated/0/.../

并且需要在manifest中添加权限:

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

但这还不够。必须在像这样访问外部存储之前询问权限(在此处使用 NuGet 插件 Current Activity for Android 项目来获取当前活动):

var currentActivity = CrossCurrentActivity.Current.Activity;
            int requestCode=1;

            ActivityCompat.RequestPermissions(currentActivity, new string[] {
                Manifest.Permission.ReadExternalStorage,
                Manifest.Permission.WriteExternalStorage
            }, requestCode);

如果授予权限,则继续并将文件复制到外部存储:

var recordingFileExternalPath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, AppConstants.CUSTOM_ALERT_FILENAME);

            if (ContextCompat.CheckSelfPermission(Android.App.Application.Context, Manifest.Permission.WriteExternalStorage) == (int)Permission.Granted)
            {
                try
                {
                    if (File.Exists(recordingFileExternalPath))
                    {
                        File.Delete(recordingFileExternalPath);
                    }

                    File.Copy(filePath, recordingFileExternalPath);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            else
            {
                UserDialogs.Instance.Alert("Permission to write to External Storage not approved, cannot save settings.", "Permission Denied", "Ok");
            }

如果不能在 CrossSimpleAudioPlayer 中工作,您可以使用DependencyServiceMediaPlayer 播放音频。最好使用流播放如下:

File tempFile = new File(path);           
FileInputStream fis = new FileInputStream(tempFile);             
mediaPlayer.reset();             
mediaPlayer.setDataSource(fis.getFD());             
mediaPlayer.prepare();             
mediaPlayer.start();

【讨论】:

  • 那行不通。我已将文件从内部存储复制到公共存储(我检查了文件并成功复制),当我从 MediaPlayer 进行准备时,它向我抛出异常“Java.IO.IOException: Prepare failed.: status=0x1”我已经添加了该权限
  • @micaelcunha 必须在访问外部存储之前询问权限。我会更新答案。
  • 你的回答真的很好很完整。但我的问题不在于权限,我在写入文件之前已经实时请求权限。但是我还是测试了你的代码,结果是一样的,在原生 android 中使用 MediaPlayer 会抛出“Java.IO.IOException: Prepare failed.: status=0x1”,使用写入外部存储器的新文件。
  • @micaelcunha 尝试使用流播放。从错误日志中,参考这个。stackoverflow.com/questions/3761305/…我会更新答案。
  • 就像我已经说过的,我已经测试了该页面中的所有代码,但没有任何效果。我再次测试了你建议的新代码,结果是一样的,同样的错误。
猜你喜欢
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 2014-08-15
  • 2014-04-01
  • 2021-11-23
  • 1970-01-01
相关资源
最近更新 更多