Cannot Parse JSON using retrofit and use listView - android

I am try to parse this Json array from this site NewsApi and display it in a listView.When I run the app nothing is displaying.Here is my code.What am doing wrong?.I have tried to debug the problem to no avail.
public class NewsApiClient {
public static String API_BASE_URL = "https://newsapi.org/v1/";
public static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
public static Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create()
);
public static Retrofit retrofit = builder.client(httpClient.build()).build();
NewsApiClient client = retrofit.create(NewsApiClient.class);
}
calling the endpoint?
public interface NewsApiInterface {
//endpoint
#GET("sources")
Call <SourcesResponse> getTechSources(
#Query("language") String language,
#Query("category") String category)
}
I am only using the name,description and category attributes.
public class Source {
#SerializedName("id")
public String id;
#SerializedName("name")
public String name;
#SerializedName("description")
public String description;
#SerializedName("url")
public String url;
#SerializedName("category")
public String category;
#SerializedName("language")
public String language;
#SerializedName("country")
public String country;
}
public class SourcesAdapter extends BaseAdapter {
Context context;
List<Source> sourceList;
public SourcesAdapter( Context context,List<Source> sourceList){
this.context = context;
this.sourceList = sourceList;
}
#Override
public int getCount() {
return sourceList.size();
}
#Override
public Object getItem(int position) {
return sourceList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
convertView = layoutInflater.inflate(R.layout.sources_list,null);
Source currentsource = sourceList.get(position);
TextView sourcesName = (TextView) convertView.findViewById(R.id.sources_name);
TextView sourcesDescription = (TextView) convertView.findViewById(R.id.sources_description);
TextView sourcesCategory = (TextView) convertView.findViewById(R.id.sources_category);
sourcesName.setText(currentsource.name);
sourcesDescription.setText(currentsource.description);
sourcesCategory.setText(currentsource.category);
return convertView;
}
}
public class SourcesFragment extends Fragment {
ListView listView;
public SourcesFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
//
//instance of the adapter to this listview
View view = inflater.inflate(R.layout.fragment_sources, container, false);
listView = (ListView)view.findViewById(R.id.list_view_sources) ;
getSources();
return view;
}
public void getSources(){
Retrofit retrofit = NewsApiClient.builder.build();
NewsApiInterface newsApiInterface = retrofit.create(NewsApiInterface.class);
Call<SourcesResponse> sourcesCall = newsApiInterface.getTechSources("en", "technology");
sourcesCall.enqueue(new Callback<SourcesResponse>() {
#Override
public void onResponse(Call<SourcesResponse> call, Response<SourcesResponse> response) {
List<Source> sources = response.body().sources;
SourcesAdapter sourcesAdapter = new SourcesAdapter(getContext(),sources);
listView.setAdapter(sourcesAdapter);
}
#Override
public void onFailure(Call<SourcesResponse> call, Throwable t) {
}
});
}
}
public class SourcesResponse {
#SerializedName("status")
public String status;
#SerializedName("sources")
public List<Source> sources;
}
I have created 3 fragments,the sources fragment is one of them.On the sources fragment i only want to display sources with technology.
Thank you in advance!

In your retrofit's onResponse callback method, you are accessing sources list like response.body().sources. Instead of this in the SourcesResponse , add a getter and setter for sources like this
public List<SourcesResponse> getSources() {
return sources;
}
public void setSources(List<SourcesResponse> sources) {
this.sources = sources;
}
Now go to your onResponse callback of retrofit and change
response.body().sources
to
response.body().getSources()

Related

Android: ListView Contains All Values in One Line

I have problem with displaying values using ListView.
I created adapter extends Base Adapter and Setter & Getter for listview, however it stores
all values in one line.
This is displayed screen
I would like to display like this
This is my adapter class
public class DataShow_List_Adapter extends BaseAdapter {
private LayoutInflater layoutInflater;
private ArrayList<TimeTable_ListItems> timeTable_listItems;
public DataShow_List_Adapter(Context context){
this.layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void SetTimeTable_listItems_adapter(ArrayList<TimeTable_ListItems> timeTable_listItems){
this.timeTable_listItems = timeTable_listItems;
}
#Override
public int getCount() {
return timeTable_listItems.size();
}
#Override
public Object getItem(int position) {
return timeTable_listItems.get(position);
}
#Override
public long getItemId(int position) {
return timeTable_listItems.get(position).getId();
}
#SuppressLint("ViewHolder")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = layoutInflater.inflate(R.layout.timetable_datashow_listview_row,parent,false);
((TextView)convertView.findViewById(R.id.Title_List)).setText(timeTable_listItems.get(position).getTitle());
((TextView)convertView.findViewById(R.id.SubTitle_List)).setText(timeTable_listItems.get(position).getSubTitle());
((TextView)convertView.findViewById(R.id.Start_Time_List)).setText(timeTable_listItems.get(position).getStart_Time());
((TextView)convertView.findViewById(R.id.End_Time_List)).setText(timeTable_listItems.get(position).getEnd_time());
return convertView;
}
}
This is Setter & Getter
public class TimeTable_ListItems {
private long id;
private String title;
private String subTitle;
private String start_Time;
private String end_time;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSubTitle() {
return subTitle;
}
public void setSubTitle(String subTitle) {
this.subTitle = subTitle;
}
public String getStart_Time() {
return start_Time;
}
public void setStart_Time(String start_Time) {
this.start_Time = start_Time;
}
public String getEnd_time() {
return end_time;
}
public void setEnd_time(String end_time) {
this.end_time = end_time;
}
}
This is method that returns String from Database
public String getTitle_database_mon(){
sqLiteDatabase = this.getReadableDatabase();
String[] columns = new String[]{COLUMN_TITLE, COLUMN_MON,};
#SuppressLint("Recycle")
Cursor cursor =
sqLiteDatabase.query(TABLE_TIMETABLE,columns,COLUMN_MON + "=" + 1 ,null,null,null,null);
int iTitle = cursor.getColumnIndex(COLUMN_TITLE);
StringBuilder result = new StringBuilder();
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
result.append(cursor.getString(iTitle)).
append("\n\n");
}
return result.toString();
}
This is My fragment
public class Monday_DataShow_Fragment extends Fragment {
private View root;
private ListView listView_mon;
private ArrayList<TimeTable_ListItems> timeTable_listItems_array;
private TimeTable_ListItems timeTable_listItems;
private DatabaseTimetable databaseTimetable;
private DataShow_List_Adapter dataShow_list_adapter;
public Monday_DataShow_Fragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_monday__data_show_, container, false);
findViews();
databaseTimetable = new DatabaseTimetable(getActivity());
timeTable_listItems = new TimeTable_ListItems();
dataShow_list_adapter = new DataShow_List_Adapter(requireActivity());
setListItems();
timeTable_listItems_array.add(timeTable_listItems);
dataShow_list_adapter.SetTimeTable_listItems_adapter(timeTable_listItems_array);
listView_mon.setAdapter(dataShow_list_adapter);
// Inflate the layout for this fragment
return root;
}
private void setListItems(){
timeTable_listItems_array = new ArrayList<>();
timeTable_listItems.setTitle(databaseTimetable.getTitle_database_mon());
dataShow_list_adapter.notifyDataSetChanged();
}
private void findViews(){
listView_mon = root.findViewById(R.id.listview_monday);
}
}
If you have any suggestions I'd like to hear it.
The issue is you have only one title as title String. getTitle_database_mon returns result.toString(). If you want to have multiple rows you need to have multiple objects in your list and unique titles for each. So instead of one TimeTable_ListItems. You need to be using ArrayList<TimeTable_ListItems> instead and have each entry contain a title so it is going to create multiple rows in the list instead of one.

retrofit, can't display my data on recyclerview from my api

im a newbie, i have a problem in my recyclerview. I cant fetch my data from my api. ive just took this tutorial since it is the same implementation form my app. http://shaoniiuc.com/android/fetch-json-api-data-recyclerview-using-retrofit-library/, Maybe my implementation is wrong here, can you please help me to solve, thank you :)
This is my api:
public interface Api {
#GET("api/Database/GetSchedule?serialNumber=1807200003")
Call<List<ScheduleDetails>> getSchedData();
}
My DetailObjects:
public class ScheduleDetails {
private String ID;
private String Location;
private String Latitude;
private String Longitude;
private String SequenceNumber;
private String Comment;
private String hasArrived;
private String ActualArrival;
private String hasDepart;
private String ActualDeparture;
private String Status;
private String ID_FleetSchedule;
private String ExpectedTimeOfTransaction;
private String EstimatedTimeOfDeparture;
private String ID_FleetCar;
private String Scheduler;
private String Car;
private String ID_FleetCompany;
private String FleetCompany;
private String ID_FleetDevice;
private String SerialNumber;
//Constructor....
//Getter.....
}
note: in my api, these are the string ive get but
ive only getting least of them... you can check
it on my adapterView.
my adapterview:
public class scheduleAdapter extends
RecyclerView.Adapter<scheduleAdapter.MyViewHolder> {
private List<ScheduleDetails> schedlist;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView location,schedule_status,dateTime,IDFleet,iid;
public MyViewHolder(View view) {
super(view);
location=view.findViewById(R.id.schedule_location);
dateTime=view.findViewById(R.id.schedule_dateTime);
schedule_status=view.findViewById(R.id.schedule_Status);
IDFleet=view.findViewById(R.id.schedule_FleetID);
iid=view.findViewById(R.id.schedule_ID);
}
}
public scheduleAdapter(List<ScheduleDetails> scheduleList) {
this.schedlist = scheduleList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.schedule_cardview, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int
position) {
ScheduleDetails sched = schedlist.get(position);
holder.location.setText(sched.getLocation());
holder.schedule_status.setText(sched.getStatus());
holder.dateTime.setText(sched.getExpectedTimeOfTransaction());
holder.IDFleet.setText(sched.getID_FleetSchedule());
holder.iid.setText(sched.getID());
}
#Override
public int getItemCount() {
return schedlist.size();
}
}
this is my API:
public class ApiClient {
private static final String BASE_URL = "http://www.example.com";
private static Retrofit retrofit = null;
public static Retrofit getRetrofit() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
this is my getList via recyclerview on my main activity:
public class ScheduleFleet extends Fragment {
View inflatedView = null;
private RecyclerView recyclerView;
private scheduleAdapter mAdapter;
private LinearLayoutManager layoutManager;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
inflatedView = inflater.inflate(R.layout.fragment_schedule_fleet, container, false);
return inflatedView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Schedule");
final SwipeRefreshLayout refresh = inflatedView.findViewById(R.id.sched_refresh);
getUserList();
refresh.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
doYourUpdate();
}
private void doYourUpdate() {
recyclerView.setAdapter(mAdapter);
getUserList();
refresh.setRefreshing(false);
}
}
);
}
private void getUserList() {
try {
Api service = ApiClient.getRetrofit().create(Api.class);
Call<List<ScheduleDetails>> call = service.getSchedData();
call.enqueue(new Callback<List<ScheduleDetails>>() {
#Override
public void onResponse(Call<List<ScheduleDetails>> call, Response<List<ScheduleDetails>> response) {
List<ScheduleDetails> userList = response.body();
layoutManager = new LinearLayoutManager(getContext());
RecyclerView recyclerView =inflatedView.
findViewById(R.id.scheduleRecycler);
recyclerView.setLayoutManager(layoutManager);
scheduleAdapter recyclerViewAdapter =
new scheduleAdapter(userList);
recyclerView.setAdapter(recyclerViewAdapter);
}
#Override
public void onFailure(Call<List<ScheduleDetails>> call, Throwable t) {
}
});
}catch (Exception e) {}
}
}
note: ive try to use the debug tool.. it says that my api is message:OK also the response= true... but i havnt display the data on my recyclerview...
ill hope, you understand my question.. feel free to comment if i i have wrong in my question.. thanks folks.
this is my sample api get using insomnia:

Fetching all user by retrofit in RecyclerView

My recyclerView showing only first user data.but when i check allusers data in my http://localhost/MyApi/public/allusers , it showing 6 user data as a JSON format
This is my JSON Image
Json image
My SingleTon class
public class RetofitClient_SingleTone {
private static final String BASE_URL = "http://192.168.0.100/MyApi/public/";
private static RetofitClient_SingleTone mInstance;
private Retrofit retrofit;
public RetofitClient_SingleTone() {
retrofit=new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static synchronized RetofitClient_SingleTone getInstance(){
if (mInstance==null){
mInstance = new RetofitClient_SingleTone();
}
return mInstance;
}
public Api getApi(){
return retrofit.create(Api.class);
}
}
My Api.class
public interface Api {
#GET("allusers")
Call<UsersResponse> getUsers();
}
2 Model Class
1. My UserResponse.class
public class UsersResponse {
#SerializedName("error")
#Expose
private Boolean error;
#SerializedName("users")
#Expose
private List<User> users = null;
public UsersResponse(boolean error, List<User> users) {
this.error = error;
this.users = users;
}
public boolean isError() {
return error;
}
public List<User> getUsers() {
return users;
}
}
2. My User.class
public class User {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("email")
#Expose
private String email;
#SerializedName("name")
#Expose
private String name;
#SerializedName("school")
#Expose
private String school;
public User(int id, String email, String name, String school) {
this.id = id;
this.email = email;
this.name = name;
this.school = school;
}
public int getId() {
return id;
}
public String getEmail() {
return email;
}
public String getName() {
return name;
}
public String getSchool() {
return school;
}
}
My Adapter Class Users_Adapter .class
public class Users_Adapter extends RecyclerView.Adapter<Users_Adapter.UserViewHolder> {
private Context context;
private List<User> userList;
public Users_Adapter(Context context, List<User> userList) {
this.context = context;
this.userList = userList;
}
#NonNull
#Override
public UserViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recyler_view_users, parent, false);
return new UserViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull UserViewHolder holder, int position) {
User user = userList.get(position);
Log.e("Name - - - -", "onBindViewHolder: "+user.getName() );
holder.name_TV.setText(user.getName());
holder.email_TV.setText(user.getEmail());
holder.school_TV.setText(user.getSchool());
}
#Override
public int getItemCount() {
return userList.size();
}
//create class that extend ViewHolder class
public class UserViewHolder extends RecyclerView.ViewHolder {
TextView name_TV;
TextView email_TV;
TextView school_TV;
public UserViewHolder(#NonNull View itemView) {
super(itemView);
name_TV = itemView.findViewById(R.id.texview_name);
email_TV = itemView.findViewById(R.id.texview_Email);
school_TV = itemView.findViewById(R.id.texview_school);
}
}
}
MY Fragment Class UsersFragment.class
public class UsersFragment extends Fragment{
RecyclerView recyclerView;
private Users_Adapter adapter;
private List<User> userList;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.users_fragment,container,false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recyclerView=view.findViewById(R.id.recylerView_id);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
Call<UsersResponse> call= RetofitClient_SingleTone.getInstance().getApi().getUsers();
call.enqueue(new Callback<UsersResponse>() {
#Override
public void onResponse(Call<UsersResponse> call, Response<UsersResponse> response) {
userList = response.body().getUsers();
adapter=new Users_Adapter(getActivity(),userList);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call<UsersResponse> call, Throwable t) {
}
});
}
}
I Want to show all user in recyclerView But it Showing only first user
app screenshort

How to call a Web Services using Android

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) {
}
}
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
Loopj official Documentation and Example
Retrofit
Retrofit official Documentation By SquareUp
Retrofit Tutorial from JournelDev
Volley
Volley official Documenation By Android Developers
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
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.
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
try this examples it's very easy this examples must help you.
asynctask-callback
volley-callback

The nearest bars and restaurants from the retrofit on api google maps

i want to find nearest bars and restoraunts from me on api google maps, and put it in listView and on map, i do it with retrofit, bit i have an error,, but i cant understand how i must to do, can you help me?
UPD all code:
UPD add adapter code
public class Retrofit {
private static final String ENDPOINT = "https://maps.googleapis.com/maps/api/place";
private static ApiInterface apiInterface;
interface ApiInterface {
#GET("/nearbysearch/json?location=49.9944422,36.2368201&radius=500&types=food&key=AIzaSyDQZoJKznf0uRkvJFqLYbZ7-1GeGudjmv0")
void getBars(Callback<PlaceResponse> callback);
}
static {
init();
}
private static void init() {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(ENDPOINT)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
apiInterface = restAdapter.create(ApiInterface.class);
}
public static void getBars(Callback<PlaceResponse> callback) {
apiInterface.getBars(callback);
}
}
Class Result:
public class Result {
public Geometry geometry;
public String icon;
public String id;
public String name;
public OpeningHours openingHours;
public List<Photo> photos = new ArrayList<Photo>();
public String placeId;
public String scope;
public List<AltId> altIds = new ArrayList<AltId>();
public String reference;
public List<String> types = new ArrayList<String>();
public String vicinity;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVicinity() {
return vicinity;
}
public void setVicinity(String vicinity) {
this.vicinity = vicinity;
}
}
Class Place Response:
public class PlaceResponse {
public List<Object> htmlAttributions = new ArrayList<Object>();
public List<Result> results = new ArrayList<Result>();
public String status;
}
Call and set in adapter:
Retrofit.getBars(new Callback<PlaceResponse>() {
#Override
public void success(PlaceResponse placeResponse, Response response) {
listView.setAdapter(new MyAdapter(MainActivity.this, placeResponse // There is error));
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(MainActivity.this, "Something Wrong", Toast.LENGTH_SHORT).show();
}
});
Error:
retrofit.RetrofitError: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
Adapter code:
class MyAdapter extends ArrayAdapter<Result> {
public MyAdapter(Context context, List<Result> objects) {
super(context, R.layout.list_item, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.textNameOfBar = (TextView) rowView.findViewById(R.id.name_id);
holder.textVicinity = (TextView) rowView.findViewById(R.id.vicinity_id);
rowView.setTag(holder);
} else {
holder = (ViewHolder) rowView.getTag();
}
Result result = getItem(position);
holder.textNameOfBar.setText(result.getName());
holder.textVicinity.setText(result.getVicinity());
return rowView;
}
class ViewHolder {
public TextView textNameOfBar;
public TextView textVicinity;
}
}
You received the error because your expected result (List<Bars>) isn't what the server is returning (i.e you're excepting an json array but the server returns an json object).
The place search documentation shows that the response has a given format encapsulating the results. In this case, the model class should like this:
public class PlaceResponse {
public List<Object> htmlAttributions = new ArrayList<Object>();
public List<Result> results = new ArrayList<Result>();
public String status;
}
...
public class Result {
public Geometry geometry;
public String icon;
public String id;
public String name;
public OpeningHours openingHours;
public List<Photo> photos = new ArrayList<Photo>();
public String placeId;
public String scope;
public List<AltId> altIds = new ArrayList<AltId>();
public String reference;
public List<String> types = new ArrayList<String>();
public String vicinity;
}
with void getBars(Callback<PlaceResponse> callback); in your API interface.
You can use jsonschema2pojo to generate your model classes from a json schema.
Also, please note that the food type is deprecated (see Place Types).
then in your retrofit callback you can do to access the results:
#Override
public void success(PlaceResponse placeResponse, Response response) {
listView.setAdapter(new MyAdapter(MainActivity.this, placeResponse.getResults()));
}

Categories

Resources