Android.net.uri getQueryParameterNames () альтернатива

Я ищу альтернативный способ получить имена параметров запроса из android.net.Uri. GetQueryParameterNames () требует api level 11. Я хотел бы сделать то же самое для любого более низкого уровня api. Я смотрел getQuery (), который вернет все после «?» знак. Будет ли лучший способ сделать это, чтобы проанализировать эту строку и выполнить поиск всего до '=' и захватить это? Я просто не знаю, какие параметры запроса будут представлены каждый раз.

Единственная проблема с API <11 заключается в том, что этот метод не реализован. Я думаю, лучшая идея – изучить исходный код Android и использовать реализацию из API> = 11. Это должно обеспечить вам абсолютно идентичную функциональность даже в старых API.

Это один из 4.1.1, модифицированный, чтобы принять Uri в качестве параметра, поэтому вы можете использовать его сразу:

/** * 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); } 

Если вы хотите вникнуть в нее самостоятельно, вот исходный код:

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

Если у вас есть java.net.URI (или создайте его), вы можете использовать URLEncodedUtils.parse для получения параметров и значений как 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()); } 

Я согласен с foxter, что лучший выбор – получить код с новейшей версии Android и добавить в свою кодовую базу. Каждый раз, когда я сталкиваюсь с такими проблемами, я создаю метод абстрагирования идиосинкразий версий. Это происходит так:

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

Хорошо, вот что я придумал. Не компилировали или не тестировали его, поэтому никаких гарантий здесь нет

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

Я писал это поздно ночью, не тестируя его, поэтому вам придется корректировать некоторые вызовы путем добавления или вычитания 1. Также я, возможно, забыл точный синтаксис добавления в List . Я думаю, комментарий о каких-либо ошибках для других, но это общий смысл. У меня такое чувство, что я забыл ; где-то.

EDIT: установите результат в новый ArrayList вместо LinkList, как предлагается ниже