2012-05-14 8 views
7

私はこの単純なサービスを利用して、ユーザーの現在地をブロードキャストしています。サービスのライフサイクルを制御するためだけのバインディングメカニズムを使用したいが、サービスはまだ開始していない。bindService()の後にサービスが作成されていない(または接続されていません)

どうしたのですか?

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: NickTの答えを修正しました。

マニフェストエントリはインテントフィルタまたは正しい名前

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

そして、私は活動を開始するときに使用する必要があるもののようなものだった結合するために使用意図を持っていませんでした。正しいものは次のとおりです。

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

を使用するどのようなあなたの '公共IBinder [OnBind]の(テントの意図)LocationService.java''で 'メソッドは次のように見えますか? – Jens

+0

@Jens私はonBind()メソッドを含めるように質問を編集しました。 – bughi

+0

Hm。そして、あなたは 'Log.i(" Location Service "、" onCreate() ");'あなたのlogcatにログインしていませんか? – Jens

答えて

3

onStartCommandにonServiceConnected()onServiceDisconnected()のためのコールバックを取り扱いますサービスが明示的に起動されている場合、サービスをバインドしたいだけのようですが、これは問題ありません。私はあなたがサービス接続を適切に設定しているのを見ません。私はサービスにバインドし、バインダーを通してサービス内のメソッドを呼び出す方法を示すスタブプログラムを投稿しています。これを実行して、さまざまなログメッセージの順序を確認することができます。ブロードキャストレシーバとonLocationChagedコードを追加する必要があります。

活動

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(); 
    } 

} 

サービス

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

マニフェスト

<?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> 

希望あなたが目を得ることがbindService呼び出すと、これは

+0

ありがとう私は私が間違っていたと私の答えを編集 – bughi

0

私が持っていた私のActivityServiceConnectionを実装し、次のようにバインドさ:

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

はその後にのみ実行されます私の Activity

+0

違いはありません。 – bughi

0

を支援エラーは次のとおりです。

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

はlogcatの出力を確認してください。

これはAndroidのバグです。それを解決するために

は、getApplicationContext().bindService(...)