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.

Schematische Übersicht (Bild von Xamarin)

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()
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow