2012-05-14 12 views
7

Tengo este servicio simple que transmite la ubicación actual del usuario. Quiero usar el mecanismo de enlace solo para controlar el ciclo de vida del servicio, pero el servicio simplemente no está comenzando.Servicio no creado (o conexión) después de bindService()

¿Qué hice mal?

public class GPSActivity extends ListActivity { 
... 
protected void onResume() { 
     super.onResume(); 

     Log.i("Service", "Service bound"); 
     Intent intent = new Intent(this, LocationService.class); 
     bindService(intent, service_connection , Context.BIND_AUTO_CREATE); 
    } 

protected void onPause() { 
     if (dataUpdateReceiver!=null) 
      unregisterReceiver(dataUpdateReceiver); 
     unbindService(service_connection); 
     super.onPause(); 
    } 
class LocationServiceConnection implements ServiceConnection{ 
     public void onServiceConnected(ComponentName name, IBinder service) { 
      Log.i("Service", "Service Connected"); 
     } 
       public void onServiceDisconnected(ComponentName name) { 

     } 
    } 
} 

LocalBinder.java

public class LocalBinder<S> extends Binder { 
    private String TAG = "LocalBinder"; 
    private WeakReference<S> mService; 


    public LocalBinder(S service){ 
     mService = new WeakReference<S>(service); 
    } 


    public S getService() { 
     return mService.get(); 
    } 
} 

LocationService.java

public class LocationService extends Service { 
    public void onCreate() { 
     initLocationListener(); 
     Log.i("Location Service","onCreate()"); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.i("Location Service", "Received start id " + startId + ": " + intent); 
     return START_NOT_STICKY; 
    } 

    private final IBinder mBinder = new LocalBinder<LocationService>(this); 
    @Override 
    public IBinder onBind(Intent intent) { 
     return mBinder; 
    } 
} 

AndroidManifest.xml

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 
    ... 

    <service android:name=".LocationService"> 
    </service> 
</application> 

EDIT: Reparado gracias a la respuesta de NickT.

La entrada de manifiesto no tenía un filtro de intención o el nombre correcto

<service 
    android:enabled="true" 
    android:name="com.android.gps.services.LocationService"> 
    <intent-filter> 
      <action android:name="com.android.gps.services.LocationService" /> 
    </intent-filter> 
</service> 

y la intención que he usado para la unión fue como los que se necesita para utilizar al iniciar una actividad. la correcta es:

Intent intent = new Intent("com.android.gps.services.LocationService"); 
+0

lo que hace su método 'pública IBinder onBind (intención Intención)' 'en LocationService.java' parece? – Jens

+0

@Jens Edité la pregunta para incluir el método onBind(). – bughi

+0

Hm. Y ni siquiera está obteniendo el 'Log.i (" Location Service "," onCreate() ");' inicie sesión en su logcat? – Jens

Respuesta

3

El onStartCommand sólo se ejecutará si el servicio se inicia explícitamente, parece que solo quieres vincularlo, lo cual está bien. Sin embargo, no veo que haya configurado la conexión de servicio correctamente. Estoy publicando mi programa de código auxiliar que muestra cómo enlazar un servicio y llamar a un método en el servicio a través de una carpeta. Es posible que desee ejecutar esto y ver la secuencia de los diversos mensajes de registro. Obviamente tendrá que agregar su BroadcastReceiver y el código onLocationChaged para que sea útil para usted.

La actividad

package com.servtest.test; 

import com.servtest.test.LocationService.LocalBinder; 
import android.app.Activity; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.content.ServiceConnection; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.util.Log; 

public class ServiceTestActivity extends Activity { 

    boolean mServiceConnected = false; 
    boolean mBound = false; 
    private LocationService mLocnServ; 

    ServiceConnection mServconn = new ServiceConnection() { 
     @Override 
     public void onServiceConnected(ComponentName name, IBinder service) { 
      Log.d("SVTEST", "Activity service connected"); 
      LocalBinder binder = (LocalBinder) service; 
      mLocnServ = binder.getService(); 
      // Can't call this methodInTheService UNTIL IT'S BOUND! 
      mLocnServ.methodInTheService(); 
      mBound = true; 
     } 

     @Override 
     public void onServiceDisconnected(ComponentName name) { 
      Log.d("SVTEST", "Activity service disconnected"); 
      mBound = false; 
     } 
    }; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
    } 
    @Override 
    public void onStart() { 
     super.onStart(); 
     Log.d("SVTEST", "Activity onStart"); 
     mServiceConnected = bindService(new Intent(
       "com.servtest.test.LOCATIONSERVICE"), mServconn, 
       Context.BIND_AUTO_CREATE); 
    } 
    @Override 
    protected void onResume() { 
     super.onResume(); 
     Log.d("SVTEST", "Activity onResume"); 
    } 
    @Override 
    public void onPause() { 
     Log.d("SVTEST", "Activity onPause"); 
     super.onPause(); 
    } 
    @Override 
    public void onStop() { 
     Log.d("SVTEST", "Activity onStop"); 
     if (mBound) { 
      unbindService(mServconn); 
      mBound = false; 
     } 
     super.onStop(); 
    } 

} 

El Servicio

package com.servtest.test; 

import android.app.Service; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationListener; 
import android.os.Binder; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.util.Log; 

public class LocationService extends Service implements LocationListener { 

    private final IBinder mBinder = new LocalBinder(); 

    @Override 
    public void onLocationChanged(Location arg0) {} 
    @Override 
    public void onProviderDisabled(String arg0) {} 
    @Override 
    public void onProviderEnabled(String arg0) {} 
    @Override 
    public void onStatusChanged(String arg0, int arg1, Bundle arg2) {} 

    @Override 
    public IBinder onBind(Intent intent) { 
     Log.d("SVTEST", "Loc service ONBIND"); 
     return mBinder; 
    } 
    @Override 
    public boolean onUnbind(Intent intent) { 
     Log.d("SVTEST", "Loc service ONUNBIND"); 
     return super.onUnbind(intent); 
    } 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     // Won't run unless it's EXPLICITLY STARTED 
     Log.d("SVTEST", "Loc service ONSTARTCOMMAND"); 
     return super.onStartCommand(intent, flags, startId); 
    } 
    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.d("SVTEST", "Loc service ONDESTROY"); 
    } 

    public class LocalBinder extends Binder { 
     LocationService getService() { 
      // Return this instance of LocalService so clients can call public methods 
      return LocationService.this; 
     } 
    } 

    public void methodInTheService() { 
     // A method you can call in the service 
     Log.d("SVTEST", "Loc service EXECUTING THE METHOD"); 
    } 
} 

El Manifiesto

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.servtest.test" 
    android:versionCode="1" 
    android:versionName="1.0" > 
    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:name=".ServiceTestActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <service 
      android:enabled="true" 
      android:name="LocationService"> 
      <intent-filter> 
       <action android:name="com.servtest.test.LOCATIONSERVICE" /> 
      </intent-filter> 
     </service> 
    </application> 
</manifest> 

Esperanza esto ayuda

+0

Gracias edité mi respuesta con lo que hice mal – bughi

0

tuve mi Activity aplicar ServiceConnection y encuadernado como esto:

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

Entonces manejan las devoluciones de llamada para onServiceConnected() y onServiceDisconnected() en mi Activity

+0

Eso no hace ninguna diferencia. – bughi

0

Cuando se llama a bindService puede obtener XX es de error:

ActivityManager java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.android.server.am.ActivityRecord$Token

comprobar la salida de Logcat.

Este es un error de Android.

Para solucionarlo, utilice getApplicationContext().bindService(...)

Cuestiones relacionadas