AMart
AMart

Reputation: 1

HttpURLConnection working in Java but not android

We've been trying to send a POST request to a node.js server in an android app. Because the old apache dependencies are deprecated (and I can't seem to access them - I've tried) we've been using the HttpURLConnection classes. We've coded a class in java that works as just a standalone class (Request.java) but when incorperated in the android program, it throws an error every time and when trying to get the message of the error, it just returns null.

Request.java

package andrewmmattb.beacongame;

/**
 * Created by matt on 05/03/2016.
 */

import java.net.HttpURLConnection;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.URL;

public class Request {

    public static void main(String[] args) throws Exception {
        Request http = new Request();

        System.out.println("POST");
        http.sendPost("{\"username\": \"matt\",\"newPoints\":5}");
    }

    public static void sendPost(String json) throws Exception {

        String url = "http://ec2-54-187-69-193.us-west-2.compute.amazonaws.com/points";
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        //add reuqest header
        con.setRequestMethod("POST");
        con.setRequestProperty("User-Agent", "");
        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        con.setRequestProperty("Content-Type", "application/json");

        String urlParameters = "";

        // Send post request
        con.setDoOutput(true);
        DataOutputStream wr = new      DataOutputStream(con.getOutputStream());
        wr.writeBytes(json);
        wr.flush();
        wr.close();

        int responseCode = con.getResponseCode();
        System.out.println("\nSending 'POST' request to URL : " + url);
        System.out.println("Post parameters : " + urlParameters);
        System.out.println("Response Code : " + responseCode);

        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        //print result
        System.out.println(response.toString());
    }
}

GameActivity.java

package andrewmmattb.beacongame;

import android.app.Activity;
import android.app.DownloadManager;
import android.content.Intent;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.util.Base64;
import android.util.JsonWriter;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

import org.json.*;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class GameActivity extends Activity {

String username;
String serverPath = "THE PATH TO THE SERVER";

int score = 0;
int prevScore = 0;

TextView usernameTextView;
TextView scoreTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game);

    usernameTextView = (TextView)findViewById(R.id.textViewGameUsername);
    scoreTextView = (TextView)findViewById(R.id.textViewGameScore);

    Intent intent = getIntent();
    username = intent.getStringExtra("username");
    usernameTextView.setText(username);

    try {
        makeSeverPost();
    }
    catch (IOException e) {
        Toast.makeText(GameActivity.this,"There was an IO error, called after function call (line 56)",Toast.LENGTH_LONG).show();
        e.printStackTrace();
    }
}

void makeSeverPost() throws IOException {
    // creates a map object with username and the additional points to the previous sent score
    Map<String,Object> values = new HashMap<String,Object>();
    values.put("username",username);
    values.put("newPoints",score-prevScore);
    // sets the previous score to equal the current score
    prevScore = score;

    // writes the map into a string in JSON format
    String jsonString = new JSONObject(values).toString();

    try {
        Request.sendPost(jsonString);
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("problem",""+e.getMessage());
    }
    }
}

There are many redundant dependancies due to all the other attempts to do this we've made.

Upvotes: 0

Views: 87

Answers (2)

Omkar
Omkar

Reputation: 1553

Here is more elaborated solution:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        usernameTextView = (TextView)findViewById(R.id.textViewGameUsername);
        scoreTextView = (TextView)findViewById(R.id.textViewGameScore);

        // creates a map object with username and the additional points to the previous sent score
        Map<String,Object> values = new HashMap<String,Object>();
        values.put("username",username);
        values.put("newPoints",score-prevScore);

        // writes the map into a string in JSON format
        String jsonString = new JSONObject(values).toString();
        String url = "http://ec2-54-187-69-193.us-west-2.compute.amazonaws.com/points";

        // executing AsyncTask with passing string parameters.
        ServerAsyncTask makeServerPost = new ServerAsyncTask();

        makeServerPost.execute(url, jsonString);
    }

    private class ServerAsyncTask extends AsyncTask<String, Void, JSONObject> {

        private final String TAG = ServerAsyncTask.class.getSimpleName();

        @Override
        protected JSONObject doInBackground(String... params) {
            JSONObject result = null;
            try {
                URL obj = new URL(params[0]);                       // added url

                HttpURLConnection con = (HttpURLConnection) obj.openConnection();

                //add reuqest header
                con.setRequestMethod("POST");
                con.setRequestProperty("User-Agent", "");
                con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
                con.setRequestProperty("Content-Type", "application/json");

                String urlParameters = "";

                // Send post request
                con.setDoOutput(true);
                DataOutputStream wr = new DataOutputStream(con.getOutputStream());
                wr.writeBytes(params[1]);                       // Added json
                wr.flush();
                wr.close();

                int responseCode = con.getResponseCode();

                Log.i(TAG, "\nSending 'POST' request to URL : " + params[0]);
                Log.i(TAG, "Post parameters : " + urlParameters);
                Log.i(TAG, "Response Code : " + responseCode);

                // safer way to parse response
                if(responseCode == HttpURLConnection.HTTP_OK){

                    BufferedReader in = new BufferedReader(
                            new InputStreamReader(con.getInputStream()));
                    String inputLine;
                    StringBuilder response = new StringBuilder();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();

                    // print result
                    Log.i(TAG, response.toString());

                    result = new JSONObject(response.toString());
                }

            } catch (IOException | JSONException e) {
                e.printStackTrace();
            }

            return result;
        }

        @Override
        protected void onPostExecute(JSONObject jsonObject) {
            super.onPostExecute(jsonObject);
            /* You get response jsonObject here,
            you can now update your UI here*/

            // Example update your score.
            try {

                String score = (String) jsonObject.get("score");

                scoreTextView.setText(score);

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

Upvotes: 0

meda
meda

Reputation: 45500

In android network on main thread are not allowed.

You have to call this method from an AsyncTask.


Example:

class MakeSeverPostTask extends AsyncTask<Void, String, JSONObject>
{
    Map<String,Object> params;

    public MakeSeverPostTask(Map<String,Object> params){
      this.params = params;
    }

    protected JSONObject doInBackground(Void... v)
    {
        String jsonString = new JSONObject(this.params).toString();
        return Request.sendPost(jsonString);
    }

    protected void onPostExecute(JSONObject result)
    {

    }
}

Usage:

Map<String,Object> values = new HashMap<String,Object>();
values.put("username",username);
values.put("newPoints",score-prevScore);

new MakeSeverPostTask(values).execute();

Upvotes: 4

Related Questions