Android.net.uri getQueryParameterNames () alternative

I am looking for an alternative way to get request parameter names from android.net.Uri. getQueryParameterNames () requires an api level 11. I would like to do the same for any lower level api. I watched getQuery (), which will return everything after "?" sign. Would there be a better way to do this to parse this line and search for everything up to '=' and grab it? I just donโ€™t know what query parameters will be presented each time.

+4
source share
4 answers

The only problem with API <11 is that this method is not implemented. I think the best idea is to look into the Android source code and use the implementation from the API> = 11. This should get absolutely identical functionality even in older APIs.

This is one of 4.1.1, modified to take Uri as a parameter, so you can use it right away:

/** * Returns a set of the unique names of all query parameters. Iterating * over the set will return the names in order of their first occurrence. * * @throws UnsupportedOperationException if this isn't a hierarchical URI * * @return a set of decoded names */ private Set<String> getQueryParameterNames(Uri uri) { if (uri.isOpaque()) { throw new UnsupportedOperationException("This isn't a hierarchical URI."); } String query = uri.getEncodedQuery(); if (query == null) { return Collections.emptySet(); } Set<String> names = new LinkedHashSet<String>(); int start = 0; do { int next = query.indexOf('&', start); int end = (next == -1) ? query.length() : next; int separator = query.indexOf('=', start); if (separator > end || separator == -1) { separator = end; } String name = query.substring(start, separator); names.add(Uri.decode(name)); // Move start to end of name. start = end + 1; } while (start < query.length()); return Collections.unmodifiableSet(names); } 

If you want to delve into it yourself, here is the source code:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/net/Uri.java?av=f

+12
source

If you have java.net.URI (or create one), you can use URLEncodedUtils.parse to get the parameters and values โ€‹โ€‹as NameValuePair :

 Map<String, String> parameters = Maps.newHashMap(); List<NameValuePair> params = URLEncodedUtils.parse(uri, "UTF-8"); for (NameValuePair param : params) { parameters.put(param.getName(), param.getValue()); } 
+3
source

I agree with foxter that the best choice is to get the code from the latest version of Android and add it to your code base. Each time I encounter such problems, I create a method for abstracting idiosyncrasy versions. This happens as follows:

 public class FWCompat { public static boolean isFroyo_8_OrNewer() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO; } public static boolean isGingerbread_9_OrNewer() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD; } public static boolean isHoneycomb_11_OrNewer() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; } public static boolean isHoneycomb_13_OrNewer() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2; } public static boolean isJellyBean_16_OrNewer() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN; } } @SuppressLint("NewApi") public class FWUriCompat { public static Set<String> getQueryParameterNames(Uri uri) { if (FWCompat.isHoneycomb_11_OrNewer()) { return uri.getQueryParameterNames(); } return FW_getQueryParameterNames(uri); } private static Set<String> FW_getQueryParameterNames(Uri uri) { if (uri == null) { throw new InvalidParameterException("Can't get parameter from a null Uri"); } if (uri.isOpaque()) { throw new UnsupportedOperationException("This isn't a hierarchical URI."); } String query = uri.getEncodedQuery(); if (query == null) { return Collections.emptySet(); } Set<String> names = new LinkedHashSet<String>(); int start = 0; do { int next = query.indexOf('&', start); int end = (next == -1) ? query.length() : next; int separator = query.indexOf('=', start); if (separator > end || separator == -1) { separator = end; } String name = query.substring(start, separator); names.add(Uri.decode(name)); // Move start to end of name. start = end + 1; } while (start < query.length()); return Collections.unmodifiableSet(names); } } 
+2
source

Well, thatโ€™s what I came up with. We did not compile or test it, so there are no guarantees here

 ArrayList<String> getQueryParamNames(String input) { ArrayList<String> result = new ArrayList<String>(); //If its everything after the ? then up to the first = is the first parameter int start = 0; int end = input.indexOf("="); if (end == -1) return null; //No parameters in string while (end != -1) { result.Add(input.substring(start, end)); //May need to do end - 1 to remove the = //Look for next parameter, again may need to add 1 to this result to get rid of the & start = input.indexOf("&", end); if (start == -1) //No more parameters break; //If you want to grab the values you can do so here by doing //input.substring(end, start); end = input.indexOf("=", start); } return result; } 

I wrote this late at night without testing it, so you will have to adjust some calls by adding or subtracting 1. Also, I may have forgotten the exact syntax for adding to the List . I think commenting on any mistakes for others to see, but this is a common sense. I have a feeling that I forgot somewhere ; .

EDIT: set the result to a new ArrayList instead of LinkList as suggested below

+1
source

All Articles