2013-02-15 69 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); 
} 

調用這個方法是從廣播幾乎是瞬間,並從相同的過程

相關問題