Xamarin.Forms
Доступ к собственным функциям с помощью DependencyService
Поиск…
замечания
Если вы не хотите, чтобы ваш код прерывался, когда реализация не была найдена, сначала проверьте DependencyService
если она имеет доступную реализацию.
Вы можете сделать это с помощью простой проверки, если она не равна null
.
var speaker = DependencyService.Get<ITextToSpeech>();
if (speaker != null)
{
speaker.Speak("Ready for action!");
}
или, если ваша среда IDE поддерживает C # 6, с оператором с нулевым условием:
var speaker = DependencyService.Get<ITextToSpeech>();
speaker?.Speak("Ready for action!");
Если вы этого не сделаете, и реализация не будет реализована во время выполнения, ваш код будет генерировать исключение.
Реализация текста в речь
Хорошим примером функции, запрашивающей специфический для платформы код, является то, что вы хотите реализовать текст в речь (tts). В этом примере предполагается, что вы работаете с общим кодом в библиотеке PCL.
Схематический обзор нашего решения будет выглядеть как снизу.
В нашем общем коде мы определяем интерфейс, который зарегистрирован в DependencyService
. Здесь мы будем делать наши призывы. Определите интерфейс, как внизу.
public interface ITextToSpeech
{
void Speak (string text);
}
Теперь в каждой конкретной платформе нам необходимо создать реализацию этого интерфейса. Начнем с реализации iOS.
Внедрение iOS
using AVFoundation;
public class TextToSpeechImplementation : ITextToSpeech
{
public TextToSpeechImplementation () {}
public void Speak (string text)
{
var speechSynthesizer = new AVSpeechSynthesizer ();
var speechUtterance = new AVSpeechUtterance (text) {
Rate = AVSpeechUtterance.MaximumSpeechRate/4,
Voice = AVSpeechSynthesisVoice.FromLanguage ("en-US"),
Volume = 0.5f,
PitchMultiplier = 1.0f
};
speechSynthesizer.SpeakUtterance (speechUtterance);
}
}
В приведенном выше примере кода вы заметите, что для iOS существует определенный код. Подобно типам AVSpeechSynthesizer
. Они не будут работать в общем коде.
Чтобы зарегистрировать эту реализацию с помощью Xamarin DependencyService
добавьте этот атрибут над объявлением пространства имен.
using AVFoundation;
using DependencyServiceSample.iOS;//enables registration outside of namespace
[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.iOS {
public class TextToSpeechImplementation : ITextToSpeech
//... Rest of code
Теперь, когда вы делаете такой вызов в своем общем коде, вводится правильная реализация для платформы, на которой выполняется ваше приложение.
DependencyService.Get<ITextToSpeech>()
. Подробнее об этом позже.
Реализация Android
Реализация этого кода для Android будет выглядеть как внизу.
using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;
public class TextToSpeechImplementation : Java.Lang.Object, ITextToSpeech, TextToSpeech.IOnInitListener
{
TextToSpeech speaker;
string toSpeak;
public TextToSpeechImplementation () {}
public void Speak (string text)
{
var ctx = Forms.Context; // useful for many Android SDK features
toSpeak = text;
if (speaker == null) {
speaker = new TextToSpeech (ctx, this);
} else {
var p = new Dictionary<string,string> ();
speaker.Speak (toSpeak, QueueMode.Flush, p);
}
}
#region IOnInitListener implementation
public void OnInit (OperationResult status)
{
if (status.Equals (OperationResult.Success)) {
var p = new Dictionary<string,string> ();
speaker.Speak (toSpeak, QueueMode.Flush, p);
}
}
#endregion
}
Снова не забудьте зарегистрировать его в DependencyService
.
using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;
[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.Droid{
//... Rest of code
Реализация Windows Phone
Наконец, для Windows Phone этот код можно использовать.
public class TextToSpeechImplementation : ITextToSpeech
{
public TextToSpeechImplementation() {}
public async void Speak(string text)
{
MediaElement mediaElement = new MediaElement();
var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Hello World");
mediaElement.SetSource(stream, stream.ContentType);
mediaElement.Play();
await synth.SynthesizeTextToStreamAsync(text);
}
}
И еще раз не забудьте зарегистрировать его.
using Windows.Media.SpeechSynthesis;
using Windows.UI.Xaml.Controls;
using DependencyServiceSample.WinPhone;//enables registration outside of namespace
[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.WinPhone{
//... Rest of code
Внедрение в общий код
Теперь все на месте, чтобы заставить его работать! Наконец, в вашем общем коде вы можете теперь вызвать эту функцию, используя интерфейс. Во время выполнения будет введена реализация, которая соответствует текущей платформе, на которой она запущена.
В этом коде вы увидите страницу, которая может быть в проекте Xamarin Forms. Он создает кнопку, которая вызывает метод Speak()
, используя DependencyService
.
public MainPage ()
{
var speak = new Button {
Text = "Hello, Forms !",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
};
speak.Clicked += (sender, e) => {
DependencyService.Get<ITextToSpeech>().Speak("Hello from Xamarin Forms");
};
Content = speak;
}
Результатом будет то, что при запуске приложения и нажатии кнопки будет передан текст.
Все это без необходимости делать такие вещи, как подсказки компилятора и т. Д. Теперь у вас есть единый способ доступа к функциональности платформы с помощью независимого от платформы кода.
Получение номеров приложений и устройств OS - Android и iOS - PCL
В приведенном ниже примере будет собрано номер версии операционной системы устройства и версия приложения (которая определена в свойствах каждого проекта), которая вводится в имя версии на Android и версию iOS.
Сначала создайте интерфейс в своем проекте PCL:
public interface INativeHelper {
/// <summary>
/// On iOS, gets the <c>CFBundleVersion</c> number and on Android, gets the <c>PackageInfo</c>'s <c>VersionName</c>, both of which are specified in their respective project properties.
/// </summary>
/// <returns><c>string</c>, containing the build number.</returns>
string GetAppVersion();
/// <summary>
/// On iOS, gets the <c>UIDevice.CurrentDevice.SystemVersion</c> number and on Android, gets the <c>Build.VERSION.Release</c>.
/// </summary>
/// <returns><c>string</c>, containing the OS version number.</returns>
string GetOsVersion();
}
Теперь мы реализуем интерфейс в проектах Android и iOS.
Android:
[assembly: Dependency(typeof(NativeHelper_Android))]
namespace YourNamespace.Droid{
public class NativeHelper_Android : INativeHelper {
/// <summary>
/// See interface summary.
/// </summary>
public string GetAppVersion() {
Context context = Forms.Context;
return context.PackageManager.GetPackageInfo(context.PackageName, 0).VersionName;
}
/// <summary>
/// See interface summary.
/// </summary>
public string GetOsVersion() { return Build.VERSION.Release; }
}
}
IOS:
[assembly: Dependency(typeof(NativeHelper_iOS))]
namespace YourNamespace.iOS {
public class NativeHelper_iOS : INativeHelper {
/// <summary>
/// See interface summary.
/// </summary>
public string GetAppVersion() { return Foundation.NSBundle.MainBundle.InfoDictionary[new Foundation.NSString("CFBundleVersion")].ToString(); }
/// <summary>
/// See interface summary.
/// </summary>
public string GetOsVersion() { return UIDevice.CurrentDevice.SystemVersion; }
}
}
Теперь использовать код в методе:
public string GetOsAndAppVersion {
INativeHelper helper = DependencyService.Get<INativeHelper>();
if(helper != null) {
string osVersion = helper.GetOsVersion();
string appVersion = helper.GetBuildNumber()
}
}