-1

after some reading, I have settled for this base code for sending a POST request to a REST API:



    package com.theroom.TestProject;

    import android.app.Activity;
    //import android.content.Context;
    import android.os.Bundle;
    import android.telephony.TelephonyManager;
    import android.view.View;
    import android.widget.*;
    import org.apache.http.HttpResponse;
    import org.apache.http.HttpStatus;
    import org.apache.http.StatusLine;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.json.JSONObject;

    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.util.Comparator;

    public class TestActivity extends Activity {
        private EditText username=null;
        private EditText  password=null;
        private Button login;
        /**
         * Called when the activity is first created.
         */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

            Spinner spinner = (Spinner) findViewById(R.id.country_prefix);
            ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.country_codes, android.R.layout.simple_spinner_item);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            Comparator comparator = new CountryComparator();
            adapter.sort(comparator);
            spinner.setAdapter(adapter);
            TelephonyManager tMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    //        String mPhoneNumber = tMgr.getLine1Number();
            String CountryCode = tMgr.getSimCountryIso();
            CountryToPhonePrefix CP = new CountryToPhonePrefix();
            String PhoneCountryCode = CP.prefixFor(CountryCode.toUpperCase());
            Integer pos = adapter.getPosition(PhoneCountryCode);
            spinner.setSelection(pos);
            TextView PhoneNumberTV = (TextView) findViewById(R.id.login_Text);
    //        PhoneNumberTV.setText(PhoneCountryCode);
    //        this.getWindow().setBackgroundDrawable();
        }

        public void ToastPhoneNumber(View view) throws IOException {
            Toast toast = new Toast(getApplicationContext());
            TextView PhoneTV = (TextView) findViewById(R.id.login_Text);
            TelephonyManager tMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
            String CountryCode = tMgr.getSimCountryIso();
            CountryToPhonePrefix CP = new CountryToPhonePrefix();
            String PhoneCountryCode = CP.prefixFor(CountryCode.toUpperCase());

            HttpClient httpClient = new DefaultHttpClient();
            HttpPost PostRequest = new HttpPost("http://10.0.0.10:8000/api/v1/register");
            JSONObject data = new JSONObject();
            StringEntity se = new StringEntity(data.toString());
            PostRequest.setEntity(se);
            PostRequest.setHeader("Accept", "application/json");
            PostRequest.setHeader("Content-type", "application/json");
            HttpResponse response = httpClient.execute(PostRequest);

            StatusLine statusLine = response.getStatusLine();
            if(statusLine.getStatusCode() == HttpStatus.SC_OK){
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                response.getEntity().writeTo(out);
                String responseString = out.toString();
                out.close();
                toast.makeText(this, responseString, Toast.LENGTH_SHORT).show();
                //..more logic
            } else{
                //Closes the connection.
                response.getEntity().getContent().close();
                throw new IOException(statusLine.getReasonPhrase());
            }


        }
    }

When I run the code and click the button to activate the method ToastPhoneNumber (previously it was for that, now its supposed to ask API to send verification SMS), this is what I get in logcat:

02-04 23:11:04.492      820-820/com.theroom.TestProject V/Zygote﹕ Switching descriptor 34 to /dev/null
02-04 23:11:04.492      820-820/com.theroom.TestProject V/Zygote﹕ Switching descriptor 9 to /dev/null
02-04 23:11:04.492      820-820/com.theroom.TestProject D/dalvikvm﹕ Late-enabling CheckJNI
02-04 23:11:04.512      820-820/com.theroom.TestProject I/dalvikvm﹕ Enabling JNI app bug workarounds for target SDK version 10...
02-04 23:11:04.552      820-820/com.theroom.TestProject D/ActivityThread﹕ handleBindApplication:com.theroom.TestProject
02-04 23:11:04.552      820-820/com.theroom.TestProject D/ActivityThread﹕ setTargetHeapUtilization:0.75
02-04 23:11:04.552      820-820/com.theroom.TestProject D/ActivityThread﹕ setTargetHeapMinFree:2097152
02-04 23:11:04.802      820-820/com.theroom.TestProject I/Timeline﹕ Timeline: Activity_idle id: android.os.BinderProxy@418911a8 time:412893749
02-04 23:11:14.212      820-820/com.theroom.TestProject D/AndroidRuntime﹕ Shutting down VM
02-04 23:11:14.212      820-820/com.theroom.TestProject W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x415dedb8)
02-04 23:11:14.222      820-820/com.theroom.TestProject E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.theroom.TestProject, PID: 820
    java.lang.IllegalStateException: Could not execute method of the activity
            at android.view.View$1.onClick(View.java:3830)
            at android.view.View.performClick(View.java:4445)
            at android.view.View$PerformClick.run(View.java:18446)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5146)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.reflect.InvocationTargetException
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at android.view.View$1.onClick(View.java:3825)
            at android.view.View.performClick(View.java:4445)
            at android.view.View$PerformClick.run(View.java:18446)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5146)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: android.os.NetworkOnMainThreadException
            at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
            at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
            at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
            at libcore.io.IoBridge.connect(IoBridge.java:112)
            at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
            at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:460)
            at java.net.Socket.connect(Socket.java:833)
            at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
            at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
            at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
            at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
            at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
            at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
            at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
            at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
            at com.theroom.TestProject.TestActivity.ToastPhoneNumber(TestActivity.java:73)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at android.view.View$1.onClick(View.java:3825)
            at android.view.View.performClick(View.java:4445)
            at android.view.View$PerformClick.run(View.java:18446)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5146)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
            at dalvik.system.NativeStart.main(Native Method)

Can you help me figure out what is the problem? I find Java's exceptions very hard to diagnose.. its not as simple and intuitive to use as PHP for example :(

Carmageddon
  • 2,627
  • 4
  • 36
  • 56

1 Answers1

1
Caused by: android.os.NetworkOnMainThreadException

you're trying to make a network call from the Mainthread which is not allowed in android.

Create an Async Task from the method ToastPhoneNumber(View view)

MyTask task = new MyTask()
task.execute();

and the Task:

public class MyTask extends AsyncTask<String, Void, String> {
    MyTask() {}
    @Override
    protected Boolean doInBackground(String... params) {

        try {
           // REST CALL
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    protected void onPostExecute(final Boolean success) {
        if (success) {
            // handle post execute
        }
    }

    @Override
    protected void onCancelled() {

    }
}

This should work, hope this helps!

Markus
  • 1,565
  • 6
  • 26
  • 57
  • Thank you! despite its mark as Duplicate, beginner to Java can easily miss the hint of NetworkOnMainThreadException along DOZENS of error lines.. I simply didn't know what to look for exactly. – Carmageddon Feb 07 '15 at 22:05