Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lvl library and android marshmallow

Lvl library doesn't compile anymore on Android Marshmallow due to the lack apache stuff removed. You can add useLibrary 'org.apache.http.legacy but it's only a temporary workaround. The problem is this method:

private Map<String, String> decodeExtras(String extras) {
  Map<String, String> results = new HashMap<String, String>();
  try {
     URI rawExtras = new URI("?" + extras);
     List<NameValuePair> extraList = URLEncodedUtils.parse(rawExtras, "UTF-8");
     for (NameValuePair item : extraList) {
        results.put(item.getName(), item.getValue());
     }

  } catch (URISyntaxException ignored) {

  }
  return results;
}

NameValuePair and URLEncodedUtils are not found.

What is the new "way"? How can I replace this call with new code compliant with the new Android version?

like image 902
greywolf82 Avatar asked Aug 20 '15 09:08

greywolf82


People also ask

What API level is marshmallow?

Marshmallow (Android version 6.0, API Level 23) is the latest release of Android, and includes a set of new APIs for developers to use.

When did Android Marshmallow come out?

Android Marshmallow (codenamed Android M during development) is the sixth major version of the Android operating system and the 13th version of Android. First released as a beta build on May 28, 2015, it was officially released on October 5, 2015, with the Nexus devices being the first to receive the update.

Is Android 6.0 still supported?

Android 6.0 was released in 2015, and we ended support to provide the latest and greatest features in our app using the more recent Android versions. As of September 2019, Google no longer supports Android 6.0, and there will be no new security updates. How can I get more information?


4 Answers

I wrote my own class looking at the original code as temporary workaround:

public class URLUtils {
    private static final String PARAMETER_SEPARATOR = "&";
    private static final String NAME_VALUE_SEPARATOR = "=";
    private static final String DEFAULT_CONTENT_CHARSET = "ISO-8859-1";

    public static List<Item> parse(final URI uri, final String encoding) {
        List<Item> result = Collections.emptyList();
        final String query = uri.getRawQuery();
        if (query != null && query.length() > 0) {
            result = new ArrayList<>();
            parse(result, new Scanner(query), encoding);
        }
        return result;
    }

    public static void parse(final List<Item> parameters, final Scanner scanner, final String encoding) {
        scanner.useDelimiter(PARAMETER_SEPARATOR);
        while (scanner.hasNext()) {
            final String[] nameValue = scanner.next().split(NAME_VALUE_SEPARATOR);
            if (nameValue.length == 0 || nameValue.length > 2)
                throw new IllegalArgumentException("bad parameter");

            final String name = decode(nameValue[0], encoding);
            String value = null;
            if (nameValue.length == 2)
                value = decode(nameValue[1], encoding);
            parameters.add(new Item(name, value));
        }
    }


    private static String decode (final String content, final String encoding) {
        try {
            return URLDecoder.decode(content, encoding != null ? encoding : DEFAULT_CONTENT_CHARSET);
        } catch (UnsupportedEncodingException problem) {
            throw new IllegalArgumentException(problem);
        }
    }
}

public class Item {
    private String name;
    private String value;

    public Item(String n, String v) {
        name = n;
        value = v;
    }

    public String getName() {
        return name;
    }

    public String getValue() {
        return value;
    }
}
like image 79
greywolf82 Avatar answered Oct 02 '22 03:10

greywolf82


Methods named decodeExtras() show up in two places in the LVL, and their code differs. No need to come up with verbose custom code - android.net.Uri offers similar functionality, and the replacements below work for API level 11 (Honeycomb) and above.

For APKExpansionPolicy:

private Map<String, String> decodeExtras(String extras) {
    Map<String, String> results = new HashMap<>();
    Uri uri = new Uri.Builder().encodedQuery(extras).build();
    Set<String> parameterNames = uri.getQueryParameterNames();
    for (String parameterName : parameterNames) {
        List<String> values = uri.getQueryParameters(parameterName);
        int count = values.size();
        if (count >= 1) {
            results.put(parameterName, values.get(0));
            for (int i = 1; i < count; ++i) {
                results.put(parameterName + i, values.get(i));
            }
        }
    }
    return results;
}

For ServerManagedPolicy:

private Map<String, String> decodeExtras(String extras) {
    Map<String, String> results = new HashMap<>();
    Uri uri = new Uri.Builder().encodedQuery(extras).build();
    Set<String> parameterNames = uri.getQueryParameterNames();
    for (String parameterName : parameterNames) {
        results.put(parameterName, uri.getQueryParameter(parameterName));
    }
    return results;
}
like image 31
Uli Avatar answered Sep 30 '22 03:09

Uli


my quick and dirty solution was to replace the legacy code with

    Uri uri = Uri.parse("?" + extras);
    for (String itemName : uri.getQueryParameterNames())
        results.put(itemName, uri.getQueryParameter(itemName));
like image 40
materemias Avatar answered Sep 30 '22 03:09

materemias


I found updated version at https://github.com/google/play-licensing, the issue is fixed with URIQueryDecoder

like image 44
alders Avatar answered Oct 01 '22 03:10

alders