2016-11-12 60 views
-1

您好我为Xamarin制作Android应用程序。我在Android工作室中创建了一个简单的应用程序。所以任何答案欢迎Java或C# 我有一项服务(GPS服务)和2个活动。主动式 - GPS服务与广播连接良好。我希望MainActivity - >另一项活动的实时GPS点(它也还可以从GPS服务发送到另一个活动),但它是失败的...程序是死了..一个服务数据在Android中的多个活动

MainActivity代码

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服务代码

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."; 
     } 

    } 

是不是有什么好办法吗?

+0

至于我明白你的问题,你想通过'Service'从一个'Activity'发送数据到另一个。我对吗? –

+0

MainActivity和其他活动都需要实时GPS点数据。所以我试图直接发送,也尝试从服务发送两个意图,但它失败了...... –

回答

0

我明白你的问题,但不知道更多关于GPS等。我在创建音乐应用时遇到了同样的问题。 有两项活动在那里和一项服务,并成功获得了来自两项活动的实时歌曲位置和歌曲数据。

我的MainActivity有

ServiceConnection sc=null; 
public static PlayerService ps; 

而在得到的onCreate的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 
     } 

    }; 

然后PlayerService.Getters类是

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

PlayerService有

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

getters getters将PlayerService的对象赋予给我的MainActivity。 现在我可以使用来自多个活动的静态ps获得服务变量和方法的实时值。

+0

恩....我认为使用观察员模式。但它缺乏设计模式的概念,不适用。 –

+0

我认为很容易与来自多个活动的服务进行交流。因为我用过相同的东西,感觉很简单。 –

0

为了将Service的数据或信息发送到Activity,您需要使用Messenger API。该API将允许您创建进程间通信(IPC),即两个或更多进程之间的通信链接。在Android中,ActivityService是两个独立的进程,因此您可以使用IPC技术在它们之间建立通信链接。

在IPC技术中,有两端,服务器端和客户端。 Service充当服务器,Activity充当客户端。

注意:服务一次只能与一个Activity进行通信。

Messenger允许在处理程序的帮助下在进程间实现基于消息的通信。

Handler是一个允许您发送和处理这些消息。

实现Messenger的步骤:

第1步。服务实现从活动

步骤2.处理程序然后创建其进一步上创建一个IBinder该服务返回到活性的信使对象接收回调处理程序。

步骤3.活动然后使用的IBinder实例信使,其活动用来将消息发送到服务。

步骤4.服务接收在第一步骤中创建的处理程序中的消息。

现在,让我们用一个例子理解:

创建在服务处理程序是这样的:

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

现在,连同onBind()方法将服务添加信使对象中提到上述第二步骤:

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

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

在活动,我们将创建一个ServiceConnection从服务获取的IBinder实例信使对象作为mentio在上面的第三步中完成。

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

    public void onServiceDisconnected(ComponentName className) { 
    } 
}; 

绑定由上面创建的ServiceConnection的帮助服务的活动:

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

要从活动消息发送到服务,使用send信使对象的()方法。

如果您想在活动中接收来自服务的消息,您需要在活动中创建一个Messenger以及一个处理程序,并使用Messenger的replyTo参数接收消息给相应的处理程序。