1

I'm trying to send String to the server, but I'm having problems with it.

This is my method.

ppublic void intervalPost(View view) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://requestb.in/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        PostInterface service = retrofit.create(PostInterface.class);
        Call<ResponseBody> call = service.postTime(time2);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                Log.d("Postavke", "Reached onResponse");
                if (!response.isSuccess()) {
                    Log.d("Postavke", "No Success");
                }

            }

            @Override
            public void onFailure(Call<ResponseBody> call,Throwable t) {
                // Toast for the moment
                // Appropriate error handling code should be present here
                Toast.makeText(Postavke.this, "Failed !", Toast.LENGTH_LONG).show();
            }
        });
}

And interface:

public interface PostInterface {
@FormUrlEncoded
@POST("/1b2bqxl1")
Call<ResponseBody> postTime(@Field("interval") String time);

}

I'm getting string time2 from spinner:

spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            String label = spinner.getSelectedItem().toString();
            tokens = new StringTokenizer(label, " ");
            time = tokens.nextToken().trim();
            timeConvert = Integer.parseInt(time);
            if (timeConvert == 1 || timeConvert == 2 || timeConvert == 3 || timeConvert == 6 || timeConvert == 12)
                timeConvert = timeConvert * 60;
            time2 = String.valueOf(timeConvert);
        }

The idea is when you chose interval in spinner, button click should send time2 to server.

When I run the application I'm getting this error: java.lang.IllegalStateException: Could not execute method for android:onClick

My question is how to fix this error and also if you could check post method, I'm not sure if it'll work.

Layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg"
android:orientation="vertical"
>


<TextView
    android:text="@string/odaberi_interval"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/odabirintervala"
    android:textSize="20sp"
    android:layout_marginTop="30dp"
    android:layout_marginLeft="30dp"
    android:layout_marginRight="20dp"
    android:textColor="#148299"
    />

<Spinner
    android:id="@+id/spinner"
    android:layout_width="125dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="33dp"
    android:layout_toRightOf="@id/odabirintervala"
    android:drawSelectorOnTop="true"
    ></Spinner>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Promijeni interval"
    android:layout_below="@id/spinner"
    android:layout_marginTop="20dp"
    android:layout_centerHorizontal="true"
    android:onClick="intervalPost"
    android:id="@+id/intervalButton"
    />
</RelativeLayout>
mustangws
  • 69
  • 1
  • 9

2 Answers2

1

From the error you get the message "@Field parameters can only be used with form encoding."

It means, you need to put @FormUrlEncoded on your interface

@FormUrlEncoded
@POST("/1gics1o1")
Call<Response> postTime(@Field("interval") String time);

The error "Caused by: android.os.NetworkOnMainThreadException" means your network process is too long being in the main thread, because you are not using asynchronous method. Try to change

  call.execute();

with enqueue method

  call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            Log.d("Postavke", "Reached onResponse");
            if (!response.isSuccess()) {
                Log.d("Postavke", "No Success");
            }else{
                Log.d("Postavke", "responsebody  => "+ response.body().toString());
            }


        }

        @Override
        public void onFailure(Call<ResponseBody> call,Throwable t) {
            // Toast for the moment
            // Appropriate error handling code should be present here
            Toast.makeText(Postavke.this, "Failed !", Toast.LENGTH_LONG).show();
        }
    });
Faruk
  • 5,438
  • 3
  • 30
  • 46
  • thank you, for the first time there's no errors, i'm getting Reached onResponse, i'll change the code in question – mustangws Jan 16 '17 at 08:00
  • now, is there any way to test it (to see if time2 was sent)? – mustangws Jan 16 '17 at 08:01
  • 1
    if the response body is ok, then the parameter should be already sent. And by the way if you see someone answer, is correctly answer your question, you should mark it as accepted answer. Or atleast put up some vote, if you have enough reputation of course. – Faruk Jan 16 '17 at 08:20
0

You do retrofit request on main thread. Try to use AsyncTask or RxAndroid or Volley.

Also you can try this answer: Does Retrofit make network calls on main thread?

Edit. Example:

public void intervalPost(View view) {
  try {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://requestb.in/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    PostInterface service = retrofit
      .create(PostInterface.class);
      .postTime(time2)
      .enqueue(new Callback<Response>() {
                @Override
                public void onResponse(Call<Response> call, Response<Response> response) {
                  // code here
                }

                @Override
                public void onFailure(Call<Response> call, Throwable t) {
                  // code here
                }
            });
  } catch (IOException Ex) {
  }
}
Community
  • 1
  • 1
Vüsal
  • 2,580
  • 1
  • 12
  • 31
  • thanks for the answer, but i still don't what to do, what should i change if i want to use retrofit and how would my method look using voley? i'm new to android developing, this is my first using retrofit and my first app which is not just buttons that do something – mustangws Jan 16 '17 at 05:48
  • Please **do not follow the above code example**.. Retrofit has an `enqueue` method for making asynchronous requests – ashkhn Jan 16 '17 at 06:30