Liste de tous les extras d'une intention

251

Pour des raisons de débogage, je souhaite répertorier tous les extras (et leurs valeurs) d'une intention. Maintenant, obtenir les clés n'est pas un problème

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

mais obtenir les valeurs des clés en est une pour moi, car certaines valeurs sont des chaînes, d'autres sont booléennes ... Comment pourrais-je obtenir les valeurs dans une boucle (parcourir les clés en boucle) et écrire les valeurs dans un fichier journal? Merci pour tout indice!

stefan.at.wpf
la source

Réponses:

467

Voici ce que j'ai utilisé pour obtenir des informations sur une intention non documentée (tierce partie):

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

Assurez-vous de vérifier si bundleest nul avant la boucle.

kshahar
la source
2
Je viens de découvrir l' application Android Intent Intercept . Ça marche aussi.
Vinayak
1
if (bundle == null) { return; }FTW
Matyas
23
Bundle bundle = data.getExtras();dataest l'intention. Pour les débutants Android.
ConquerorsHaki
2
Avant de vous connecter, vous devez vérifier si la valeur est nulle, si c'est le cas value = "null".
Sebastian Kreft
Merci pour cela! Je cherchais un moyen de vérifier toutes les clés fournies dans cette application iTracing non documentée, pour contrôler mon téléphone via un bouton Bluetooth bon marché. A fonctionné comme un charme!
Shane Smiskol
111

C'est ainsi que je définis la méthode utilitaire pour vider tous les extras d'une intention.

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");
    }
}
Pratik
la source
8
Merci! Maintenant, si seulement l'équipe Android commençait à mettre en œuvre des substitutions .toString utiles comme celle-ci.
Jim Vitek
37

Vous pouvez le faire en une seule ligne de code:

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

Il produit quelque chose comme:

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

À la fin de cette chaîne (la partie que j'ai mise en gras), vous pouvez trouver la liste des extras (un seul supplémentaire dans cet exemple).

Ceci est conforme à la documentation de toUri : "L'URI contient les données de l'intention en tant qu'URI de base, avec un fragment supplémentaire décrivant l'action, les catégories, le type, les indicateurs, le package, le composant et les extras."

Alex Vang
la source
3
Si vous voulez simplement déboguer et voir quel est le contenu de l'intention, c'est la meilleure option. Merci beaucoup
Shyri
Ce devrait être la réponse acceptée. Parfait pour le débogage des journaux!
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());
    }
}
user123321
la source
8

La méthode get (String key) de Bundle renvoie un objet. Votre meilleur pari est de faire tourner l'ensemble de clés en appelant get (String) sur chaque clé et en utilisant toString () sur l'objet pour les sortir. Cela fonctionnera mieux pour les primitives, mais vous pouvez rencontrer des problèmes avec des objets qui n'implémentent pas de toString ().

nicholas.hauschild
la source
4
Bundle extras = getIntent().getExtras();
Set<String> ks = extras.keySet();
Iterator<String> iterator = ks.iterator();
while (iterator.hasNext()) {
    Log.d("KEY", iterator.next());
}
Luis
la source
1
for (String key: extras.keySet ()) {Log.d (LOG_TAG, key + ":" + extras.get (key)); }
Defuera
4

Je voulais un moyen de sortir le contenu d'une intention dans le journal et de pouvoir le lire facilement, alors voici ce que j'ai trouvé. J'ai créé une LogUtilclasse, puis dumpIntent()j'ai pris la méthode créée par @Pratik et l'ai légèrement modifiée. Voici à quoi tout cela ressemble:

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

J'espère que cela aide quelqu'un!

LukeWaggoner
la source
2

Vous pouvez utiliser for (String key : keys) { Object o = get(key);pour renvoyer un objet, l'appeler getClass().getName()pour obtenir le type, puis faire un ensemble de choses de type if name.equals ("String") pour déterminer la méthode que vous devez réellement appeler, afin d'obtenir la valeur ?

Ben Williams
la source
1

J'ai remarqué dans la source Android que presque toutes les opérations obligent le Bundle à décompresser ses données. Donc, si (comme moi) vous devez le faire fréquemment à des fins de débogage, la saisie ci-dessous est très rapide:

Bundle extras = getIntent().getExtras();
extras.isEmpty(); // unparcel
System.out.println(extras);
Ian Lovejoy
la source
0

Désolé si c'est trop verbeux ou trop tard, mais c'était le seul moyen que j'ai pu trouver pour faire le travail. Le facteur le plus compliqué était le fait que java ne dispose pas de fonctions de passage par référence, donc les méthodes get --- Extra ont besoin d'une valeur par défaut pour retourner et ne peuvent pas modifier une valeur booléenne pour dire si la valeur par défaut est retournée par hasard, ou parce que les résultats n'étaient pas favorables. À cette fin, il aurait été plus agréable que la méthode lève une exception que de renvoyer une valeur par défaut.

J'ai trouvé mes informations ici: Android Intent Documentation .

    //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

Définir la documentation

    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();
    }
Jackson Kulik
la source
Vous ne voulez pas écrire autant de code pour faire cette chose simple, sauf si vous voulez compliquer tellement votre code que vous êtes certain de ne jamais pouvoir obtenir une mise à jour de votre application. Les réponses Top-2 le font avec beaucoup moins de code et en utilisant Log, ce qui est mieux que Toasts pour de telles utilisations
Louis CAD
0

La version Kotlin de la méthode utilitaire de Pratik qui vide tous les extras d'une intention:

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

}
romain
la source
1
Il serait plus simple à utiliserfor (key in bundle.keySet())
DDoSolitary
-2

Si pour déboguer tout ce que vous voulez est une chaîne (en quelque sorte implicite par l'OP mais non explicitement indiquée), utilisez simplement toStringsur les extras Bundle:

intent.getExtras().toString()

Il renvoie une chaîne telle que:

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

Documentation: Bundle.toString () (c'est malheureusement le Object.toString()javadoc par défaut et en tant que tel tout à fait inutile ici.)

ralfoide
la source
4
Lorsque j'ai essayé cela, il renvoie: Bundle [mParcelledData.dataSize = 480]
ToddH