【问题标题】:Avoiding the deprecated `Forms.Context` on playing audio on Xamarinn Forms Android避免在 Xamarinn Forms Android 上播放音频时弃用的 `Forms.Context`
【发布时间】:2020-05-07 03:21:49
【问题描述】:

如何使用 Xamarin Forms 在 Android 上播放音频?我有以下服务,这可行,但 Forms.Context 已弃用,并显示消息“上下文在 2.5 版已过时。请改用本地上下文。”。

[assembly: Dependency(typeof(AudioService))]
namespace SensaLabScan.Droid.Services
{
    public class AudioService : IAudioService
    {
        private readonly MediaPlayer _mediaPlayer = new MediaPlayer();

        public void PlayBeep()
        {
            _mediaPlayer.Reset();

            // Forms.Context references the Activity which calls Forms.Init, i.e. MainActivity.
            using (var beepFile = Forms.Context.Assets.OpenFd("beep.mp3"))
            {
                _mediaPlayer.SetDataSource(beepFile);
                _mediaPlayer.Prepare();
                _mediaPlayer.Start();
            }
        }
    }
}

在这种情况下,已弃用的Forms.Context 的替代方案是什么?我试过了

  1. Android.App.Application.Context.Assets.OpenFd("beep.pm3"); 但这会引发文件未找到异常
  2. 使用MainActivity 作为上下文并从中使用Assets,但再次找不到文件错误。

我要阅读的 mp3 文件位于 Assets 文件夹中,并标记为 AndroidAsset

【问题讨论】:

  • 只是想一想,Forms.ContextAndroid.App.Application.Context 的上下文是否属于同一类型(ApplicationContext 或 ActivityContext)。我有一个类似的问题与这些混合。
  • @Nikhileshwar 表单上下文和应用程序上下文可能属于同一类型,但它们不是一回事!!一个只有活动级别上下文,而另一个拥有应用程序上下文。详情请查看我的回答

标签: android xamarin xamarin.forms xamarin.android


【解决方案1】:

同意 Nikhileshwar,您应该将 Forms.Context 替换为 Android.App.Application.Context

这是我使用 DependenceService 播放音频的代码。

 [assembly: Dependency(typeof(MyDependenceService))]
 namespace MediaPlayDemo.Droid
 {
public class MyDependenceService : IPlayMedia
{
    public void playMusic()
    {
        //throw new NotImplementedException();


        var bytes = default(byte[]);
        using (StreamReader reader = new StreamReader(Android.App.Application.Context.Assets.Open("Test.mp3")))
        {
            using (var memstream = new MemoryStream())
            {
                reader.BaseStream.CopyTo(memstream);
                bytes = memstream.ToArray();
            }
        }
        Play(bytes);
    }


        //  Stop();

        MediaPlayer currentPlayer;
        public void Play(byte[] AudioFile)
        {
            Stop();
            currentPlayer = new MediaPlayer();
            currentPlayer.Prepared += (sender, e) =>
            {
                currentPlayer.Start();
            };
            currentPlayer.SetDataSource(new StreamMediaDataSource(new System.IO.MemoryStream(AudioFile)));
            currentPlayer.Prepare();
        }

        void Stop()
        {
            if (currentPlayer == null)
                return;

            currentPlayer.Stop();
            currentPlayer.Dispose();
            currentPlayer = null;
        }




}

public class StreamMediaDataSource : MediaDataSource
{
    System.IO.Stream data;

    public StreamMediaDataSource(System.IO.Stream Data)
    {
        data = Data;
    }

    public override long Size
    {

        get
        {
            return data.Length;
        }
    }

    public override int ReadAt(long position, byte[] buffer, int offset, int size)
    {
        data.Seek(position, System.IO.SeekOrigin.Begin);
        return data.Read(buffer, offset, size);
    }

    public override void Close()
    {
        if (data != null)
        {
            data.Dispose();
            data = null;
        }
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);

        if (data != null)
        {
            data.Dispose();
            data = null;
        }
    }
}
}

这是我的演示。

https://github.com/851265601/PlayAudio

【讨论】:

    【解决方案2】:

    始终确保应该使用哪个上下文作为应用程序上下文并不适合在任何地方使用,以便了解在哪里使用什么检查

    When to call activity context OR application context?

    处理此问题的最简单方法是使用此处描述的 CurrentActivity 插件设置过程:https://github.com/jamesmontemagno/CurrentActivityPlugin

    使用完之后你要做的就是:

     using (var beepFile = CrossCurrentActivity.Current.Activity.Assets.OpenFd("beep.mp3"))
            {
                _mediaPlayer.SetDataSource(beepFile);
                _mediaPlayer.Prepare();
                _mediaPlayer.Start();
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-25
      相关资源
      最近更新 更多