2013-02-15 31 views
25

Istnieje usługa, która nasłuchuje głosu. Jeśli głos pasuje do ciągu, w obiekcie usługi wywoływana jest pewna metoda.Jak wywołać metodę w działaniu z usługi

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

    //... 
} 

To jak ja uruchomić usługę w mojej działalności:

Intent i = SpeechActivationService.makeStartServiceIntent(this); 
startService(i); 

z tej metody usługi, w jaki sposób można wywołać metodę, która mieszka w obiekcie działalności? Nie chcę dostępu z działania do usługi, ale z usługi do działania. Czytałem już o sprzedawcach i nadawcach, ale nie mogłem znaleźć/zrozumieć żadnego przykładu. Jakieś pomysły?

+0

Czy metoda musi być w klasie aktywny, czy można przenieść go do klasy użytkowej? –

+0

Chcę zaktualizować interfejs użytkownika, więc myślę, że musi być w klasie aktywności –

Odpowiedz

2

Istnieje wiele różnych sposobów, aby achive to. Jeden z nich używa klas Handler i . Ideą tej metody jest przekazanie obiektu Handler z Activity do Service. Za każdym razem, gdy Service chce wywołać pewną metodę z Activity, po prostu wysyła Message i Activity w jakiś sposób.

aktywny:

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

Usługa:

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

Moja usługa rozciąga się od usługi, a nie od IntentService –

+0

Możesz również użyć 'Service'. Ten kod pokazuje tylko ideę. Zaktualizowałem swoją odpowiedź i teraz używa ona 'Service' zamiast' IntentService' –

+0

+1 Dziękuję, już to zrobiłem z odbiornikiem transmisji http://inchoo.net/mobile-development/android-development/broadcast-receiver-from -activity/ –

54

Zakładając swoje usługi i działalność są w tym samym opakowaniu (czyli tej samej aplikacji), można użyć LocalBroadcastManager następująco:

W usłudze:

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

W swojej działalności:

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

Z sekcji 7.3 @ Ascorbin za linkiem: http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html#ownreceiver_localbroadcastmanager

+3

Działa jako urok, TY! –

+1

To jest absolutnie niesamowite, dzięki człowiekowi, którego uratowałeś – Ale

+1

Dzięki Tony! Świetna odpowiedź – Nickmccomb

0

Po niektórych badań znalazłem następujące czasy w moim przypadku do wysyłania i odbierania stacji radiowych. Mam usługi w tym samym procesie.

sendBroadcast (nie zalecane, gdy oba elementy są w tym samym procesie) 34 s

LocalBroadcastManager.getInstance (co).sendBroadcast (zamiar); blisko 30 sek

Implementacja za pomocą AIDL i RemoteCallbackList Będzie pracować dla samego procesu lub innego procesu

w usłudze

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

Kiedy trzeba metody w zastosowaniu/Acitvity z usługą połączeń

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

W twojej klasie pielęgnowanie aplikacji lub działania.

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

Wywołanie tej drogi jest prawie natychmiastowe od nadawanie i odbieranie z tego samego procesu