2010-07-21 12 views
31

C'è un modo per un Activity per scoprire chi (nome della classe) ha inviato uno Intent? Sto cercando un modo generico per il mio Activity per rispondere a un intento ricevuto inviandone uno al mittente, chiunque sia.Come ottenere il mittente di un intent?

risposta

27

Potrebbe esserci un altro modo, ma l'unica soluzione che so è che l'attività A ha richiamato l'attività B tramite startActivityForResult(). Quindi l'attività B può utilizzare getCallingActivity() per recuperare l'identità dell'Attività A.

+1

Stiamo lavorando su una libreria per verificare il mittente e il destinatario di 'Intent's che utilizza questa tecnica per iniziare, dal momento che è la più semplice. Puoi trovare ulteriori informazioni qui https://dev.guardianproject.info/projects/trustedintents/wiki –

+1

Come utilizzare getCallingActivity()? Ho provato ad usarlo per impostare il testo in questo modo: 'txt.setText (getCallingActivity());' ma mostra 'null'. Cosa posso fare per farlo mostrare il nome dell'attività di chiamata? –

5

Generalmente non è necessario saperlo. Se l'attività di chiamata utilizza startActivityForResult(Intent, int), il destinatario può utilizzare setResult(int, Intent) per specificare un intent da inviare al chiamante. Il chiamante riceverà questo intento nel suo metodo onActivityResult(int, int, Intent).

+1

L'intento di 'setResult' viene inviato solo quando l'attività figlio è chiusa. Mi piacerebbe essere in grado di rinviare arbitrariamente gli intenti all'attività dei genitori mentre l'attività dei bambini è operativa. – zer0stimulus

7

Questo non è incredibilmente diretto ma è possibile ottenere un elenco delle attività recenti da ActivityManager. Quindi il chiamante sarebbe essenzialmente il compito prima del tuo e tu puoi recuperare informazioni su quell'attività.

Esempio di utilizzo:

ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); 
List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasks(10000,ActivityManager.RECENT_WITH_EXCLUDED); 

È possibile che questo restituirà un elenco di tutti i compiti dalla più recente (il vostro) per il limite specificato. Vedere i documenti here per il tipo di informazioni che è possibile ottenere da un oggetto RecentTaskInfo.

+2

getRecentTasks è obsoleto in API 21 e non funzionerà più per gli stack che non appartengono alla tua app. Vedere http://developer.android.com/reference/android/app/ActivityManager.html#getRecentTasks(int, int) –

7

Una tecnica che uso è richiedere all'applicazione di inviare l'Intent rilevante per aggiungere un PendingIntent come extra Parcelable; il PendingIntent può essere di qualsiasi tipo (servizio, trasmissione, ecc.). L'unica cosa che fa il mio servizio è chiamare PendingIntent.getCreatorUid() e getCreatorPackage(); questa informazione viene popolata quando PendingIntent viene creato e non può essere falsificato dall'app in modo da ottenere le informazioni sul mittente di Intent. Solo l'avvertenza è che la soluzione funziona solo da Jellybean e in seguito, che è il mio caso. Spero che questo aiuti,

+0

Come si richiede loro di inviare un PendingIntent? Non vedo un'opzione intent-filter per questo. Ti basta inserire intenti che non ne hanno uno come extra? – TBridges42

+0

Sembra una cattiva idea a prima vista. Un'app malevola non potrebbe falsificare il 'PendingIntent'? Certo, 'PendingIntent' non ha un costruttore pubblico ma' readPendingIntentOrNullFromParcel' sembra che potrebbe fare il trucco, no? – Giszmo

+1

@Giszmo bene i documenti getCreatorUid() dichiarano che non può essere falsificato. Non sei sicuro di come viene gestita la serializzazione, ma devono esserci alcune misure di sicurezza speciali, come la firma dei contenuti serializzati con una chiave privata di proprietà del creatore. Detto questo, come sottolineano i documenti getCreatorUid(), devi comunque stare attento a questa strategia. Solo perché alcuni pacchetti X hanno un PendingIntent creato da Y non significa che X == Y. Y potrebbe aver inviato il PendingIntent a X per scopi non correlati. E Y inviando un PendingIntent a X significa che Y si fida di X con quella particolare azione, non in generale. –

1

Sulla base alla tua domanda, dal momento che si desidera inviare un intento torna al startSubActivity mittente è una scelta migliore di quello che sto per suggerire. Ma avevo bisogno di avviare l'attività B quando l'utente ha fatto clic su una notifica ed eseguire del codice nell'attività B solo se l'attività del mittente è l'attività A. Ecco come l'ho fatto in modo molto semplice.

All'interno Attività A:

String senderName = this.getClass().getSimpleName();   
Intent clickIntent = new Intent(ActivityA.this, ActivityB.class); 
clickIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
clickIntent.putExtra("SENDER_CLASS_NAME", senderName); 

//I use PendingIntent to start Activity B but you can use what you like such as this.startActivity(clickIntent); 
PendingIntent.getActivity(ActivityA.this, NOTIFICATION_ID, clickIntent, PendingIntent.FLAG_ONE_SHOT); 

All'interno Attività B:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    if (savedInstanceState == null) { 
     Bundle bundle = getIntent().getExtras(); 
     if (bundle != null) { 
      if(bundle.containsKey("SENDER_CLASS_NAME")){ 
       String senderName = bundle.getString("SENDER_CLASS_NAME");     
       //Execute some code 
       Log.d("GCM", "Notifications clicked"); 
       } 
      } 
     } 
    } 
9

E 'un app esterna si riceve l'intento da? È possibile utilizzare il metodo della classe di attività

Un semplice esempiogetReferrer(): Ho aperto Google Map app per condividere alcune posizione con la mia app utilizzando l'opzione quota di google maps. Poi la mia app si apre e questa chiamata di metodo nella attività:

this.getReferrer().getHost() 

tornerà:

com.google.android.apps.maps 

vedere la documentazione qui: https://developer.android.com/reference/android/app/Activity.html#getReferrer()

Si noti che questo richiede API 22.Per le versioni precedenti di Android vedere la risposta di ajwillliams

+0

Cosa succede se la tua app è già stata aperta e rimane in background mentre usi la funzione di condivisione in google maps. Restituirà ancora il packagename di google maps? – mathew11

+1

getReferrer() richiede API22 (Android 5.1). Cosa fare nelle versioni inferiori come 4.4? –

+0

Alcuni codici per verificare l'API22: String startedFrom = null; if (android.os.Build.VERSION.SDK_INT> = Build.VERSION_CODES.LOLLIPOP_MR1) { startedFrom = this.getReferrer(). GetHost(); } – FrankKrumnow

Problemi correlati