2012-11-28 15 views
7

Więc mam proste pytanie, jest możliwe, aby obsłużyć metodę onActivityResult() w usłudze, jeśli to działanie zostało uruchomione z tej samej usługi (przy użyciu intencji)?Handle onActivityResult on a Service

w moim przypadku, chcę zacząć SpeechRegnition, mówić, i uzyskać wynik w Serwisie, wszystko na tle (główne usługi zaczynają się od widżetu),

Dzięki.

+0

nie mam wypróbowany i nigdy nie próbowałem użyj onAtcivityResult w klasie Non-Activity jeszcze teraz ... – user1839514

Odpowiedz

6

Dzięki za niedawne zaniedbanie, ktokolwiek to był. Poprzednia odpowiedź, którą dałem w 2012 roku, jest całkowitym nonsem, więc postanowiłem napisać właściwą.

Nie można obsłużyć wyniku działania w usłudze, ale można przekazać dowolne dane pobrane z usługi onActivityResult() do usługi.

Jeżeli obsługa jest już uruchomiony, można zadzwonić StartService() z obsługi zdarzenia nowego intencyjny, tak jak

@Override 
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (requestCode == CODE && resultCode == RESULT_OK) { 
     notifyService(data); 
    } 
} 

private void notifyService(final Intent data) { 
    final Intent intent = new Intent(this, MyService.class); 
    intent.setAction(MyService.ACTION_HANDLE_DATA); 
    intent.putExtra(MyService.EXTRA_DATA, data); 
    startService(intent); 
} 

i obsługiwać działania w Serwisie. Jeśli jest już uruchomiony nie zostanie ponownie uruchomiony, w przeciwnym razie zostanie uruchomiona

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    if (intent != null) { 
     final String action = intent.getAction(); 
     if (action != null) { 
      switch (action) { 
       case ACTION_HANDLE_DATA: 
        handleData(intent.getParcelableExtra(EXTRA_DATA)); 
        // Implement your handleData method. Remember not to confuse Intents, or even better make your own Parcelable 
        break; 
      } 
     } 
    } 
    return START_NOT_STICKY; 
} 
+0

Nie musisz tego pokazywać. Wystarczy raz wykonać instancję. Twoja aplikacja została uruchomiona przy użyciu jakiejś czynności. Zastąp metodę wywołania zwrotnego. Utwórz statyczny odnośnik, aby uzyskać dostęp z Usługi, a następnie rozpocznij żądaną aktywność od tego odniesienia w usłudze, a wynik uzyska się w czynności przywoływanej. Po tym, co możesz nazwać statyczną metodą w usłudze lub wysłać transmisję lub cokolwiek innego, aby dostarczyć wynik do usługi. Ale nie pamiętam, czy zostaniesz ponownie dostarczony do działania po zakończeniu czynności związanych z mową. –

+0

Zaktualizowano odpowiedź. –

+1

To bardzo zła praktyka. Przechowywanie działania w polu statycznym powoduje wyciek aktywności, o ile nie zostanie jawnie ustawiony na wartość null. Nawet jeśli JESTEŚ ostrożny, to nadal jest brzydki. Istnieje wiele sposobów radzenia sobie z tym – dnkoutso

1

Nie ma czegoś takiego jak OnActivityForResult w zakresie Service.

Możesz przeczytać wskazówki dla programistów Androida: here.

+1

OK, dlatego zapytałem, jak mogę to zrobić, thx. – user1839514

0

Niedawno natknęliśmy się na tym samym numerze, jak drut onActivityResult() wynik do serwisu dla działalności rozpoczął się od wspomnianej usługi. Nie chciałem przechowywać działania w zmiennej statycznej, biorąc pod uwagę, że wyciek aktywności jest złą praktyką. Dodałem więc statycznego detektora w działaniu Activity onActivityResult(), który implementuje odpowiedni interfejs i tworzy instancję tego detektora jako prywatnego członka klasy Service.

Kod w formie uproszczonej wygląda następująco:

public class MyActivity extends FragmentActivity { 

    public Interface ResultListener { 
     onPositiveResult(); 
     onNegativeResult(); 
    } 

    private static ResultListener mResultListener; 

    public static setListener(ResultListener resultListener) { 
     mResultListener = resultListener; 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (resultCode == Activity.RESULT_OK && mResultListener != null) { 
      mResultListener.onPositiveResult(); 
     } else if (resultCode == Activity.RESULT_CANCELED && mResultListener != null) { 
      mResultListener.onNegativeResult(); 
     } 
     mResultListener = null; 
    } 
} 

public class MyService { 

    private MyActivity.ResultListener mListener = new MyActivity.ResultListener() { 
     onPositiveResult() { 
      // do something on RESULT_OK 
     } 
     onNegativeResult() { 
      // do something on RESULT_CANCELED 
     } 
    } 

    private void startActivityForResultFromHere() { 
     MyActivity.setListener(mListener); 
     Intent intent = new Intent(); 
     intent.setClass(this, MyActivity.class); 
     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     startActivity(intent); 
    } 
} 

Jak widać nie mogłem uniknąć odniesień statycznych ze względu na kwestie obrotu urządzenie, ale myślę, że to rozwiązanie jest bardziej odpowiednie; choć gadatliwy.

0

Otwarte Przejrzyste działanie z usługi i użytkowania BroadcastReceiver w serwisie. Wykonaj szczegółowe instrukcje.

1. Otwarte aktywność przezroczysty z Serwisu

Intent i = new Intent(mContext, FloatingServiceSupportActivity.class); 
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
i.putExtra("action", "SpeechRegnition"); 
mContext.startActivity(i); 

// Dla przejrzystego stosowania Działalność Ten kod w AndroidManifest.xml

<activity 
android:name=".FloatingServiceSupportActivity" 
android:theme="@style/Theme.Transparent" /> 

2. Tworzenie BroadcastReceiver w służbie

BroadcastReceiver brOnActivityResult = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     // TODO: 
    } 
}; 

3. Zarejestruj tę transmisję w usłudzeUtwórz usługę

IntentFilter brintent = new IntentFilter(); 
brintent.addAction("brActionFloatingServiceOnActivityResult"); 
mContext.registerReceiver(brOnActivityResult, brintent); 

4. Wyrejestruj Ta transmisja w onDestroy Służby

mContext.unregisterReceiver(brOnActivityResult); 

5. działają aktywności za pomocą startActivityForResult i Wyślij transmisję z działalności za (FloatingServiceSupportActivity) onActivityResult

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
super.onActivityResult(requestCode, resultCode, data); 

Intent i = new Intent(); 
i.setAction("brActionFloatingServiceOnActivityResult"); 
i.putExtra("action", "initTextToSpeech"); 
mActivity.sendBroadcast(i); 

mActivity.finish(); 
}