2013-02-15 71 views
25

有一种服务可以侦听某些语音。如果语音匹配字符串,则会在服务对象中调用某个方法。如何从服务中调用活动中的方法

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

从这项服务中的方法,我怎么可以调用驻留在活动对象的方法?我不想从活动到服务,而是从服务到活动。我已经阅读过关于处理程序和广播公司的内容,但找不到/理解任何示例。有任何想法吗?

+0

接收请问方法必须是在活动类,或者可以将它移动到一个实用工具类? – 2013-02-15 14:13:46

+0

我想更新用户界面,所以我认为它必须在活动课 – 2013-02-15 14:17:09

回答

2

有许多不同的方式来实现这一目标。其中之一使用HandlerMessanger类。该方法的想法是将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; 
    } 
} 
+0

我的服务从服务扩展而不是IntentService – 2013-02-15 14:34:15

+0

您也可以使用'服务'。这段代码只是显示了这个想法。我更新了我的答案,现在它使用'服务'而不是'IntentService' – 2013-02-15 14:49:34

+0

+1谢谢,我已经用广播接收器管理它http://inchoo.net/mobile-development/android-development/broadcast-receiver-from -activity/ – 2013-02-15 14:53:59

54

假设你的服务和活动都在同一个包(即在同一应用程序),你可以使用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(); 
} 

从@维他命C的链接的第7.3节:http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html#ownreceiver_localbroadcastmanager

+3

它作为一种魅力,TY! – 2015-01-29 14:51:28

+1

这绝对是真棒,谢谢你,你救了我 – Ale 2016-05-13 10:28:47

+1

谢谢托尼!很好的回答 – Nickmccomb 2016-08-09 05:01:30

0

一些研究,我发现在我的情况下定时发送和接收节目播出后。我在同一个过程中有服务。

sendBroadcast(不推荐如果两个部件在相同的工艺) 34秒

LocalBroadcastManager.getInstance(本)。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); 
} 

当你需要调用从服务应用程序/ 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(); 
} 

在你的课上ex管理应用程序或活动。

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

调用这个方法是从广播几乎是瞬间,并从相同的过程

相关问题