2012-11-28 12 views
7

Quindi ho una semplice domanda, è possibile gestire il metodo onActivityResult() in un servizio se questa attività è stata avviata dallo stesso servizio (Utilizzo di intent)?Handle onActivityResult su un servizio

Nel mio caso, voglio iniziare SpeechRegnition, Parla, e ottenere il risultato sul servizio, tutto su sfondo (Main Servizio ai proprietari inizio da un widget),

Grazie.

+0

i no ho provato e non ho mai provato a usa onAtcivityResult in una classe Non-Activity ancora adesso ... – user1839514

risposta

6

Grazie per un recente downvoting, chiunque fosse. La risposta precedente che ho restituito nel 2012 è un totale nonsesnse, quindi ho deciso di scriverne uno corretto.

Non è possibile gestire il risultato dell'attività in un servizio, ma è possibile passare qualsiasi dato recuperato da onActivityResult() a un servizio.

Se il servizio è già in esecuzione, è possibile chiamare StartService() con una nuova gestione dell'evento Intent, in questo modo

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

E gestire l'azione in un servizio. Se è già in esecuzione, non sarà riavviato, altrimenti verrà avviato

@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

Non è necessario mostrarlo. Deve solo essere istanziato una volta. L'applicazione è stata avviata da alcune attività. Sostituisci il metodo di callback là fuori. Stabilire un riferimento statico all'accesso da un servizio, quindi avviare l'attività desiderata da quel riferimento in servizio e si otterrà il risultato in attività di riferimento. Dopo ciò che è possibile chiamare un metodo statico in servizio o inviare una trasmissione o qualsiasi altra cosa per fornire il risultato al servizio. Ma non ricordo se sarai riconsegnato a un'attività dopo che l'attività vocale è terminata o meno. –

+0

Aggiornamento della risposta. –

+1

questa è una pessima pratica. La memorizzazione di un'attività in un campo statico causa la perdita di attività a meno che non si imposti esplicitamente su null. Anche se STAI attento che è ancora brutto da fare. Ci sono molti modi per gestire questo – dnkoutso

1

Non esiste una cosa come OnActivityForResult nell'ambito di uno Service.

È possibile leggere le linee guida per gli sviluppatori Android here.

+1

ok ecco perchè ho chiesto come posso farlo, grazie. – user1839514

0

ho recentemente incappato lo stesso problema, come cablare onActivityResult() esito ad un Servizio per un'attività iniziata dal servizio di cui sopra. Non volevo archiviare l'attività in una variabile statica dato che la perdita di attività è una cattiva pratica. Così ho aggiunto un listener statico nella gestione delle attività onActivityResult() che implementa un'interfaccia appropriata e ha istanziato questo listener come membro privato della classe Service.

Il codice in una forma semplificata si presenta così:

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

Come potete vedere non ho potuto evitare riferimenti statici a causa di problemi di rotazione del dispositivo, ma penso che questa soluzione è più appropriato; anche se prolisso.

0

Apri Attività trasparente dal servizio e utilizza BroadcastReceiver in servizio. Segui i passaggi in dettaglio.

1. Aprire un'attività trasparente dal Servizio

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

// Per l'uso di attività trasparente questo codice in AndroidManifest.xml

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

2. Creare BroadcastReceiver in Service

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

3. Registrare questa trasmissione su onCreate of Service

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

4. Annullare la registrazione questa trasmissione in OnDestroy of Service

mContext.unregisterReceiver(brOnActivityResult); 

5. fare il lavoro in attività utilizzando startSubActivity e inviare trasmissioni dal di attività (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(); 
} 
Problemi correlati