Auflistung aller Extras einer Absicht

251

Aus Debugging-Gründen möchte ich alle Extras (und deren Werte) einer Absicht auflisten. Jetzt ist es kein Problem, die Schlüssel zu bekommen

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

Aber die Werte der Schlüssel zu erhalten, ist eine für mich, weil einige Werte Zeichenfolgen sind, andere boolesch ... Wie könnte ich die Werte in einer Schleife abrufen (die Schlüssel durchlaufen) und die Werte in eine Protokolldatei schreiben? Danke für jeden Hinweis!

stefan.at.wpf
quelle

Antworten:

467

Folgendes habe ich verwendet, um Informationen über eine undokumentierte Absicht (von Drittanbietern) zu erhalten:

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

Stellen Sie sicher, dass bundlevor der Schleife überprüft wird, ob null ist.

kshahar
quelle
2
Ich habe gerade von der Intent Intercept Android App erfahren . Das funktioniert auch.
Vinayak
1
if (bundle == null) { return; }FTW
Matyas
23
Bundle bundle = data.getExtras();Wo dataist die Absicht? Für Android Anfänger.
ConquerorsHaki
2
Bevor Sie sich anmelden, müssen Sie überprüfen, ob der Wert null ist value = "null".
Sebastian Kreft
Danke dafür! Ich suchte nach einer Möglichkeit, alle Schlüssel zu überprüfen, die in dieser undokumentierten iTracing-App bereitgestellt wurden, um mein Telefon über eine billige Bluetooth-Taste zu steuern. Lief wie am Schnürchen!
Shane Smiskol
111

So definiere ich die Utility-Methode, um alle Extras eines Intents zu sichern.

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
quelle
8
Vielen Dank! Wenn nur das Android-Team damit beginnen würde, nützliche .toString-Überschreibungen wie diese zu implementieren.
Jim Vitek
37

Sie können dies in einer Codezeile tun:

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

Es gibt etwas aus wie:

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

Am Ende dieser Zeichenfolge (der Teil, den ich fett gedruckt habe) finden Sie die Liste der Extras (in diesem Beispiel nur eine zusätzliche).

Dies geht aus der toUri-Dokumentation hervor : "Der URI enthält die Daten des Intents als Basis-URI, wobei ein zusätzliches Fragment die Aktion, Kategorien, Typen, Flags, Pakete, Komponenten und Extras beschreibt."

Alex Vang
quelle
3
Wenn Sie nur debuggen und sehen möchten, was der Inhalt der Absicht ist, ist dies die beste Option. Vielen Dank
Shyri
Dies sollte die akzeptierte Antwort sein. Perfekt für das Debuggen von Protokollen!
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
quelle
8

Die Methode get (String key) von Bundle gibt ein Objekt zurück. Am besten drehen Sie sich über den Schlüsselsatz, indem Sie get (String) für jeden Schlüssel aufrufen und toString () für das Objekt verwenden, um sie auszugeben. Dies funktioniert am besten für Grundelemente, es können jedoch Probleme mit Objekten auftreten, die kein toString () implementieren.

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

Ich wollte eine Möglichkeit, den Inhalt einer Absicht in das Protokoll auszugeben und ihn leicht lesen zu können. Deshalb habe ich mir Folgendes ausgedacht. Ich habe eine LogUtilKlasse erstellt und dann die von dumpIntent()@Pratik erstellte Methode übernommen und ein wenig geändert. So sieht alles aus:

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

Hoffe das hilft jemandem!

LukeWaggoner
quelle
2

Sie können for (String key : keys) { Object o = get(key);ein Objekt zurückgeben, es aufrufen getClass().getName(), um den Typ abzurufen, und dann eine Reihe von if name.equals ("String") -Typen ausführen, um herauszufinden, welche Methode Sie tatsächlich aufrufen sollten, um den Wert abzurufen ?

Ben Williams
quelle
1

In der Android-Quelle ist mir aufgefallen, dass fast jede Operation das Bundle zwingt, seine Daten zu entpacken. Wenn Sie dies (wie ich) häufig zum Debuggen tun müssen, können Sie Folgendes schnell eingeben:

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

Es tut mir leid, wenn dies zu ausführlich oder zu spät ist, aber dies war der einzige Weg, den ich finden konnte, um die Arbeit zu erledigen. Der komplizierteste Faktor war die Tatsache, dass Java keine Referenzfunktionen zum Übergeben hat. Daher benötigen die Methoden get --- Extra einen Standardwert für die Rückgabe und können einen booleschen Wert nicht ändern, um festzustellen, ob der Standardwert zufällig zurückgegeben wird. oder weil die Ergebnisse nicht günstig waren. Zu diesem Zweck wäre es schöner gewesen, wenn die Methode eine Ausnahme ausgelöst hätte, als wenn sie eine Standardeinstellung zurückgegeben hätte.

Ich habe meine Informationen hier gefunden: 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

Dokumentation festlegen

    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
quelle
Sie möchten nicht so viel Code schreiben, um diese einfache Sache zu erledigen, es sei denn, Sie möchten Ihren Code so komplizieren, dass Sie sicher nie in der Lage sind, ein Update für Ihre App durchzuführen. Top-2-Antworten tun dies mit viel weniger Code und verwenden Log, das für solche Verwendungen besser ist als Toasts
Louis CAD
0

Die Kotlin-Version von Pratiks Utility-Methode, die alle Extras eines Intents enthält:

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

}
römisch
quelle
1
Es wäre einfacher zu bedienenfor (key in bundle.keySet())
DDoSolitary
-2

Wenn Sie zum Debuggen nur eine Zeichenfolge benötigen (vom OP impliziert, aber nicht explizit angegeben), verwenden Sie einfach toStringdie folgenden Extras Bundle:

intent.getExtras().toString()

Es gibt eine Zeichenfolge zurück wie:

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

Dokumentation: Bundle.toString () (es ist leider das Standard- Object.toString()Javadoc und als solches hier ziemlich nutzlos.)

ralfoide
quelle
4
Als ich dies versuchte, kehrte es zurück: Bundle [mParcelledData.dataSize = 480]
ToddH