1

I am newbie to Android application development. I am developing a shopping cart application. I am trying to call a web-service in GET method using android. But how can I do that? What I tried is here. But it gives me an error PostResponseAsyncTask: 405 Method not allowed. How to fix that? Anybody can help me? Thanks in advance.

MainFragment Class

public class MainFragment extends Fragment implements AsyncResponse, AdapterView.OnItemClickListener{
    public static final String PREFS = "prefFile";
    final String LOG = "MainFragment";

    final static String url = "http://10.0.3.2:8080/WebService/rest/get/products";

    private ArrayList<Products> productList;
    private ListView lv;
    FunDapter<Products> adapter;

    View view;


    public MainFragment() {

    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        view = inflater.inflate(R.layout.fragment_main, container, false);

        ImageLoader.getInstance().init(UILConfig.config(MainFragment.this.getActivity()));

        PostResponseAsyncTask taskRead = new PostResponseAsyncTask(MainFragment.this.getActivity(), this);
        taskRead.execute(url);


        return view;
    }

    @Override
    public void processFinish(String s) {

        productList = new JsonConverter<Products>().toArrayList(s, Products.class);

        BindDictionary dic = new BindDictionary();

        dic.addStringField(R.id.tvName, new StringExtractor<Products>() {
            @Override
            public String getStringValue(Products item, int position) {
                return item.name;
            }
        });

        dic.addStringField(R.id.tvDesc, new StringExtractor<Products>() {
            @Override
            public String getStringValue(Products item, int position) {
                return item.description;
            }
        }).visibilityIfNull(View.GONE);

        dic.addStringField(R.id.tvPrice, new StringExtractor<Products>() {
            @Override
            public String getStringValue(Products item, int position) {
                return ""+item.price;
            }
        });

        dic.addDynamicImageField(R.id.ivImage, new StringExtractor<Products>() {
            @Override
            public String getStringValue(Products item, int position) {
                return item.pic;
            }
        }, new DynamicImageLoader() {
            @Override
            public void loadImage(String url, ImageView img) {
                //Set image
                ImageLoader.getInstance().displayImage(url, img);
            }
        });

        dic.addBaseField(R.id.btnCart).onClick(new ItemClickListener() {
        });

        adapter = new FunDapter<>(MainFragment.this.getActivity(), productList, R.layout.product_row, dic);
        lv = (ListView)view.findViewById(R.id.lvProduct);
        lv.setAdapter(adapter);

        lv.setOnItemClickListener(this);

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

    }
}
  • it seems like there is a problem on server side. as 405 error code suggest that "the request method is known by the server but has been disabled and cannot be used." – Waqar UlHaq Apr 17 '18 at 05:12
  • @WaqarUlHaq it's not server side problem. it's his request method problem. – noman404 Apr 17 '18 at 05:14
  • I think best way to handle network api used retrofit . and also check data coming to define url and define 405 error –  Apr 21 '18 at 05:54

4 Answers4

1

Try using some Libraries such as Retrofit, Volley, Loopj etc for Asynchrous GET or POST HTTP Requests.

For Implementing dynamic image from url or file path use Piccasso or Glide Library.

Here are some examples and documentation on these libraries

Loopj

  1. Loopj official Documentation and Example

Retrofit

  1. Retrofit official Documentation By SquareUp
  2. Retrofit Tutorial from JournelDev

Volley

  1. Volley official Documenation By Android Developers
  2. Volley tutorial from Journeldev

DYNAMIC IMAGE HANDLING

Picasso

Android Picasso Library

Glide

Glide Library for Android

Hope these may help you

Example with Retrofit

build.gradle(app)

        implementation 'com.google.code.gson:gson:2.6.2'
        implementation 'com.squareup.retrofit2:retrofit:2.0.2'
        implementation 'com.squareup.retrofit2:converter-gson:2.0.2'

MainFragment

public class MainFragment extends Fragment {

    public static final String PREFS = "prefFile";
    final String LOG = "MainFragment";

    private ArrayList<Product> productList;
    private ListView lv;
    FunDapter adapter;
    private ApiInterface apiInterface;

    View view;


    public MainFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_main, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);


        lv = (ListView) view.findViewById(R.id.lvProduct);
        apiInterface = ApiClient.getRetrofitApiClient().create(ApiInterface.class);

        productList  = new ArrayList<Product>();

        adapter= new FunDapter (getContext(), 0, productList);
        lv.setAdapter(adapter);

        getProduct();


    }

    private void getProduct() {

        Call<List<Product>> call = apiInterface.getProducts();
        call.enqueue(new Callback<List<Product>>() {
            @Override
            public void onResponse(Call<List<Product>> call, Response<List<Product>> response) {

                List<Product> products= response.body();
                Log.d("TEST", "onResponse: "+response.body().size());
                if(products.size()>0){
                    productList.addAll(products);
                }

                adapter.notifyDataSetChanged();
            }

            @Override
            public void onFailure(Call<List<Product>> call, Throwable t) {

            }
        });

    }
}

ApiClient

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by android on 3/10/17.
 */
class ApiClient {

        public static final String BASE_URL = "http://10.0.2.2:8080/WebService/rest/";

        public static Retrofit retrofit = null;

        public static Retrofit getRetrofitApiClient() {
            if (retrofit == null) {
                retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
            }

            return retrofit;
        }
    }

ApiInterface

import java.util.List;

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;


public interface ApiInterface {

    @GET("get/products")
    Call<List<Product>> getProducts();

}

Products

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

class Product {

    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("ram")
    @Expose
    private String ram;
    @SerializedName("price")
    @Expose
    private String price;
    @SerializedName("pic")
    @Expose
    private String pic;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRam() {
        return ram;
    }

    public void setRam(String ram) {
        this.ram = ram;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic;
    }

}

FunDapter

class FunDapter extends ArrayAdapter<Product> {

    private Context context;
    private ArrayList<Product> objects;
    private static LayoutInflater inflater = null;

    public FunDapter(@NonNull Context context, int resource, @NonNull ArrayList<Product> objects) {
        super(context, resource, objects);
        try {
            this.context = context;
            this.objects = objects;

            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        } catch (Exception e) {

        }
    }
    public int getCount() {
        return objects.size();
    }

    public Product getItem(Product position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public static class ViewHolder {
        public TextView display_name;
        public TextView display_number;
        public ImageView image;

    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View vi = convertView;
        final ViewHolder holder;
        try {
            if (convertView == null) {
                vi = inflater.inflate(R.layout.singlerow_mylistview, null);
                holder = new ViewHolder();

                holder.display_name = (TextView) vi.findViewById(R.id.title_listview);
                holder.display_number = (TextView) vi.findViewById(R.id.subtitle_listview);
                holder.image = (ImageView) vi.findViewById(R.id.icon_listview);



                vi.setTag(holder);
            } else {
                holder = (ViewHolder) vi.getTag();
            }



            holder.display_name.setText(objects.get(position).getName());
            holder.display_number.setText(objects.get(position).getPrice());

            Picasso.with(context)
                    .load(objects.get(position).getPic())
                    .resize(50, 50)
                    .centerCrop()
                    .into(holder.image);


        } catch (Exception e) {


        }
        return vi;
    }
}

Dont forget to add <uses-permission android:name="android.permission.INTERNET" /> in Manifest

Tomin B Azhakathu
  • 2,656
  • 1
  • 19
  • 28
0

Your are performing a POST request by doing this PostResponseAsyncTask that's why you're getting 405 Method not allowed. If that endpoint accept GET then do a GET request. Better you should use Volley or Retrofit library for network communication.

noman404
  • 928
  • 1
  • 8
  • 23
  • How can I send a GET request? I need to sync response data with this fragment. So how can I send GET request Sir? If you can give me the code It will help me as I am a newbie in android development. –  Apr 17 '18 at 05:16
  • Try this example https://examples.javacodegeeks.com/android/core/android-volley-example/ If you got helped don't forget to accept my answer or vote up :) – noman404 Apr 17 '18 at 05:19
  • Can you tell me how can I add that to this class and fetch data in ProcessFinish method. –  Apr 17 '18 at 05:31
  • So far i don't find and possible way to do GET request with your current library – noman404 Apr 17 '18 at 07:08
  • If I do with that volley library that you provided. How can i add that code to this MainFragment and fetch data in ProcessFinish method? It is a big help Sir. –  Apr 17 '18 at 07:26
0

Try using retrofit, first add the following dependencies

compile 'com.squareup.retrofit2:retrofit:2.3.0'

compile 'com.squareup.retrofit2:converter-gson:2.3.0'

First of all try to find out what type of json response you are getting from the backend- It can be an array response/an object response.

Json array responses are of the form [{"field1":"value1",..},{"field2":"value2",..}..] whereas object responses are of the form {"field1":"value1",..}

You may check this tutorial to have an idea about parsing json responses

If you check the backend and figure out the response, then you can generate a model class using the same from http://www.jsonschema2pojo.org/

Case 1 : Suppose you have a json object response({"field1":"value1",..})

First create a model class using your response from jsonschema2pojo as mentioned above, then call it like following(suppose YourObjectModel is your model class)

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://10.0.3.2:8080/WebService/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    SampleInterface request = retrofit.create(SampleInterface.class);
    Call<YourObjectModel> call1=request.getResponse();
    call1.enqueue(new Callback<YourObjectModel>() {
        @Override
        public void onResponse(Call<YourObjectModel> call, Response<YourObjectModel> response) {
            Toast.makeText(MainActivity.this,response.body().toString(),Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onFailure(Call<YourObjectModel> call, Throwable t) {
            Toast.makeText(MainActivity.this,t.toString(),Toast.LENGTH_SHORT).show();
        }

    });

SampleInterface.java

public interface SampleInterface {
@GET("rest/get/products")
Call<YourObjectModel> getResponse();
}

Case 2 : Suppose you have a json array response([{"field1":"value1",..},{"field2":"value2",..}..])

First create a model class like in above case and since it is an array response you might need to get the response as a list so change all the call method from Call<YourObjectModel> to Call<List<YourArrayModel>>

where YourArrayModel is your model class for json array response

Navneet Krishna
  • 5,009
  • 5
  • 25
  • 44
0

try this examples it's very easy this examples must help you.

  1. asynctask-callback
  2. volley-callback
yathavan
  • 183
  • 1
  • 14