Is there an easy way to print the contents of a Bundle
to Logcat if you can't remember the names of all the keys (even being able to print just the key names would be cool)?
12 Answers
Bundle#keySet() should work.
for (String key: bundle.keySet())
{
Log.d ("myApplication", key + " is a key in the bundle");
}
And if you want to get the Object, you can use Bundle#get(String key)
(which is also in the same documentation I linked at the top of my answer). However, keep in mind using the generic get()
call:
- You're working with Object. If you're simply printing to a Log,
toString()
will be invoked and all will be fine. However, if you actually want to use the key's pair, you need to doinstanceof
checks to avoid calling the wrong method. - Since toString will be invoked, if you have a special Object (eg ArrayLists, or special Serializable/Parcelable extras) you're most likely not going to get anything useful from the printout.

- 36,351
- 10
- 106
- 92
-
2I think you meant `bundle.keySet()` (since your docs link is fine); otherwise this is correct. – Cat Feb 19 '13 at 02:20
-
1@Eric gah, silly errors. At least I spelled it correctly when I linked to it. – A--C Feb 19 '13 at 02:22
You can get more specific by printing the mapped value as follows:
for (String key : bundle.keySet())
{
Log.d("Bundle Debug", key + " = \"" + bundle.get(key) + "\"");
}

- 35,852
- 23
- 123
- 164
Bundle-to-string converter:
public static String bundle2string(Bundle bundle) {
if (bundle == null) {
return null;
}
String string = "Bundle{";
for (String key : bundle.keySet()) {
string += " " + key + " => " + bundle.get(key) + ";";
}
string += " }Bundle";
return string;
}
Example usage:
Log.d(TAG,"details="+bundle2string(details));
and output:
details=Bundle{ RESPONSE_CODE => 5; }Bundle
Note that the arrows =>
and semicolons ;
let you mention spaces in the keys and values. One space before the arrow, one space after the arrow, no space before the semi-colon, one space after the semi-colon, one space after {
and one space before }
, and all other spaces are there because they are in the keys or values.

- 16,368
- 4
- 94
- 127
-
Good solution, but I would rather use a StringBuffer for better performance: `public static String bundle2string(Bundle bundle) { StringBuffer buf = new StringBuffer("Bundle{"); for (String key : bundle.keySet()) buf.append(" " + key + " => " + bundle.get(key) + ";"); buf.append(" }Bundle"); return buf.toString(); }` – Maurix Sep 05 '14 at 09:09
-
1IMO performance is irrelevant to the purpose of _bundle2string()_, but even if we assume the opposite, according to http://stackoverflow.com/a/4649160/755804 , _String concatenation is translated into StringBuilder operations by the compiler._ I did not check it myself for Android; if someone cares to check this, please confirm or disprove. – 18446744073709551615 Sep 05 '14 at 09:35
-
1@Maurix Since there are no threads involved, StringBuilder is better than StringBuffer : https://developer.android.com/reference/java/lang/StringBuffer.html – android developer Sep 29 '16 at 09:53
-
Note that some values might contain multiple-lines, so it can get problematic to print all of them in a single log entry. – Yoav Feuerstein Sep 19 '17 at 15:26
Realize that this isn't answering the question exactly, but I see allot of developers trying to dump the contents to logcat/console because they are not aware that they can set up in Android Studio debugger to display customized object rendering at debug time, when you hit a break point. And in the case of Bundle, you can take the type of code shown in the other answers here, and apply that as a custom renderer, so that you don't need to pipe the dump to logcat and/or the console.
(These instructions are from Android Studio 3.1.3 (June 2018) ...
- Select the "File" and then the "Settings" menu option/suboption.
- In the 'Settings' dialog, on the left side, drill-down and select "Build, Execution, Deployment", "Debugger", "Data Views", "Java Type Renderers".
- Right side of the dialog, where it says "Renderer name" enter a name you wish to identify with the renderer you are creating.
- Right side of the dialog, where it says "Apply renderer to objects of type", enter 'android.os.Bundle'.
- Right side of the dialog, under the "When rendering a node" section, select the "Use following expression:" radio button.
- In the text field below that, type in the following ...
StringBuilder builder = new StringBuilder(); for (String key : ((android.os.Bundle)this).keySet()) { Object value = ((android.os.Bundle)this).get(key); builder.append("["); builder.append(key); builder.append("]=["); builder.append(value); builder.append("]("); builder.append((value != null) ? value.getClass().getSimpleName() : "null"); builder.append("), "); } return builder.toString();
- Press 'Apply'/'OK' button.
Now, when you run your app, and you hit a breakpoint that shows a variable that is of type android.os.Bundle, you'll see the output generated from the above code, on the variables section of the debugger window.
I'll also include a screenshot, showing what I described above ...

- 1,795
- 16
- 23
-
1This is a really neat feature of Android Studio that I didn't know existed. Thank you! – Julian A. Dec 14 '18 at 22:03
-
@Julian A. You're welcome. Yeah, I've always been surprised its not talked about more, and wish that pre-created expressions for used often classes are not included with Android Studio, would save some time. FYI, Eclipse also has a similar feature as well, for those who use that IDE. – Adrian Romanelli Dec 18 '18 at 01:42
-
Great tip! And it turns out we can simplify the renderer expression to `keySet(); toString()` since accessing the Bundle's contents seems to reify it, letting `toString()` format all the elements. See my Answer. – Jerry101 Mar 01 '22 at 19:11
Simple Bundle to String implementation in Kotlin:
val bundleToString = bundle.keySet()
.joinToString(", ", "{", "}") { key ->
"$key=${bundle[key]}"
}
Example of result {id=3, name="Jhon"}

- 1,545
- 20
- 31
-
1Thanks, it works. The keys are arranged in alphabetical order (`keySet()` returns a sorted collection). – CoolMind Dec 23 '20 at 15:35
In Kotlin, recursive for when it contains child bundles:
/**
* Recursively logs the contents of a [Bundle] for debugging.
*/
fun Bundle.printDebugLog(parentKey: String = "") {
if (keySet().isEmpty()) {
Log.d("printDebugLog", "$parentKey is empty")
} else {
for (key in keySet()) {
when (val value = this[key]) {
is Bundle -> value.printDebugLog(key)
is Array<*> -> Log.d("printDebugLog", "$parentKey.$key : ${value.joinToString()}")
else -> Log.d("printDebugLog", "$parentKey.$key : $value")
}
}
}
}
Usage: myBundle.printDebugLog()

- 88
- 8

- 12,010
- 8
- 61
- 78
Trick: Access the Bundle's contents to reify it, then bundle.toString()
will format its elements.
(I'd rely on this only for debugging purposes.)
Example in an AppWidgetProvider, call newOptions.keySet()
:
@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
int appWidgetId, Bundle newOptions) {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
newOptions.keySet(); // <-- reify the Bundle so .toString() will elaborate
Log.i(TAG, "*** WidgetOptionsChanged: " + newOptions);
}
Result:
*** WidgetOptionsChanged: Bundle[{appWidgetMaxHeight=137, appWidgetCategory=1, appWidgetMaxWidth=603, appWidgetMinHeight=82, appWidgetMinWidth=338, appWidgetSizes=[338.0x137.5, 603.5x82.0]}]
Much better than:
*** WidgetOptionsChanged: Bundle[mParcelledData.dataSize=408]

- 12,157
- 5
- 44
- 63
Kotlin
If you have simple Bundle
s (without nested bundles) then the tip by Jerry101 will already get you very far (see their comment why this works). Here's a one-liner:
Log.d(TAG, "bundle: ${bundle?.also { it.keySet() }?: "N/A"}")
The above prints:
bundle: Bundle[{a=42, s=hello, ...}]
Or when the bundle is null
:
bundle: N/A
In case you're not confident that the above will always work, with slightly more code almost the same thing (using the keySet
function that others here have already pointed out) - also one line:
Log.d(TAG, "bundle: ${bundle?.keySet()?.associateWith { bundle[it] }?: "N/A"}")
This converts the bundle to a map and prints
bundle: {a=42, s=hello, ...}

- 688
- 11
- 19
Java 8 stream one liner:
bundle.keySet().stream().forEach(k -> Log.d(TAG, k + " = " + bundle.get(k)));

- 31
- 3
I have developed a library called pretty-print
which annotation processor that prints the contents of the bundle in a nice table format.
Do check it out
https://github.com/NULLPointerGuy/pretty-print

- 707
- 1
- 10
- 19
A Kotlin solution:
val bundleFromNotifications: Bundle? = remoteMessage?.toIntent()?.extras
bundleFromNotifications?.keySet()?.forEach{
Log.d(LOG_TAG, it + "=> \"" + bundleFromNotifications.get(it) + "\"")
}

- 8,598
- 83
- 57
- 92

- 31
- 6
Solution in Kotlin:
fun Bundle.toPrintableString(): String {
val sb = StringBuilder("{")
var isFirst = true
for (key in keySet()) {
if (!isFirst)
sb.append(',')
else
isFirst = false
when (val value = get(key)) {
is Bundle -> sb.append(key).append(':').append(value.toPrintableString())
else -> sb.append(key).append(':').append(value)
//TODO handle special cases if you wish
}
}
sb.append('}')
return sb.toString()
}
Sample:
val bundle = Bundle()
bundle.putString("asd", "qwe")
bundle.putInt("zxc", 123)
Log.d("AppLog", "bundle:${bundle.toPrintableString()}")
Note that it doesn't handle all possible types of values. You should decide which are important to show and in which way.

- 114,585
- 152
- 739
- 1,270