I have found on Stack Overflow someone complaining about Java’s JsonObjectRequest not working
(link)
I have tried to use instead an alternate method called StringRequest() and it works. Maybe that I was incorrectly using JsonObjectRequest, I don’t know.
Anyway, I put below the code that is working for me. If that can help someone else!
I suspect that my implementation of JsonObjectRequest was incorrectly sending the JSON file so the server didn’t find what it is expecting and displayed this message about device_id not matching regex. That’s the case also if you send an empty JSON file. That would be nice if the server was able to display a more explicit message when a mandatory field is not found.
private void addEndDeviceToIdentityServer() {
JSONObject dataObject = new JSONObject();
// Prepare JSON data
try {
JSONObject idsObject = new JSONObject();
idsObject.put("dev_eui", mDevEUI);
idsObject.put("join_eui", mJoinEUI);
idsObject.put("device_id", mDeviceId);
JSONObject endDeviceObject = new JSONObject();
endDeviceObject.put("ids", idsObject);
endDeviceObject.put("network_server_address", TTN_SERVER);
endDeviceObject.put("application_server_address", TTN_SERVER);
endDeviceObject.put("join_server_address", TTN_SERVER);
JSONArray paths = new JSONArray();
paths.put("network_server_address");
paths.put("application_server_address");
paths.put("join_server_address");
JSONObject fieldMaskObject = new JSONObject();
fieldMaskObject.put("paths", paths);
dataObject.put("end_device", endDeviceObject);
dataObject.put("field_mask", fieldMaskObject);
} catch (JSONException e) {
e.printStackTrace();
return;
}
Log.w(TAG,"addEndDeviceToIdentityServer: " + dataObject);
mRequestQueue = Volley.newRequestQueue(this);
mRequestQueue.getCache().clear();
String url = TTN_URL + "/applications/" + mApplicationId + "/devices";
StringRequest strRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
@Override
public void onResponse(String response)
{
Log.d(TAG, response);
}
},
new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error)
{
if (error == null || error.networkResponse == null) {
return;
}
Log.e(TAG, "onErrorResponse: " + error.getMessage());
String body;
//get status code here
final String statusCode = String.valueOf(error.networkResponse.statusCode);
//get response body and parse with appropriate encoding
try {
body = new String(error.networkResponse.data,"UTF-8");
Log.e(TAG, "body: " + body);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
})
{
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
final Map<String, String> headers = new HashMap<>();
headers.put("Centent-Type", "application/json");
headers.put("Authorization", "Bearer " + mMyAppApiKey);
return headers;
}
@Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
@Override
public byte[] getBody() throws AuthFailureError {
return dataObject.toString().getBytes(StandardCharsets.UTF_8);
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
strRequest.setShouldCache(false);
strRequest.setTag(TAG);
mRequestQueue.add(strRequest);
}