2012-03-31 22 views
17

Estoy unión al servicio de esta manera: ClaseAndroid: parámetro pase a servicio desde Actividad

Actividad:

ListenLocationService mService; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
     ... 
     Intent intent = new Intent(this, ListenLocationService.class); 
     intent.putExtra("From", "Main"); 
     bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
     ... 
} 

private ServiceConnection mConnection = new ServiceConnection() { 

     public void onServiceConnected(ComponentName className, 
       IBinder service) { 
      LocalBinder binder = (LocalBinder) service; 
      mService = binder.getService();   
     } 

     public void onServiceDisconnected(ComponentName arg0) { 
     } 
    }; 

onBind Este es el método de mi Servicio:

@Override 
public IBinder onBind(Intent intent) { 
    Bundle extras = intent.getExtras(); 
    if(extras == null) 
     Log.d("Service","null"); 
    else 
    { 
     Log.d("Service","not null"); 
     String from = (String) extras.get("From"); 
     if(from.equalsIgnoreCase("Main")) 
      StartListenLocation(); 
    } 
    return mBinder; 
} 

Tengo "nulo" en LogCat - el paquete es nulo en s La pena de que hice intent.putExtra antes de bindService

En general, el servicio funciona bien. Sin embargo, necesito llamar al StartListenLocation(); solo desde la actividad principal de la aplicación (decido hacer esto enviando un indicador).

¿Cómo puedo enviar datos al servicio? ¿O tal vez haya otra forma de verificar qué actividad inició onBind?

Respuesta

8

1 Crear una interfaz que declare toda firma del método que desea llamar de una actividad:

public interface ILocationService { 
    public void StartListenLocation(Location location); 
} 

2 Haga su ligante implementa ILocaionService y definir el cuerpo del método real:

public class MyBinder extends Binder implements ILocationService { 
    ... ... 

    public void StartListenLocation(Location location) { 
    // implement your method properly 
    } 

    ... ... 
} 

3 En la actividad que se une al servicio, consulte su carpeta por la interfaz:

... ... 

ILocationService mService; // communication is handled via Binder not the actual service class. 

private ServiceConnection mConnection = new ServiceConnection() { 

    public void onServiceConnected(ComponentName className, IBinder service) { 
    mService = (ILocationService) service;  
    } 

    ... ... 
}; 

... ... 

// At some point if you need call service method with parameter: 
Location location = new Location(); 
mService.StartListenLocation(location); 

Todas las comunicaciones (es decir método de llamada a su Servicio) debe manejarse y ejecutarse a través de la clase de enlace inicializar y devolver en ServiceConnection.onServiceConnected(), no la clase de servicio real (binder.getService() es innecesario). Así es como la comunicación del servicio de enlace está diseñada para funcionar en la API.

Tenga en cuenta que bindService() es una llamada asincrónica. Habrá un retraso después de llamar a bindService() y antes de que el sistema active la devolución de llamada ServiceConnection.onServiceConnected(). Entonces, el mejor lugar para realizar el método de servicio es inmediatamente después de que mService se inicialice en el método ServiceConnection.onServiceConnected().

Espero que esto ayude.

+0

Gracias por la respuesta . Me enfrenté a otro problema más adelante, tal vez usted sepa cómo resolverlo: http://stackoverflow.com/questions/9956601/android-set-and-get-services-variable-in-different-activities –

+0

@yorkw "Así es como vincular la comunicación de servicios diseñada para funcionar en la API "- no es que dude que usted tenga razón, pero ¿tiene un enlace a algunos documentos oficiales de Android donde puedo leer más sobre esto? – DuneCat

+2

@DuneCat, acepté que la declaración no es del todo exacta, en realidad se hace referencia a una de las recomendaciones que Google sugirió para implementar un servicio enlazado, consulte [aquí] (http://developer.android.com/guide/components/bound -services.html # Binder) para más detalles. – yorkw

0

De acuerdo con esta sesión http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html

Una forma de enviar datos a un servicio es mediante el uso de una base de datos que contiene de columnas PID (Identificador de proceso), datos de estado en el que el estado se puede leer, LISTO, Encuadernación y y así sucesivamente, cuando el servicio se carga, lee la tabla que se llena con la actividad de llamada y se puede eliminar cuando finaliza, a la inversa se indica AIDL como se indicó en la respuesta anterior, elija según su aplicación.

26

Puede pasar el parámetro de esta manera sencilla: -

Intent serviceIntent = new Intent(this,ListenLocationService.class); 
    serviceIntent.putExtra("From", "Main"); 
    startService(serviceIntent); 

y obtener el parámetro en el método onStart de su clase de servicio

@Override 
public void onStart(Intent intent, int startId) { 
    super.onStart(intent, startId); 
    Bundle extras = intent.getExtras(); 
if(extras == null) 
    Log.d("Service","null"); 
else 
{ 
    Log.d("Service","not null"); 
    String from = (String) extras.get("From"); 
    if(from.equalsIgnoreCase("Main")) 
     StartListenLocation(); 
} 

} 

Enjoy :)

+2

Esta es la manera de pasar parámetros al método onBind, según lo solicitado. @yorkw tiene una buena solución general para llamar a la Actividad del Servicio. –

Cuestiones relacionadas