web-dev-qa-db-ja.com

Android:ActivityからServiceにパラメーターを渡す

私はこの方法でサービスにバインドしています:

アクティビティクラス:

_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) {
        }
    };
_

これは私のServiceonBindメソッドです:

_@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;
}
_

したがって、LogCatの前に_intent.putExtra_を作成したにもかかわらず、bindServiceに「null」が含まれている-バンドルがnullである

一般的にサービスは正常に動作します。ただし、アプリケーションのメインアクティビティからのみStartListenLocation();を呼び出す必要があります(フラグを送信してこれを行うことにしました)。

サービスにデータを送信するにはどうすればよいですか、またはonBindを起動したアクティビティを確認する別の方法がありますか?

20
Ilya Blokh

1アクティビティから呼び出すすべてのメソッドシグネチャを宣言するインターフェイスを作成します。

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

2バインダーにILocaionServiceを実装させ、実際のメソッド本体を定義します。

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

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

  ... ...
}

3サービスにバインドするアクティビティで、インターフェイスでバインダーを参照します。

... ...

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

すべての通信(つまり、サービスへのメソッド呼び出し)は、実際のサービスクラス(binder.getService()は不要)ではなく、ServiceConnection.onServiceConnected()でバインダークラスの初期化と戻りを介して処理および実行する必要があります。これは、APIで機能するように設計されたバインドサービス通信です。

BindService()は非同期呼び出しであることに注意してください。 bindService()を呼び出した後、ServiceConnection.onServiceConnected()コールバックがシステムに関与する前に、遅延が発生します。したがって、サービスメソッドを実行するのに最適な場所は、mServiceがServiceConnection.onServiceConnected()メソッドで初期化された直後です。

お役に立てれば。

9
yorkw

この簡単な方法でパラメータを渡すことができます:-

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

サービスクラスのonStartメソッドでパラメータを取得します

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

}

楽しい :)

32
Deepak Sharma

このセッションによると http://www.google.com/events/io/2010/sessions/developing-RESTful-Android-apps.html

データをサービスに送信する1つの方法は、pid(プロセスID)、データ、ステータスの列を含むデータベースを使用することです。ステータスは、READ、READY、BINDINGなどであり、サービスがロードされると、次のテーブルを読み取ります。呼び出しアクティビティで埋められ、終了時に削除できます。示されている他の方法は、前の回答で示されているAIDLです。アプリケーションに応じて選択してください。

0
user1304907