2015-05-13 16 views
5

Ich habe eine Anwendung basierend auf XamarinForms.Übergeben Sie Daten von Android Service zu ContentPage in Xamarin Formular basierte Anwendung

Ein Hintergrunddienst, den ich in Android-Projekt erstellt habe und der Dienst möchte Daten an ContentPage (die in PCL ist) senden, die dem Benutzer angezeigt wird.

Wie kann ich Daten an ContentPage übergeben (Von XX.Droid-Projekt zu PCL)?

Eine Lösung ist:

  • Klasse zu erstellen, in PCL mit statischen Variablen, die von xxx.Droid Projekt zugegriffen werden (z var TEMP_VAR.).
  • Aktualisiere den Wert dieser statischen Variable (TEMP_VAR) von der Serviceklasse aus dem xxx.Droid-Projekt.
  • Sie müssen Notifier für diese statische Variable (TEMP_VAR) erstellen.
  • Aktualisieren Sie die Inhaltsseite mithilfe von MessageCenter Mechanism, falls erforderlich.

Wenn es eine bessere Lösung gibt, könnten Sie mir bitte zur Verfügung stellen?

Antwort

5

Dies kann mit dem Konzept von C#

  • Abhängigkeitsdienst
  • Ereignis

Need 4 Klassen für eine solche Implementierung haben, erreicht werden:

  1. Schnittstelle in PCL (zB CurrentLocationService.cs) mit darin definierten Event-Handlern.

namespace NAMESPACE 
 
{ 
 
\t public interface CurrentLocationService 
 
\t { 
 
\t \t void start(); 
 

 
\t \t event EventHandler<PositionEventArgs> positionChanged; 
 
\t } 
 
}

  1. Implementierung der Schnittstelle von PCL in xxx.Droid Projekt (zB CurrentLocationService_Android.cs) unter Verwendung von Abhängigkeitsdienst

class CurrentLocationService_Android : CurrentLocationService 
 
{ 
 

 
\t public static CurrentLocationService_Android mySelf; 
 

 
\t public event EventHandler<PositionEventArgs> positionChanged; 
 
\t 
 
\t 
 
\t public void start() 
 
\t { 
 
\t \t mySelf = this; 
 
\t \t Forms.Context.StartService(new Intent(Forms.Context, typeof(MyService))); 
 

 
\t } 
 

 
\t public void receivedNewPosition(CustomPosition pos) 
 
\t { 
 
\t \t positionChanged(this, new PositionEventArgs(pos)); 
 
\t } 
 

 
}

  1. ContentPage in PCL - das Objekt der Implementierung der Schnittstelle haben wird. Objekt kann durch

public CurrentLocationService LocationService 
 
{ 
 
\t get 
 
\t { 
 
\t \t if(currentLocationService == null) 
 
\t \t { 
 
\t \t \t currentLocationService = DependencyService.Get<CurrentLocationService>(); 
 
\t \t \t currentLocationService.positionChanged += OnPositionChange; 
 
\t \t } 
 
\t \t return currentLocationService; 
 
\t } 
 
    
 

 
} 
 

 
private void OnPositionChange(object sender, PositionEventArgs e) 
 
{ 
 
\t Debug.WriteLine("Got the update in ContentPage from service "); 
 
}

  1. Hintergrund Service in xxx.Droid Projekt gewonnen werden. Dieser Dienst enthält eine Referenz zur Implementierung des Abhängigkeitsdienstes CurrentLocationService.
  2. cs

[Service] 
 
    public class MyService : Service 
 
    { 
 
     public string TAG = "MyService"; 
 
     
 
     public override IBinder OnBind(Intent intent) 
 
     { 
 
      throw new NotImplementedException(); 
 
     } 
 

 
     
 

 
     public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId) 
 
     { 
 
      Log.Debug(TAG, TAG + " started"); 
 

 
      doWork(); 
 

 
      return StartCommandResult.Sticky; 
 
     } 
 

 
     public void doWork() 
 
     { 
 
      var t = new Thread(
 
       () => 
 
       { 
 
        Log.Debug(TAG, "Doing work"); 
 
        Thread.Sleep(10000); 
 
        Log.Debug(TAG, "Work completed"); 
 

 
        if(CurrentLocationService_Android.mySelf != null) 
 
        { 
 
         CustomPosition pos = new CustomPosition(); 
 
         pos.update = "Finally value is updated"; 
 
         CurrentLocationService_Android.mySelf.receivedNewPosition(pos); 
 
         
 
        } 
 

 
        StopSelf(); 
 
       }); 
 
      t.Start(); 
 
     } 
 

 
    }

Hinweis: PositionEventArgs Klasse erstellt werden müssen als je Verwendung von Daten zwischen Service und Content passieren.

Das funktioniert für mich wie Charme.

Hoffe, dass dies für Sie hilfreich wäre.