Error when trying to add an End Device from HTTP API

I have found on Stack Overflow someone complaining about Java’s JsonObjectRequest not working

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

            JSONObject fieldMaskObject = new JSONObject();
            fieldMaskObject.put("paths", paths);

            dataObject.put("end_device", endDeviceObject);
            dataObject.put("field_mask", fieldMaskObject);

        } catch (JSONException e) {

        Log.w(TAG,"addEndDeviceToIdentityServer: " + dataObject);

        mRequestQueue = Volley.newRequestQueue(this);

        String url = TTN_URL + "/applications/" + mApplicationId + "/devices";

        StringRequest strRequest = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>()
                    public void onResponse(String response)
                        Log.d(TAG, response);
                new Response.ErrorListener()
                    public void onErrorResponse(VolleyError error)
                        if (error == null || error.networkResponse == null) {
                        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(,"UTF-8");
                            Log.e(TAG, "body: " + body);
                        } catch (UnsupportedEncodingException e) {
            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;

            public String getBodyContentType() {
                return "application/json; charset=utf-8";

            public byte[] getBody() throws AuthFailureError {
                return dataObject.toString().getBytes(StandardCharsets.UTF_8);

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


1 Like

Sounds like my life all over, use apparently good library, finally figure out it has ‘issues’, use something else. Sometimes rinse & repeat.

If it’s empty, absolutely - you can submit the issue on GitHub and do the fix and submit a PR :wink: