2016-11-12 3 views
-1

Hallo, ich mache Android-Anwendung für Xamarin. Ich habe eine einfache Anwendung im Android Studio erstellt. so jede Antwort willkommen entweder Java oder C# Ich habe einen Service (GPS-Service) und 2 Aktivitäten. MainActivity - GPS-Service sind gut mit der Sendung verbunden. Ich hoffe MainActivity. -> Eine weitere Aktivität in Echtzeit-GPS-Punkt (. Es ist auch in Ordnung, von der GPS-Dienst auf eine andere Tätigkeit zu senden), aber es ist nicht ... App ist tot ..One Service Daten Mehrere Aktivitäten in Android

MainActivity Code

private void RegisterService() 
    { 
     _gpsServiceConnection = new GPSServiceConnection(_binder); 
     _gpsServiceIntent = new Intent(Android.App.Application.Context, typeof(GPS.GPSService)); 
     BindService(_gpsServiceIntent, _gpsServiceConnection, Bind.AutoCreate); 
    } 

    private void RegisterBroadcastReceiver() 
    { 
     IntentFilter filter = new IntentFilter(GPSServiceReciever.LOCATION_UPDATED); 
     filter.AddCategory(Intent.CategoryDefault); 
     _receiver = new GPSServiceReciever(); 
     RegisterReceiver(_receiver, filter); 
    } 

    private void UnRegisterBroadcastReceiver() 
    { 
     UnregisterReceiver(_receiver); 
    } 

    public void UpdateUI(Intent intent) 
    { 
     LatLng_txt.Text = intent.GetStringExtra("Location"); 
     Lat = intent.GetDoubleExtra("Lat", 0.0); 
     Lng = intent.GetDoubleExtra("Lng", 0.0); 
    } 

    protected override void OnResume() 
    { 
     base.OnResume(); 
     RegisterBroadcastReceiver(); 
    } 

    protected override void OnPause() 
    { 
     base.OnPause(); 
     UnRegisterBroadcastReceiver(); 
    } 

    [BroadcastReceiver] 
    internal class GPSServiceReciever : BroadcastReceiver 
    { 
     public static readonly string LOCATION_UPDATED = "LOCATION_UPDATED"; 
     public override void OnReceive(Context context, Intent intent) 
     { 
      if (intent.Action.Equals(LOCATION_UPDATED)) 
      { 
       Instance.UpdateUI(intent); 

      } 
     } 
    } 

GPS Service Code

public void OnLocationChanged(Location location) 
    { 
     try 
     { 
      _currentLocation = location; 

      if (_currentLocation == null) 
      { 
       _location = "Unable to determine your location."; 
      } 
      else 
      { 
       _location = String.Format("{0}, {1}", _currentLocation.Latitude, _currentLocation.Longitude); 

       Geocoder geocoder = new Geocoder(this); 

       IList<Address> addressList = geocoder.GetFromLocation(_currentLocation.Latitude, 
        _currentLocation.Longitude, 10); 

       Address addressCurrent = addressList.FirstOrDefault(); 

       if (addressCurrent != null) 
       { 
        StringBuilder deviceAddress = new StringBuilder(); 

        for (int i = 0; i < addressCurrent.MaxAddressLineIndex; i++) 
        { 
         deviceAddress.Append(addressCurrent.GetAddressLine(i)).AppendLine(","); 
        } 

        _address = deviceAddress.ToString(); 
       } 
       else 
       { 
        _address = "Unable to determine the address."; 
       } 

       IList<Address> source = geocoder.GetFromLocationName(_sourceAddress, 1); 
       Address addressOrigin = source.FirstOrDefault(); 

       var coord1 = new LatLng(addressOrigin.Latitude, addressOrigin.Longitude); 
       var coord2 = new LatLng(addressCurrent.Latitude, addressCurrent.Longitude); 

       var distanceInRadius = Utils.HaversineDistance(coord1, coord2, Utils.DistanceUnit.Miles); 

       _remarks = string.Format("Your are {0} miles away from your original location.", distanceInRadius); 

       Intent intent = new Intent(this, typeof(MainActivity.GPSServiceReciever)); 
       intent.SetAction(MainActivity.GPSServiceReciever.LOCATION_UPDATED); 
       intent.AddCategory(Intent.CategoryDefault); 
       intent.PutExtra("Location", _location); 
       intent.PutExtra("Lat", _currentLocation.Latitude); 
       intent.PutExtra("Lng", _currentLocation.Longitude); 
       SendBroadcast(intent); 

      } 
     } 
     catch 
     { 
      _address = "Unable to determine the address."; 
     } 

    } 

Ist das nicht ein guter Weg, da?

+0

Soweit ich Ihr Problem verstanden habe, möchten Sie Daten von einem 'Activity' zum anderen über' Service' senden. Habe ich recht? –

+0

MainActivity und eine andere Aktivität benötigen GPS-Daten in Echtzeit. also habe ich versucht direkt zu senden und habe auch versucht, zwei intents vom service zu senden, aber es ist gescheitert ... –

Antwort

0

Ich habe Ihr Problem verstanden. Aber wissen Sie nicht mehr über GPS etc.Ich habe das gleiche Problem konfrontiert, als ich Music App erstellt habe. Zwei Aktivitäten waren da und ein Service. Und erfolgreich erhalten Song-Position und Song-Daten aus beiden Aktivitäten in Echtzeit.

Mein MainActivity hat

ServiceConnection sc=null; 
public static PlayerService ps; 

und erhält seinen Wert in onCreate von MainActivity

sc=new ServiceConnection(){ 

     @Override 
     public void onServiceConnected(ComponentName p1, IBinder p2) 
     { 
      PlayerService.Getters getters=(PlayerService.Getters) p2; 
      ps=getters.getService(); 
     } 

     @Override 
     public void onServiceDisconnected(ComponentName p1) 
     { 
      // TODO: Implement this method 
     } 

    }; 

Dann PlayerService.Getters Klasse ist

public class Getters extends Binder 
{ 
    public PlayerService getService() 
    { 
     return PlayerService.this; 
    } 
} 

PlayerService

hat
@Override 
public IBinder onBind(Intent p1) 
{ 
    return new Getters(); 
} 

getService von Getters gibt das Objekt von PlayerService an meine MainActivity. Jetzt kann ich Echtzeitwerte von Servicevariablen und Methoden mit statischen ps von mehreren Aktivitäten erhalten.

+0

um .... ich denke benutze zu beobachter muster. Aber es fehlt das Konzept des Entwurfsmusters und ist nicht anwendbar. –

+0

Ich denke, es ist einfach, mit Diensten aus mehreren Aktivitäten zu kommunizieren. Weil ich das selbe benutzt habe und mich sehr einfach gefühlt habe. –

0

Um Daten oder Informationen von Service zu Activity zu senden, müssen Sie Messenger API verwenden. Mit dieser API können Sie eine Interprozesskommunikation (IPC) erstellen, d. H. Eine Kommunikationsverbindung zwischen zwei oder mehr Prozessen. In Android sind Activity und Service zwei getrennte Prozesse, so dass Sie die IPC-Technik verwenden können, um eine Kommunikationsverbindung zwischen ihnen herzustellen.

In der IPC-Technik gibt es zwei Enden, das Serverende und das Clientende. Die Service fungiert als Server und Activity fungiert als Client.

Hinweis: Der Dienst kann nur mit einem Activity gleichzeitig kommunizieren.

Messenger ermöglicht die Implementierung der message-basierten Kommunikation über Prozesse mit Hilfe von Handlern.

Handler ist ein, mit dem Sie diese Nachrichten senden und verarbeiten können.

Schritte zur Implementierung eines Messenger:

Schritt 1.Der Service implementiert einen Handler, der die Callbacks von der Aktivität empfängt. Schritt 2. Der Handler erstellt dann ein Messenger-Objekt, das im Weiteren einen IBinder erstellt, den der Dienst an die Aktivität zurückgibt.

Schritt 3. Die Aktivität verwendet dann den IBinder, um den Messenger zu instanziieren, mit dem die Aktivität Nachrichten an den Dienst sendet.

Schritt 4. Der Dienst empfängt die Nachrichten im Handler, die im ersten Schritt erstellt wurden.

Lets verstehen jetzt ist es mit einem Beispiel:

erstellen Handler im Service wie folgt aus:

class ServiceHandler extends Handler { 
    @Override 
    public void handleMessage(Message msg) { 
     switch (msg.what) { 
      default: 
       super.handleMessage(msg); 
     } 
    } 
} 

Nun fügen Sie den Messenger-Objekt zusammen mit onBind() -Methode zum Service wie erwähnt in 2. Schritt oben:

final Messenger messenger = new Messenger(new ServiceHandler()); 

@Override 
public IBinder onBind(Intent intent) { 
    return messenger.getBinder(); 
} 

in der Aktion, werden wir eine ServiceConnection schaffen die iBinder aus dem Dienst zu holen, das Messenger-Objekt als mentio zu instanziiert ned in der 3. Stufe oben.

Messenger messenger; 
private ServiceConnection serviceConnection = new ServiceConnection() { 
    public void onServiceConnected(ComponentName className, IBinder iBinder) { 
     messenger = new Messenger(iBinder); 
    } 

    public void onServiceDisconnected(ComponentName className) { 
    } 
}; 

Binden der Dienst an der Aktivität mit Hilfe des ServiceConnection oben erstellt:

bindService(new Intent(this, MessengerService.class), serviceConnection, 
    Context.BIND_AUTO_CREATE); 

Um Nachrichten an den Service von der Aktivität zu senden, verwenden Sie die Methode send() des Objekts Messenger.

Wenn Sie Nachrichten vom Dienst in der Aktivität empfangen möchten, müssen Sie einen Messenger in der Aktivität zusammen mit einem Handler erstellen und den Parameter replyTo des Messenger zum Empfangen von Nachrichten an den entsprechenden Handler verwenden.

Verwandte Themen