31

一部の音声をリッスンするサービスがあります。音声が文字列と一致する場合、特定のメソッドがサービス オブジェクトで呼び出されます。

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

このサービス メソッドから、アクティビティ オブジェクトにあるメソッドを呼び出すにはどうすればよいですか? アクティビティからサービスへのアクセスではなく、サービスからアクティビティへのアクセスが必要です。ハンドラーとブロードキャスターについては既に読みましたが、例を見つけたり理解したりできませんでした。何か案は?

4

4 に答える 4

11

Activity に BroadcastReceiver を登録し、サービスから Intent を送信します。このチュートリアルを参照してください: http://www.vogella.com/articles/AndroidBroadcastReceiver/article.html 少し長く見えるかもしれませんが、とにかくそれらの使用方法を学びたいと思うでしょう ;)

于 2013-02-15T14:24:00.500 に答える
2

これを達成するには、さまざまな方法があります。使用するクラスの 1HandlerMessanger。メソッドの考え方は、Handlerオブジェクトを からActivityに渡すことServiceです。Serviceのメソッドを呼び出すたびに、Activityを送信して何らかの方法MessageActivity処理します。

アクティビティ:

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;
    }
}
于 2013-02-15T14:24:41.577 に答える
0

いくつかの調査の後、ブロードキャストを送受信するための私の場合、次のタイミングが見つかりました。私は同じプロセスでサービスを提供しています。

sendBroadcast (両方のコンポーネントが同じプロセスにある場合はお勧めしません) 34 秒

LocalBroadcastManager.getInstance(this).sendBroadcast(意図); 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/Activity のメソッドを呼び出す必要がある場合

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

アプリケーションまたはアクティビティを拡張するクラスで。

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

この方法の呼び出しは、同じプロセスからのブロードキャストと受信からほぼ瞬時に行われます

于 2016-04-29T22:02:45.273 に答える