Как избежать устаревшего `Forms.Context` при воспроизведении аудио на Xamarinn Forms Android - PullRequest
0 голосов
/ 21 января 2020

Как воспроизводить аудио на Android с помощью форм Xamarin? У меня есть следующая служба, она работает, но 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, которые я хочу прочитать, находятся в папке «Ресурсы» и помечены как AndroidAsset .

.

Ответы [ 2 ]

0 голосов
/ 21 января 2020

Всегда проверяйте, какой контекст следует использовать для чего, поскольку контекст приложения не идеален для использования везде, для хорошей идеи знать, где использовать какую проверку

Когда вызывать контекст действия ИЛИ приложение context?

Самый простой способ справиться с этим - использовать описанный здесь процесс установки плагина CurrentActivity: https://github.com/jamesmontemagno/CurrentActivityPlugin

После этого все, что вам нужно сделать это:

 using (var beepFile = CrossCurrentActivity.Current.Activity.Assets.OpenFd("beep.mp3"))
        {
            _mediaPlayer.SetDataSource(beepFile);
            _mediaPlayer.Prepare();
            _mediaPlayer.Start();
        }
0 голосов
/ 21 января 2020

Согласитесь с 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

...