Я использую библиотеку Google Volley для своего проекта приложения, который нацелен на минимальный уровень API 14. Итак, библиотека Volley использует HttpURLConnection в качестве NetworkClient.
Поэтому не должно быть никаких проблем, связанных с удалением Apache HTTPClient. Тем не менее, я выполнил конфигурацию, необходимую для 6.0 Sdk, т.е. compileSdkVersion 23, build-tool-version 23.0.1 и build:gradle:1.3.1 'и даже попытался добавить useLibrary 'org.apache.http.legacy'. Обновил то же самое для проекта библиотеки Volley в моем приложении.
Недавно я попытался запустить свое приложение на Android 6.0 (MarshMallow), мой проект компилируется и запускается. Но те запросы, которые требуют заголовков аутентификации, не работают в MarshMallow:
BasicNetwork.performRequest: Неожиданный код ответа 401 com.android.volley.AuthFailureError
Однако то же самое работает на всех уровнях API ниже 23.
Я много раз проверял заголовки. Как ни странно, те запросы, которые не требуют аутентификации, дают ответ с 200 OK.
Прямо сейчас я совершенно не знаю, что нарушает запросы, кто-нибудь знает, что изменилось в новой версии, что запрос HttpURLConnection не работает только для уровня API 23? Кто-нибудь еще использует Volley и сталкивается с подобной проблемой?
Вот мой класс CustomRequest
public class CustomRequest extends Request<Void> {
int id, cmd;
Map<String, String> params;
BaseModel model;
public CustomRequest(int method, int cmd, String url, Map<String, String> params, int id, BaseModel model) {
super(method, url, null);
this.id = id;
this.cmd = cmd;
this.params = params;
this.model = model;
if (method == Method.GET) {
setUrl(buildUrlForGetRequest(url));
}
Log.v("Volley", "Making request to: " + getUrl());
}
private String buildUrlForGetRequest(String url) {
if (params == null || params.size() == 0) return url;
StringBuilder newUrl = new StringBuilder(url);
Set<Entry<String, String>> paramPairs = params.entrySet();
Iterator<Entry<String, String>> iter = paramPairs.iterator();
newUrl.append("?");
while (iter.hasNext()) {
Entry<String, String> param = iter.next();
newUrl
.append(param.getKey())
.append("=")
.append(param.getValue());
if (iter.hasNext()) newUrl.append("&");
}
return newUrl.toString();
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("X-Api-Version", Contract.API_VERSION);
headers.put("X-Client", "android");
String accessToken = APP.getInstance().getToken();
if (!accessToken.equals("")) {
headers.put("Authorization", "Bearer " + accessToken);
}
return headers;
}
@Override
protected Response<Void> parseNetworkResponse(NetworkResponse response) {
Exception ex;
try {
String jsonString = new String(
response.data, HttpHeaderParser.parseCharset(response.headers));
JsonNode json = new ObjectMapper().readTree(jsonString);
if (model != null) model.parse(id, json);
EventBus.getDefault().post(new EventResponse(cmd, true, null));
return Response.success(null, HttpHeaderParser.parseCacheHeaders(response)); //Doesn't return anything. BaseModel.parse() does all the storage work.
} catch (NoMoreDataException e) {
ex = e;
EventBus.getDefault().post(new NoMoreDataModel(cmd, e));
EventBus.getDefault().post(new EventResponse(cmd, false, null));
return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
} catch (Exception e) {
ex = e;
Log.e("CustomRequest", Log.getStackTraceString(e));
String message = APP.getInstance().getString(R.string.failedRequest);
if (!TextUtils.isEmpty(e.getMessage()))
message = e.getMessage();
EventBus.getDefault().post(new ErrorEventModel(cmd, message, e));
return Response.error(new ParseError(ex));
}
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}
@Override
protected void deliverResponse(Void response) {
Log.v("Volley", "Delivering result: " + getUrl());
}
@Override
public void deliverError(VolleyError error) {
Log.e("CustomRequest", "Delivering error: Request=" + getUrl() + " | Error=" + error.toString());
String message = APP.getInstance().getString(R.string.failedRequest);
EventBus.getDefault().post(new ErrorEventModel(cmd, message, error));
}
}
Единственное различие, которое я нашел между Api 23 и другими, — это HostNameVerifier. Для уровня API 23: com.android.okhttp.internal.tls.OkHostnameVerifier Для уровня API ‹23: javax.net.ssl.DefaultHostnameVerifier.
map.putAll(request.getHeaders()); map.putAll(additionalHeaders);внутриperformRequestHurlStack.java - person BNK   schedule 29.10.2015