1

I want to send JSON from Android to the server using HTTP (POST).

But stop at the following line:

OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());

I use a thread for HTTP, and I added the following manifest:

<uses-permission android:name="android.permission.INTERNET" />

But the results did not change.

public class MainActivity extends AppCompatActivity {

    private Handler handler = new Handler();
    private String PostUrl = "http://localhost:3000";
    private String JSON = "{\"test\":\"100\"}";

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

    public void callPost()  {

        handler.post(new Runnable() {
            @Override
            public void run() {

                HttpURLConnection con = null;

                try{
                    URL url = new URL(PostUrl);
                    con = (HttpURLConnection) url.openConnection();
                    con.setRequestMethod("POST");
                    con.setDoOutput(true);
                    con.setRequestProperty("Content-Type","application/JSON; charset=utf-8");

                    Log.d("debug", "----- All right here -----");
                    OutputStreamWriter out = new 
OutputStreamWriter(con.getOutputStream());
                    Log.d("debug", "----- This message is not displayed -----");
                    out.write(JSON);
                    out.flush();
                    con.connect();

                } catch (Exception e){
                }
            }
        });
    }
}

There is no error, and only "----- All right here -----" is displayed.

gyagyaw6
  • 25
  • 4
  • 2
    `localhost:3000` points to the current device unless explicitly changed to point to a remote host. And to view the stack trace use `e.printStackTrace();` – Madhan Varadhodiyil Jun 13 '19 at 15:01
  • Thank you for your quick response. I changed "http://localhost:3000" to IP address of the server, but this situation is not changed. And when I tried e.printStackTrace(); , "android.os.NetworkOnMainThreadException" was displayed. – gyagyaw6 Jun 13 '19 at 15:19
  • [This](https://stackoverflow.com/questions/6343166/how-do-i-fix-android-os-networkonmainthreadexception) Might help you solve it – Madhan Varadhodiyil Jun 13 '19 at 15:23

2 Answers2

0

Updated Answer Verify that you've implemented below points and then use the code at the end which will work for you.

1. Use IP Address:

you can't use localhost in emulator because emulator refers local host to itself not to your laptop. Instead use IP address of your laptop i.e http://100.100.10.1:3000. Read more here.

2. Cleartext Issue:

you need to add your server URL (IP address in your case) in cleartext network config. for this create file res/xml/network_security_config.xml and add your IP address instead of Ip.Adress.here.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">Ip.Adress.here</domain>
    </domain-config>
</network-security-config>

Then add this file inside application tag manifest by android:networkSecurityConfig="@xml/network_security_config"

Your application tag in manifest will looks like this

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:networkSecurityConfig="@xml/network_security_config"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

Read more here.

3. Network in main thread

You will get Network in main thread issue. Since Network calls should be in background for that use Async Task. Below code is working fine for me just replace your.ip.address.here with your IP Address.

public class MainActivity extends AppCompatActivity {

private String PostUrl = "http://your.ip.address.here:3000";
private String JSON = "{\"test\":\"100\"}";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    new PostTask().execute();
}

class PostTask extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... voids) {
        HttpURLConnection con = null;

        try {
            URL url = new URL(PostUrl);
            con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setRequestProperty("Content-Type", "application/JSON; charset=utf-8");

            Log.d("debug", "----- All right here -----");
            OutputStream os = con.getOutputStream();
            Log.d("debug", "----- This message is not displayed -----");
            os.write(JSON.getBytes("UTF-8"));
            os.close();

            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
            StringBuilder response = new StringBuilder();
            String responseLine = null;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
            return response.toString();

        } catch (Exception e) {
            return e.getMessage();
        }
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        if (s!=null) {
            System.out.println(s);
        } else {
            System.out.println("Result not found");
        }
    }
}

}

Good Luck. If still issue there try post the result of System.out from logcat.

Community
  • 1
  • 1
Mureed Hussain
  • 2,745
  • 2
  • 18
  • 22
0

Move the con.connect() line just after the con.setRequestProperty line and close the OutputStreamWriter after calling the flush method.

If you get a NetworkOnMainThreadException it's because you can't make network calls in main thread so you need to use AsyncTask.

iperezmel78
  • 415
  • 5
  • 20