Xamarin.Forms
Zugriff auf native Funktionen mit DependencyService
Suche…
Bemerkungen
Wenn der Code nicht beschädigt werden soll, wenn keine Implementierung gefunden wird, überprüfen Sie zuerst den DependencyService
ob eine Implementierung verfügbar ist.
Sie können dies durch eine einfache Überprüfung tun, wenn es nicht null
.
var speaker = DependencyService.Get<ITextToSpeech>();
if (speaker != null)
{
speaker.Speak("Ready for action!");
}
oder, wenn Ihre IDE C # 6 unterstützt, mit einem nullbedingten Operator:
var speaker = DependencyService.Get<ITextToSpeech>();
speaker?.Speak("Ready for action!");
Wenn Sie dies nicht tun und zur Laufzeit keine Implementierung gefunden wird, generiert Ihr Code eine Ausnahme.
Implementierung von Text-zu-Sprache
Ein gutes Beispiel für eine Funktion, die plattformspezifischen Code anfordert, ist die Implementierung von Text-to-Speech (tts). In diesem Beispiel wird davon ausgegangen, dass Sie mit gemeinsamem Code in einer PCL-Bibliothek arbeiten.
Eine schematische Übersicht unserer Lösung würde wie das Bild darunter aussehen.
In unserem Shared Code definieren wir eine Schnittstelle, die beim DependencyService
registriert ist. Hier werden wir unsere Forderungen erledigen. Definieren Sie eine Schnittstelle wie darunter.
public interface ITextToSpeech
{
void Speak (string text);
}
Jetzt müssen wir in jeder spezifischen Plattform eine Implementierung dieser Schnittstelle erstellen. Beginnen wir mit der iOS-Implementierung.
iOS-Implementierung
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);
}
}
Im obigen Codebeispiel stellen Sie fest, dass für iOS spezifischer Code vorhanden ist. AVSpeechSynthesizer
Typen wie AVSpeechSynthesizer
. Diese funktionieren nicht im gemeinsam genutzten Code.
Um diese Implementierung beim Xamarin DependencyService
zu registrieren, fügen Sie dieses Attribut oberhalb der Namespace-Deklaration ein.
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
Wenn Sie nun in Ihrem gemeinsam genutzten Code einen solchen Aufruf durchführen, wird die richtige Implementierung für die Plattform, auf der Sie Ihre App ausführen, eingefügt.
DependencyService.Get<ITextToSpeech>()
. Mehr dazu später.
Android-Implementierung
Die Android-Implementierung dieses Codes würde darunter aussehen.
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
}
Vergessen Sie auch nicht, es beim DependencyService
zu registrieren.
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-Implementierung
Schließlich kann dieser Code für Windows Phone verwendet werden.
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);
}
}
Und vergessen Sie nicht noch einmal, es zu registrieren.
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
Implementierung in Shared Code
Jetzt ist alles vorhanden, damit es funktioniert! Schließlich können Sie diese Funktion in Ihrem Shared Code jetzt über die Schnittstelle aufrufen. Zur Laufzeit wird die Implementierung eingefügt, die der aktuellen Plattform entspricht, auf der sie ausgeführt wird.
In diesem Code sehen Sie eine Seite, die sich in einem Xamarin Forms-Projekt befinden könnte. Es erstellt eine Schaltfläche, die die Speak()
-Methode mithilfe des DependencyService
aufruft.
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;
}
Das Ergebnis ist, dass beim Ausführen der App und Klicken der Schaltfläche der bereitgestellte Text gesprochen wird.
All dies ohne harte Dinge wie Compiler-Tipps und ähnliches zu tun. Sie haben jetzt eine einheitliche Möglichkeit, auf plattformspezifische Funktionen durch plattformunabhängigen Code zuzugreifen.
Versionsnummern von Anwendungs- und Geräte-Betriebssystemen erhalten - Android & iOS - PCL
Im folgenden Beispiel werden die Betriebssystemversionsnummer des Geräts und die Version der Anwendung (die in den Eigenschaften der einzelnen Projekte definiert ist) erfasst, die unter Android unter Version und unter iOS unter Version eingegeben wird.
Erstellen Sie zunächst eine Schnittstelle in Ihrem PCL-Projekt:
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();
}
Jetzt implementieren wir die Schnittstelle in Android- und iOS-Projekten.
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; }
}
}
Nun, um den Code in einer Methode zu verwenden:
public string GetOsAndAppVersion {
INativeHelper helper = DependencyService.Get<INativeHelper>();
if(helper != null) {
string osVersion = helper.GetOsVersion();
string appVersion = helper.GetBuildNumber()
}
}