Search code examples
javaandroiditeratorbundle

Android Bundle Iterator to Put and Remove Entries


I am seeking a method to iterate over the entries contained in a Bundle object. Currently, I am incorrectly using a For Each approach:

for (String key : bundle.keySet()) {
    if ("videourl".equals(key.toLowerCase()) || "priority".equals(key.toLowerCase())) {
        // Save value to bundle using lowercase key value
        extras.putString(key.toLowerCase(), (String) extras.get(key));
        // Remove original version of this bundle entry
        extras.remove(key);
    }
}

The problem with the approach shown above is that it risks arbitrary, non-deterministic behavior at an undetermined time in the future.

I've seen Iterator implementations for Map objects (e.g. https://stackoverflow.com/a/1884916/3957979):

for(Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); it.hasNext(); ) {
  Map.Entry<String, String> entry = it.next();
  if(entry.getKey().equals("test")) {
    it.remove();
  }
}

However, I don't have direct access to the Bundle's entries so I can't use the same approach.

Please let me know if Iterators can be used with Bundle objects or please suggest a different approach.


Solution

  • Unfortunately, I was not able to find a way to use an iterator to add and remove entries to the Bundle. My workaround is to save entries I want to add into a temporary Bundle object and to save the original key names for the entries I want to delete to a List. See the code below:

    // Loop through all messages and change the extras' key names to lowercase (only for keys of interest)
    Bundle tempBundle = new Bundle();
    ArrayList<String> keysToBeRemoved = new ArrayList<>();
    Bundle extras = messages.get(i).getExtras();
    
    for (String key : extras.keySet()) {
        // Check if key is not all lower case and if it is a key of interest
        if (!key.equals(key.toLowerCase()) && isKeyOfInterest(key)) {
            // Save value to bundle using lowercase key value
            tempBundle.putString(key.toLowerCase(), extras.getString(key));
            // Add original version of this key to a list for later deletion
            keysToBeRemoved.add(key);
        }
    }
    
    // Remove original entries from message extras
    for (String originalKey : keysToBeRemoved) {
        extras.remove(originalKey);
    }
    
    // Add all new bundle entries to message extras
    extras.putAll(tempBundle);
    

    Still, if anyone does figure out how to use an Iterator with a Bundle, I'd love to know!