Elencando tutti gli extra di un Intento


251

Per motivi di debug voglio elencare tutti gli extra (e i loro valori) di un Intento. Ora, ottenere le chiavi non è un problema

Set<String> keys = intent.getExtras().keySet();

ma ottenere i valori delle chiavi è uno per me, perché alcuni valori sono stringhe, altri sono booleani ... Come posso ottenere i valori in un ciclo (scorrere le chiavi) e scrivere i valori in un file di registro? Grazie per qualsiasi suggerimento!

Risposte:


467

Ecco cosa ho usato per ottenere informazioni su un intento non documentato (di terze parti):

Bundle bundle = intent.getExtras();
if (bundle != null) {
    for (String key : bundle.keySet()) {
        Log.e(TAG, key + " : " + (bundle.get(key) != null ? bundle.get(key) : "NULL"));
    }
}

Assicurati di verificare se bundleè nullo prima del ciclo.


2
Ho appena scoperto l' app Intent Intercept per Android . Anche questo funziona.
Vinayak

1
if (bundle == null) { return; }FTW
Matyas,

23
Bundle bundle = data.getExtras();Dov'è datal'intento. Per i principianti Android.
ConquerorsHaki,

2
Prima di accedere è necessario verificare se il valore è null, in tal caso value = "null".
Sebastian Kreft,

Grazie per questo! Stavo cercando un modo per controllare tutti i tasti forniti in questa app iTracing non documentata, per controllare il mio telefono tramite un pulsante Bluetooth economico. Ha funzionato come un fascino!
Shane Smiskol,

111

Questo è il modo in cui definisco il metodo di utilità per scaricare tutti gli extra di un Intento.

import java.util.Iterator;
import java.util.Set;
import android.os.Bundle;


public static void dumpIntent(Intent i){

    Bundle bundle = i.getExtras();
    if (bundle != null) {
        Set<String> keys = bundle.keySet();
        Iterator<String> it = keys.iterator();
        Log.e(LOG_TAG,"Dumping Intent start");
        while (it.hasNext()) {
            String key = it.next();
            Log.e(LOG_TAG,"[" + key + "=" + bundle.get(key)+"]");
        }
        Log.e(LOG_TAG,"Dumping Intent end");
    }
}

8
Grazie! Ora, se solo il team Android inizierà a implementare utili sostituzioni .toString in questo modo.
Jim Vitek,

37

Puoi farlo in una riga di codice:

Log.d("intent URI", intent.toUri(0));

Emette qualcosa del tipo:

"#Intent; action = android.intent.action.MAIN; categoria = android.intent.category.LAUNCHER; launchFlags = 0x10a00000; component = com.mydomain.myapp / .StartActivity; sourceBounds = 12% 20870% 20276% 201167; l .profile = 0; fine "

Alla fine di questa stringa (la parte che ho in grassetto) puoi trovare l'elenco degli extra (solo un extra in questo esempio).

Questo è secondo la documentazione di toUri : "L'URI contiene i dati dell'intento come URI di base, con un frammento aggiuntivo che descrive l'azione, le categorie, il tipo, i flag, il pacchetto, il componente e gli extra".


3
Se vuoi solo eseguire il debug e vedere quali sono i contenuti dell'intento, questa è l'opzione migliore. Grazie mille
Shyri,

Questa dovrebbe essere la risposta accettata. Perfetto per il debug dei log!
Ethan Arnold,

12
private TextView tv;

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

    tv = new TextView(this);
    tv.setText("Extras: \n\r");

    setContentView(tv);

    StringBuilder str = new StringBuilder();
    Bundle bundle = getIntent().getExtras();
    if (bundle != null) {
        Set<String> keys = bundle.keySet();
        Iterator<String> it = keys.iterator();
        while (it.hasNext()) {
            String key = it.next();
            str.append(key);
            str.append(":");
            str.append(bundle.get(key));
            str.append("\n\r");
        }
        tv.setText(str.toString());
    }
}

8

Il metodo get (String key) di Bundle restituisce un oggetto. La soluzione migliore è girare il set di chiavi chiamando get (String) su ciascun tasto e usando toString () sull'Oggetto per emetterli. Funzionerà meglio con le primitive, ma potresti riscontrare problemi con Oggetti che non implementano un toString ().


4
Bundle extras = getIntent().getExtras();
Set<String> ks = extras.keySet();
Iterator<String> iterator = ks.iterator();
while (iterator.hasNext()) {
    Log.d("KEY", iterator.next());
}

1
for (Chiave stringa: extras.keySet ()) {Log.d (LOG_TAG, chiave + ":" + extras.get (chiave)); }
Defuera,

4

Volevo un modo per generare il contenuto di un intento nel registro e poterlo leggere facilmente, quindi ecco cosa mi è venuto in mente. Ho creato una LogUtilclasse, quindi ho preso il dumpIntent()metodo creato da @Pratik e l'ho modificato un po '. Ecco come appare tutto:

public class LogUtil {

    private static final String TAG = "IntentDump";

    public static void dumpIntent(Intent i){
        Bundle bundle = i.getExtras();
        if (bundle != null) {
            Set<String> keys = bundle.keySet();

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("IntentDump \n\r");
            stringBuilder.append("-------------------------------------------------------------\n\r");

            for (String key : keys) {
                stringBuilder.append(key).append("=").append(bundle.get(key)).append("\n\r");
            }

            stringBuilder.append("-------------------------------------------------------------\n\r");
            Log.i(TAG, stringBuilder.toString());
        }
    }
}

Spero che questo aiuti qualcuno!


2

È possibile utilizzare for (String key : keys) { Object o = get(key);per restituire un oggetto, chiamarlo getClass().getName()per ottenere il tipo, quindi eseguire una serie di elementi if name.equals ("String") per capire quale metodo si dovrebbe effettivamente chiamare, al fine di ottenere il valore ?


1

Ho notato nella fonte Android che quasi ogni operazione costringe il Bundle a non impacchettare i suoi dati. Quindi, se (come me) è necessario farlo frequentemente per scopi di debug, di seguito è molto veloce digitare:

Bundle extras = getIntent().getExtras();
extras.isEmpty(); // unparcel
System.out.println(extras);

0

Scusate se questo è troppo dettagliato o troppo tardi, ma questo è stato l'unico modo che ho potuto trovare per fare il lavoro. Il fattore più complicato è stato il fatto che java non ha funzioni di riferimento passanti, quindi i metodi get --- Extra hanno bisogno di un valore predefinito per restituire e non possono modificare un valore booleano per dire se il valore predefinito viene restituito per caso, o perché i risultati non erano favorevoli. A tal fine, sarebbe stato meglio avere il metodo sollevare un'eccezione piuttosto che restituire un valore predefinito.

Ho trovato le mie informazioni qui: Documentazione di Android Intent .

    //substitute your own intent here
    Intent intent = new Intent();
    intent.putExtra("first", "hello");
    intent.putExtra("second", 1);
    intent.putExtra("third", true);
    intent.putExtra("fourth", 1.01);
    // convert the set to a string array

Imposta documentazione

    String[] anArray = {};
    Set<String> extras1 = (Set<String>) intent.getExtras().keySet();
    String[] extras = (String[]) extras1.toArray(anArray);
    // an arraylist to hold all of the strings
    // rather than putting strings in here, you could display them
    ArrayList<String> endResult = new ArrayList<String>();
    for (int i=0; i<extras.length; i++) {
        //try using as a String
        String aString = intent.getStringExtra(extras[i]);
        // is a string, because the default return value for a non-string is null
        if (aString != null) {
            endResult.add(extras[i] + " : " + aString);
        }
        // not a string
        else {
            // try the next data type, int
            int anInt = intent.getIntExtra(extras[i], 0);
            // is the default value signifying that either it is not an int or that it happens to be 0 
            if (anInt == 0) {
                // is an int value that happens to be 0, the same as the default value
                if (intent.getIntExtra(extras[i], 1) != 1) {
                    endResult.add(extras[i] + " : " + Integer.toString(anInt));
                }
                // not an int value
                // try double (also works for float)
                else {
                    double aDouble = intent.getDoubleExtra(extras[i], 0.0);
                    // is the same as the default value, but does not necessarily mean that it is not double
                    if (aDouble == 0.0) {
                        // just happens that it was 0.0 and is a double
                        if (intent.getDoubleExtra(extras[i], 1.0) != 1.0) {
                            endResult.add(extras[i] + " : " + Double.toString(aDouble));
                        }
                        // keep looking...
                        else {
                            // lastly check for boolean
                            boolean aBool = intent.getBooleanExtra(extras[i], false);
                            // same as default, but not necessarily not a bool (still could be a bool)
                            if (aBool == false) {
                                // it is a bool!
                                if (intent.getBooleanExtra(extras[i], true) != true) {
                                    endResult.add(extras[i] + " : " + Boolean.toString(aBool));
                                }
                                else {
                                    //well, the road ends here unless you want to add some more data types
                                }
                            }
                            // it is a bool
                            else {
                                endResult.add(extras[i] + " : " + Boolean.toString(aBool));
                            }
                        }
                    }
                    // is a double
                    else {
                        endResult.add(extras[i] + " : " + Double.toString(aDouble));
                    }
                }
            }
            // is an int value
            else {
                endResult.add(extras[i] + " : " + Integer.toString(anInt));
            }
        }
    }
    // to display at the end
    for (int i=0; i<endResult.size(); i++) {
        Toast.makeText(this, endResult.get(i), Toast.LENGTH_SHORT).show();
    }

Non vuoi scrivere così tanto codice per fare questa semplice cosa a meno che tu non voglia complicare così tanto il tuo codice da non riuscire mai a fare un aggiornamento della tua app. Le risposte migliori 2 fanno questo con molto meno codice e usando Log, che è meglio di Toasts per tali usi
Louis CAD

0

La versione di Kotlin del metodo di utilità di Pratik che scarica tutti gli extra di un Intento:

fun dumpIntent(intent: Intent) {

    val bundle: Bundle = intent.extras ?: return

    val keys = bundle.keySet()
    val it = keys.iterator()

    Log.d(TAG, "Dumping intent start")

    while (it.hasNext()) {
        val key = it.next()
        Log.d(TAG,"[" + key + "=" + bundle.get(key)+"]");
    }

    Log.d(TAG, "Dumping intent finish")

}

1
Sarebbe più semplice da usarefor (key in bundle.keySet())
DDoSolitary

-2

Se per il debug tutto ciò che vuoi è una stringa (una specie di implicita dall'OP ma non dichiarata esplicitamente), usa semplicemente toStringsugli extra Bundle:

intent.getExtras().toString()

Restituisce una stringa come:

Bundle[{key1=value1, key2=value2, key3=value3}]

Documentazione: Bundle.toString () (purtroppo è il Object.toString()javadoc predefinito e come tale abbastanza inutile qui.)


4
Quando ho provato questo ritorna: Bundle [mParcelledData.dataSize = 480]
ToddH
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.