音声を聞くサービスがあります。音声が文字列に一致する場合、特定のメソッドがサービスオブジェクトで呼び出されます。
public class SpeechActivationService extends Service {
public static Intent makeStartServiceIntent(Context pContext){
return new Intent(pContext, SpeechActivationService.class);
}
//...
public void onMatch(){
Log.d(TAG, "voice matches Word");
}
//...
}
これは私のアクティビティでサービスを開始する方法です:
Intent i = SpeechActivationService.makeStartServiceIntent(this);
startService(i);
このサービスメソッドから、アクティビティオブジェクトにあるメソッドをどのように呼び出すことができますか?アクティビティからサービスへのアクセスが必要ではなく、サービスからアクティビティへのアクセスが必要です。ハンドラーとブロードキャスターについてはすでに読みましたが、例を見つけることができませんでした。何か案は?
BroadcastReceiverをアクティビティに登録し、サービスからインテントを送信します。このチュートリアルを参照してください: http://www.vogella.com/articles/AndroidBroadcastReceiver/article.html 少し長く見えるかもしれませんが、とにかくそれらを使用する方法を学ぶために;)
サービスとアクティビティが同じパッケージ(つまり、同じアプリ)にあると仮定すると、次のようにLocalBroadcastManagerを使用できます。
あなたのサービスで:
// Send an Intent with an action named "my-event".
private void sendMessage() {
Intent intent = new Intent("my-event");
// add data
intent.putExtra("message", "data");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
あなたの活動:
@Override
public void onResume() {
super.onResume();
// Register mMessageReceiver to receive messages.
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("my-event"));
}
// handler for received Intents for the "my-event" event
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Extract data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
@Override
protected void onPause() {
// Unregister since the activity is not visible
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}
@Ascorbinのリンクのセクション7.3から: http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html#ownreceiver_localbroadcastmanager
これを実現するには、さまざまな方法があります。それらの1つはHandler
およびMessanger
クラスを使用します。メソッドの考え方は、Handler
からActivity
オブジェクトをService
に渡すことです。 Service
がActivity
のメソッドを呼び出すたびに、Message
を送信し、Activity
がそれを何らかの方法で処理します。
アクティビティ:
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
showToast(msg.what);
}
};
final Intent intent = new Intent(this, MyService.class);
final Messenger messenger = new Messenger(handler);
intent.putExtra("messenger", messenger);
startService(intent);
}
private void showToast(int messageId) {
Toast.makeText(this, "Message " + messageId, Toast.LENGTH_SHORT).show();
}
}
サービス:
public class MyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
final Messenger messenger = (Messenger) intent.getParcelableExtra("messenger");
final Message message = Message.obtain(null, 1234);
try {
messenger.send(message);
} catch (RemoteException exception) {
exception.printStackTrace();
}
}
return START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
いくつかの調査の後、私は放送を送受信するための私のケースで次のタイミングを見つけました。同じプロセスでサービスを提供しています。
sendBroadcast(両方のコンポーネントが同じプロセスにある場合は推奨されません)34秒
LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 30秒近く
AIDLとRemoteCallbackListを使用した実装同じプロセスまたは異なるプロセスで動作します
あなたのサービスで
public final RemoteCallbackList<ICallBackAidl> mDMCallbacks = new RemoteCallbackList<ICallBackAidl>();
public void registerDMCallback(ICallBackAidl cb) {
Logger.d(LOG_TAG, "registerDMCallback " + cb);
if (cb != null)
mDMCallbacks.register(cb);
}
Application/Acitvityのサービスからメソッドを呼び出す必要がある場合
public void callMehodsInApplication() {
final int N = mDMCallbacks.beginBroadcast();
for (int i = 0; i < N; i++) {
try {
mDMCallbacks.getBroadcastItem(i).method1();
} catch (RemoteException e) {
e.printStackTrace();
}
}
mDMCallbacks.finishBroadcast();
}
クラスでApplicationまたはActivityを拡張します。
private ISyncmlServiceDMCallback mCallback = new ISyncmlServiceDMCallback.Stub() {
// Implement callback methods here
public void method1() {
// Service can call this method
}
}
public void onServiceConnected(ComponentName name, IBinder service) {
svc.LocalBinder binder = (svc.LocalBinder) service;
mSvc = binder.getService();
mSvc.registerDMCallback(mCallback);
}
この方法での呼び出しは、同じプロセスからのブロードキャストと受信からほぼ瞬時に行われます