This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I am trying to fetch an array from the data.police.uk website.
Unfortunately, when running the code an error comes up: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
Here's the code, no idea, what I am doing wrong:
package com.example.cosmin.crimerate.Latest_crimes;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import com.example.cosmin.crimerate.R;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class JsonCrimesActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_json_crimes);
final ListView listView = findViewById(R.id.crimesList);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Api.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Api api = retrofit.create(Api.class);
Call<List<Crime>> call = api.getCrimes();
call.enqueue(new Callback<List<Crime>>() {
#Override
public void onResponse(Call<List<Crime>> call, Response<List<Crime>> response) {
List<Crime> Crimes = response.body();
String[] crimeCategories = new String[Crimes.size()];
for (int i=0; i < Crimes.size();i++){
crimeCategories[i]= Crimes.get(i).getCategory();
}
listView.setAdapter(
new ArrayAdapter<String>(
getApplicationContext(),
android.R.layout.simple_list_item_1,
crimeCategories
)
);
}
#Override
public void onFailure(Call<List<Crime>> call, Throwable t) {
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
That's the Api class:
public interface Api{
String BASE_URL = "https://data.police.uk/api/";
#GET("/crimes-no-location?category=all-crime&force=leicestershire&date=2017-02")
Call<List<Crime>> getCrimes();
Do you think it can be because of the array?
If you can please me give me a hint or anything what's happening.
Thank you for your help!
LE: CRIME MODEL:
public class Crime {
private String category;
private String persistent_id;
private String location_subtype;
private String id;
private String location;
private String context;
private String month;
private String location_type;
private String outcome_status;
public Crime(String category, String persistent_id, String location_subtype, String id, String location, String context, String month, String location_type, String outcome_status) {
this.category = category;
this.persistent_id = persistent_id;
this.location_subtype = location_subtype;
this.id = id;
this.location = location;
this.context = context;
this.month = month;
this.location_type = location_type;
this.outcome_status = outcome_status;
}
public String getCategory() {
return category;
}
public String getPersistent_id() {
return persistent_id;
}
public String getLocation_subtype() {
return location_subtype;
}
public String getId() {
return id;
}
public String getLocation() {
return location;
}
public String getContext() {
return context;
}
public String getMonth() {
return month;
}
public String getLocation_type() {
return location_type;
}
public String getOutcome_status() {
return outcome_status;
}
}
Make sure this piece of code if working fine.
List<Crime> Crimes = response.body();
Your Crimes List is probably empty or null.
Your response.body() is returning null. I'm pretty sure it's because you misconfigured your Api. As is, you're making an http call to the following uri (notice the double //):
https://data.police.uk/api//crimes-no-location?category=all-crime&force=leicestershire&date=2017-02
Remove the leading slash in your #GET
Related
I am making an api call to themoviedb.org api in android using retrofit. I am expecting a json array with a list of movies in the response, however i get a null object reference when i call the getResults method of my POJO class. Kindly assist.
This is the error message i am getting;
2020-01-03 12:28:10.396 20851-20851/com.popularmovies E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.popularmovies, PID: 20851
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.gson.JsonArray com.popularmovies.TrendingPojo.getResults()' on a null object reference
at com.popularmovies.TrendingFragment$1.onResponse(TrendingFragment.java:109)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:71)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7045)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
Here is my api interface
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;
public interface TmdbApi {
final String BASE_URL = "https://api.themoviedb.org/4/";
#GET("list/{id}")
Call<CategoryJsonResponse> getMovies(#Path ("id") String id, #Query("api_key") String api_key);
#GET("discover/movie")
Call<DiscoverPOJO> getDiscover(#Query("sort_by") String sort_by,#Query("api_key") String api_key);
#GET("trending/{media_type}/{time_window}")
Call<TrendingPojo> getTrending(#Path("media_type") String media_type, #Path("time_window") String time_window, #Query("api_key") String api_key);
}
my problem is with the trending endpoint.
Below is my POJO class
package com.popularmovies;
import com.google.gson.JsonArray;
public class TrendingPojo {
private int page;
private JsonArray results;
private int total_results;
private int total_pages;
//Default constructor for api calls
public TrendingPojo(int page, JsonArray results, int total_pages, int total_results) {
this.page = page;
this.results = results;
this.total_results = total_results;
this.total_pages = total_pages;
}
public int getPage() {
return page;
}
public JsonArray getResults() {
return results;
}
public int getTotal_results() {
return total_results;
}
public int getTotal_pages() {
return total_pages;
}
public void setPage(int page) {
this.page = page;
}
public void setResults(JsonArray results) {
this.results = results;
}
public void setTotal_results(int total_results) {
this.total_results = total_results;
}
public void setTotal_pages(int total_pages) {
this.total_pages = total_pages;
}
}
Below is the fragment from which i make the api call using retrofit;
package com.popularmovies;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import static com.popularmovies.DiscoverFragment.API_KEY;
public class TrendingFragment extends Fragment implements MovieAdapter.MovieAdapterOnclickHandler {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private View rootView;
private ProgressBar progressBar;
private RecyclerView mRecyclerView;
private MovieAdapter movieAdapter;
private List<Movies> moviez;
public TrendingFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_trending, container, false);
progressBar = rootView.findViewById(R.id.trending_pb);
progressBar.setVisibility(View.VISIBLE);
mRecyclerView = rootView.findViewById(R.id.trending_rv);
GridLayoutManager layoutManager = new GridLayoutManager(rootView.getContext(), 2);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
movieAdapter = new MovieAdapter(this);
mRecyclerView.setAdapter(movieAdapter);
getTrendingResponse();
return rootView;
}
// TODO: Rename method, update argument and hook method into UI event
private void getTrendingResponse(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(TmdbApi.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
TmdbApi tmdbApi = retrofit.create(TmdbApi.class);
Call<TrendingPojo> call = tmdbApi.getTrending("movie","week",API_KEY);
call.enqueue(new Callback<TrendingPojo>() {
#Override
public void onResponse(Call<TrendingPojo> call, Response<TrendingPojo> response) {
TrendingPojo movies = response.body();
JsonArray allmovies;
allmovies = movies.getResults();
if(allmovies!= null){
for(int i = 0; i < allmovies.size(); i++){
Gson gson = new Gson();
Type listType = new TypeToken<Collection<Movies>>(){}.getType();
moviez = gson.fromJson(allmovies, listType);
}
movieAdapter.setData(moviez);
progressBar.setVisibility(View.INVISIBLE);
}
}
#Override
public void onFailure(Call<TrendingPojo> call, Throwable t) {
Toast.makeText(rootView.getContext(), t.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onDetach() {
super.onDetach();
}
#Override
public void onClick(int s) {
}
}
Finally here is a link to the api documentation for the trending endpoint.
https://developers.themoviedb.org/3/trending/get-trending
Turns out the problem was I was using a version 4 base URL which returns a 404 error code for some endpoints instead of version 3.
changing
"https://api.themoviedb.org/4/"
to
"https://api.themoviedb.org/3/"
was the solution.
Even though every thing is working properly and registration is happening. Retrofit on Response don't get called but onFailure gets called. Call.isexecutted returns true.
I am showing the model class and registrationFragment where the error occured. This is taking a lot time. So thanks in advance for help
RegistrationFragment.java
package com.example.milan.hospital;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* A simple {#link Fragment} subclass.
*/
public class RegistrationFragment extends Fragment {
private EditText Name,UserName, UserPassword;
private Button BnRegister;
public RegistrationFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_registration, container, false);
Name = view.findViewById(R.id.txt_name);
UserName = view.findViewById(R.id.txt_user_name);
UserPassword = view.findViewById(R.id.txt_password);
BnRegister = view.findViewById(R.id.bn_register);
BnRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
performRegistration();
}
});
return view;
}
public void performRegistration()
{
String name = Name.getText().toString();
String username = UserName.getText().toString();
String password = UserPassword.getText().toString();
Call<User> call = MainActivity.apiInterface.performRegistration(name,username,password);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
if(response.body().getResponse().equals("ok"))
{
MainActivity.prefConfig.displayToast("Registration success...");
}
else if(response.body().getResponse().equals("exist"))
{
MainActivity.prefConfig.displayToast("User already exist....");
}
else if(response.body().getResponse().equals("error"))
{
MainActivity.prefConfig.displayToast("Something went wrong...");
}
}
#Override
public void onFailure(Call<User> call, Throwable t) {
}
});
Name.setText("");
UserPassword.setText("");
UserName.setText("");
}
}
User.java
package com.example.milan.hospital;
import com.google.gson.annotations.SerializedName;
public class User {
#SerializedName("response")
private String Response;
#SerializedName("name")
private String Name;
public String getResponse() {
return Response;
}
public String getName() {
return Name;
}
}
MainActivity.java
package com.example.milan.hospital;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity implements LoginFragment.OnLoginFormActivityListener{
public static PrefConfig prefConfig;
public static ApiInterface apiInterface;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefConfig = new PrefConfig(this);
apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
if(findViewById(R.id.fragment_container) != null)
{
if(savedInstanceState != null)
{
return;
}
if(prefConfig.readLoginStatus())
{
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container,new WelcomeFragment()).commit();
}
else
{
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container,new LoginFragment()).commit();
}
}
}
#Override
public void performRegister() {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new RegistrationFragment()).addToBackStack(null).commit();
}
#Override
public void performLogin(String name) {
}
}
ApiInterface.java
package com.example.milan.hospital;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface ApiInterface
{
#GET("register.php")
Call<User> performRegistration(#Query("name") String Name,#Query("user_name") String UserName,#Query("user_password") String UserPassword);
#GET("login.php")
Call<User> performUserLogin(#Query("user_name") String UserName,#Query("user_password") String UserPassword);
}
I think performRegistration() in ApiInterface.java should have an annotation of #POST rather than #GET since registration is the act of posting data rather than getting. Give it a try once.
change the ApiClient to this. As there was a well known problem of retrofit while reading json. to resolve we have initialize gson object ourself
public class ApiClient
{
public static final String BASE_URL = "http://10.0.3.2/loginapp/";
public static Retrofit retrofit = null;
public static Retrofit getApiClient()
{
Gson gson = new GsonBuilder()
.setLenient()
.create();
if(retrofit == null)
{
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create(gson)).build();
}
return retrofit;
}
}
I'm trying to use retrofit 2 to parse a json array :
[{"question":"question 1"},{"question":"question 2"}]
Here is the main activity of my project :
package maxime.mysqltest;
import android.graphics.Movie;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private final static int idForm = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Questionable questionService =
ApiClient.getClient().create(Questionable.class);
Call<QuestionList> call = questionService.getQuestions(idForm);
call.enqueue(new Callback<QuestionList>() {
#Override
public void onResponse(Call<QuestionList>call, Response<QuestionList> response) {
List<Question> questions = response.body().getQuestions();
Log.d(TAG, "Number of questions received: " + questions.size());
}
#Override
public void onFailure(Call<QuestionList>call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
}
}
I created a class to access my page on the MAMP server :
public class ApiClient {
public static final String BASE_URL = "http://*myIP*:8888";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
I also have two classes for the object that I try to parse :
public class Question {
private final String question;
public Question(String question)
{
this.question=question;
}
}
public class QuestionList {
private List<Question> questions = new ArrayList<>();
public QuestionList(List<Question> questions)
{
this.questions=questions;
}
public List<Question> getQuestions() {
return questions;
}
}
and finally my interface :
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface Questionable {
#GET("/takeQuestions.php")
Call<QuestionList> getQuestions(#Query("idForm") int idForm);
}
When I run the application the following error appeared :
E/MainActivity: com.google.gson.JsonSyntaxException:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was
BEGIN_ARRAY at line 1 column 2 path $
I searched on the internet but I can't find a solution to my problem...
Gson expected an Object but it received an Array.
This is a plain json array with 2 objects:
[{"question":"question 1"},{"question":"question 2"}]
This is an object that contains a list questions that has the questions in it.
public class QuestionList {
private List<Question> questions = new ArrayList<>();
}
Which would look like:
{
"questions" : [{"question":"question 1"},{"question":"question 2"}]
}
So when you tell retrofit that you expect a Call<QuestionList> Gson expects the above Json, which is not the same as the one on top. It is a list "wrapped" inside an object.
Your call object should look like this:
Call<Question[]> getQuestions()
// or
Call<List<Question>> getQuestions()
either of which is an actual list / array of Question.
I want to load question and answer in expandable listview from json using retrofit library. I dont know how to do this. Find me a solution.
Here is the two model class i am using.
public class QuestionResult {
boolean IsSuccess;
List<QuestionsModel> question;
public boolean isSuccess() {
return IsSuccess;
}
public List<QuestionsModel> getQuestion() {
return question;
}
}
And
public class QuestionsModel {
private int q_id;
private int category_id;
private String question;
private String answer;
public int getQ_id() {
return q_id;
}
public int getCategory_id() {
return category_id;
}
public String getQuestion() {
return question;
}
public String getAnswer() {
return answer;
}
}
Here is my Activity
public class QuestionBank extends AppCompatActivity {
#InjectView(R.id.ques_type_spinner)
Spinner courseSpinner;
#InjectView(R.id.home_btn_qbank)
Button homeButton;
#InjectView(R.id.no_questions)
TextView textView;
#InjectView(R.id.ques_ans_listview)
ExpandableListView listView;
List<String> courseNames;
ArrayAdapter<String> courseAdapter;
ExpandableListAdapter listAdapter;
List<QuestionResult> resultList;
ProgressDialog progress;
int selectedPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question_bank);
ButterKnife.inject(this);
StatusBarTheme.setStatusBarColor(this);
showCourseCategory();
homeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
courseSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
selectedPosition = courseSpinner.getSelectedItemPosition() + 1;
Log.d("cat_id ", " " + selectedPosition);
loadQuestions(selectedPosition);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
private void loadQuestions(final int selectedPosition) {
ApiInterface apiInterface = ApiClient.getClient(this).create(ApiInterface.class);
Call<QuestionResult> call = apiInterface.loadQuesAndAnswers(selectedPosition);
call.enqueue(new Callback<QuestionResult>() {
#Override
public void onResponse(Call<QuestionResult> call, Response<QuestionResult> response) {
List<QuestionsModel> questionsModelList = response.body().getQuestion();
if (questionsModelList != null) {
listAdapter = new ExpandListAdapter(QuestionBank.this, questionsModelList, selectedPosition);
listView.setAdapter(listAdapter);
} else {
listView.setVisibility(View.GONE);
textView.setVisibility(View.VISIBLE);
}
}
#Override
public void onFailure(Call<QuestionResult> call, Throwable t) {
}
});
}
private void showCourseCategory() {
ApiInterface apiInterface = ApiClient.getClient(this).create(ApiInterface.class);
Call<CategoryResult> call = apiInterface.loadCourseTitle();
progress = new ProgressDialog(QuestionBank.this);
progress.setMessage("Loading.. Please wait");
progress.show();
call.enqueue(new Callback<CategoryResult>() {
#Override
public void onResponse(Call<CategoryResult> call, Response<CategoryResult> response) {
if (progress.isShowing()) {
progress.dismiss();
}
if (response.body().isSuccess() && response.body().getCategory() != null) {
response.body().getCategory();
courseNames = new ArrayList<>();
for (CourseType courseType : response.body().getCategory()) {
courseNames.add(courseType.getCategory_title());
}
loadSpinner(courseNames);
}
}
#Override
public void onFailure(Call<CategoryResult> call, Throwable t) {
}
});
}
private void loadSpinner(List<String> educationTypeList) {
courseAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, educationTypeList);
courseAdapter.setDropDownViewResource(android.R.layout.simple_list_item_checked);
courseSpinner.setAdapter(courseAdapter);
}
}
Here is the complete code. Change it for your purposes. If anything will happen you can write comment i will answer.
Application.class
public class Application extends Application{
private static Application instance;
private I_Requests iWebEndpoint;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static Application i() {
return instance;
}
public I_Requests w() {
if(this.iWebEndpoint == null){
initRetrofit();
}
return iWebEndpoint;
}
private void initRetrofit(){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient
.Builder()
.addInterceptor(interceptor)
.readTimeout(1, TimeUnit.MINUTES)
.writeTimeout(1, TimeUnit.MINUTES)
.connectTimeout(1, TimeUnit.MINUTES)
.build();
client.readTimeoutMillis();
this.iWebEndpoint = new Retrofit.Builder()
.baseUrl(I_Requests.address)
.client(client)
.addConverterFactory(JacksonConverterFactory.create())
.build()
.create(I_Requests.class);
}
}
JacksonConverterFactory.class
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
/**
* A {#linkplain Converter.Factory converter} which uses Jackson.
* <p>
* Because Jackson is so flexible in the types it supports, this converter assumes that it can
* handle all types. If you are mixing JSON serialization with something else (such as protocol
* buffers), you must {#linkplain Retrofit.Builder#addConverterFactory(Converter.Factory) add this
* instance} last to allow the other converters a chance to see their types.
*/
public final class JacksonConverterFactory extends Converter.Factory {
/** Create an instance using a default {#link ObjectMapper} instance for conversion. */
public static JacksonConverterFactory create() {
return create(new ObjectMapper());
}
/** Create an instance using {#code mapper} for conversion. */
public static JacksonConverterFactory create(ObjectMapper mapper) {
return new JacksonConverterFactory(mapper);
}
private final ObjectMapper mapper;
private JacksonConverterFactory(ObjectMapper mapper) {
if (mapper == null) throw new NullPointerException("mapper == null");
this.mapper = mapper;
}
#Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
JavaType javaType = mapper.getTypeFactory().constructType(type);
ObjectReader reader = mapper.reader(javaType);
return new JacksonResponseBodyConverter<>(reader);
}
#Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
JavaType javaType = mapper.getTypeFactory().constructType(type);
ObjectWriter writer = mapper.writerWithType(javaType);
return new JacksonRequestBodyConverter<>(writer);
}
}
JacksonRequestBodyConverter.class
import com.fasterxml.jackson.databind.ObjectWriter;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Converter;
final class JacksonRequestBodyConverter<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
private final ObjectWriter adapter;
JacksonRequestBodyConverter(ObjectWriter adapter) {
this.adapter = adapter;
}
#Override public RequestBody convert(T value) throws IOException {
byte[] bytes = adapter.writeValueAsBytes(value);
return RequestBody.create(MEDIA_TYPE, bytes);
}
}
JacksonResponseBodyConverter.class
import com.fasterxml.jackson.databind.ObjectReader;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Converter;
final class JacksonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final ObjectReader adapter;
JacksonResponseBodyConverter(ObjectReader adapter) {
this.adapter = adapter;
}
#Override public T convert(ResponseBody value) throws IOException {
try {
return adapter.readValue(value.charStream());
} finally {
value.close();
}
}
}
I_Request.interface
import java.util.ArrayList;
import manqaro.com.projectz.ServerSide.Response.TestData;
import manqaro.com.projectz.ServerSide.Response.TestResponse;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
public interface I_Requests {
//PUT HERE YOUR SERVER MAIN ADDRES
String address = "http://goto.xcodes.club";
//SAMPLE EXAMPLE OF POST TYPE , YOU SHOULD CHANGE EVERYTHING YOU WANT.
//IN THIS EXAMPLE YOU WILL GET JSON DATA WHICH WILL BE CONVERTED TO JAVA OBJECT.
#FormUrlEncoded
//Here YOU HAVE TO GIVE ADDRESS TO SPECIFIC CALL
#GET("/api/v1/objects/")
Call<TestResponse<ArrayList<TestData>>> login(
);
#FormUrlEncoded
#POST("/api/v1/objects/")
Call<TestResponse<ArrayList<TestData>>> register(
);
}
TestResponse.class
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Created by ArsenSench on 11/9/2016.
*/
public class TestResponse<T> {
#JsonProperty("status")
public int status;
#JsonProperty("message")
public String message;
#JsonProperty("data")
public T data;
}
TestData.class
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Created by ArsenSench on 11/9/2016.
*/
public class TestData extends {
#JsonProperty("id")
public int id;
#JsonProperty("name")
public String name;
#JsonProperty("description")
public String description;
#JsonProperty("avatar")
public String avatar;
#JsonProperty("rate")
public int rate;
}
ServerCalls.class
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import java.util.ArrayList;
import manqaro.com.projectz.ServerSide.Application.Tickle_Application;
import manqaro.com.projectz.ServerSide.Response.TestData;
import manqaro.com.projectz.ServerSide.Response.TestResponse;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Created by ArsenSench on 11/9/2016.
*/
public class ServerCalls {
Context context;
public ServerCalls(Context context){
this.context = context;
}
public void testCallBack(){
Tickle_Application.i().w().login().enqueue(new Callback<TestResponse<ArrayList<TestData>>>() {
#Override
public void onResponse(Call<TestResponse<ArrayList<TestData>>> call, Response<TestResponse<ArrayList<TestData>>> response) {
if(response.code()==200){
if(response.body().status==200){
Toast.makeText(context, response.body().data.get(0).name, Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(context, "No Name", Toast.LENGTH_SHORT).show();
}
}
else{
Toast.makeText(context, "No Connection", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<TestResponse<ArrayList<TestData>>> call, Throwable t) {
Toast.makeText(context, t.getCause().getMessage(), Toast.LENGTH_SHORT).show();
Log.e("jex", "onFailure: " + t.getCause().getMessage() );
}
});
}
}
TestActivity.activity
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import manqaro.com.projectz.R;
import manqaro.com.projectz.ServerSide.Main.ServerCalls;
public class TestActivity extends AppCompatActivity {
ServerCalls sc = new ServerCalls(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
}
public void clickThatShit(View view){
sc.testCallBack();
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="your.package.name">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".Application"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:replace="android:icon">
<activity
android:name=".TestActivity">
</activity>
</application>
</manifest>
build.gradle(module app)
Include these dependencies in yourdependencies
compile 'com.squareup.retrofit2:retrofit:2.0.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.3'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.3'
Include this lines in your android{} block
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
}
I want to receive the value of the variable Id from the listItem clicked and to pass it in the other activity.But I am not receiving anything in the variable.
Here is the attached code :
MainActivity.java
package com.example.hp.citysearchapp;
import android.app.ProgressDialog;
import android.content.Intent;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.view.menu.ExpandedMenuView;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonArrayRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private ProgressDialog pDialog;
private List<City> cityList = new ArrayList<City>();
private ListView listView;
private static String url;
ImageView searchIcon;
String idGet;
String edittextSearch;
TextInputLayout searchLayout;
EditText search;
private CustomListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.city_listView);
searchLayout=(TextInputLayout)findViewById(R.id.input_layout_search);
search=(EditText)findViewById(R.id.input_search);
searchIcon=(ImageView)findViewById(R.id.imageView);
adapter = new CustomListAdapter(this,cityList);
searchIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
edittextSearch=search.getText().toString();
Log.d("hello2", search.getText().toString());
adapter.notifyDataSetChanged();
url = "http://test.maheshwari.org/services/testwebservice.asmx/SuggestCity?tryValue="+edittextSearch;
parsingMethod();
}
});
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(MainActivity.this,CityDetailsActivity.class);
City city = cityList.get(position);
idGet=city.getId();
Log.d("dfjdkfj", idGet); //Not receiving anything ,here is the problem
intent.putExtra("gettingId",idGet);
startActivity(intent);
}
});
}
private void parsingMethod() {
Log.d("hello", url);
pDialog = new ProgressDialog(this);
// Showing progress dialog
pDialog.setMessage("Loading...");
pDialog.show();
// Creating volley request obj
JsonArrayRequest cityReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
hidePDialog();
// Parsing json
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = null;
try {
obj = jsonArray.getJSONObject(i);
} catch (JSONException e) {
e.printStackTrace();
}
City city = new City();
try {
city.setId(obj.getString("Id"));
city.setTitle(obj.getString("Title"));
city.setDescription(obj.getString("Description"));
city.setExv1(obj.getString("ExtraValue1"));
Log.d("hello",obj.getString("ExtraValue1"));
city.setExv2(obj.getString("ExtraValue2"));
city.setExv3(obj.getString("ExtraValue3"));
city.setExv4(obj.getString("ExtraValue4"));
city.setExv5(obj.getString("ExtraValue5"));
city.setExv6(obj.getString("ExtraValue6"));
city.setExv7(obj.getString("ExtraValue7"));
city.setExv8(obj.getString("ExtraValue8"));
city.setExv9(obj.getString("ExtraValue9"));
cityList.add(city);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener()
{
#Override
public void onErrorResponse (VolleyError error){
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(cityReq);
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
}
City.java
package com.example.hp.citysearchapp;
/**
* Created by hp on 22-03-2016.
*/
public class City {
String title,description,exv1,exv3,exv6,id,exv2,exv4,exv5,exv9,exv7,exv8;
public City(String title, String description, String id, String exv1, String exv3, String exv6,
String exv2, String exv4 , String exv5 , String exv7 , String exv8 , String exv9) {
this.title = title;
this.description=description;
this.id=id;
this.exv1=exv1;
this.exv2=exv2;
this.exv3=exv3;
this.exv4=exv4;
this.exv5=exv5;
this.exv6=exv6;
this.exv7=exv7;
this.exv8=exv8;
this.exv9=exv9;
}
public City() {
}
public String getId() {
return id;
}
public String getExv2() {
return exv2;
}
public String getExv4() {
return exv4;
}
public String getExv5() {
return exv5;
}
public String getExv7() {
return exv7;
}
public String getExv8() {
return exv8;
}
public String getExv9() {
return exv9;
}
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
public String getExv1() {
return exv1;
}
public String getExv3() {
return exv3;
}
public String getExv6() {
return exv6;
}
public void setId(String id) {
this.id = id;
}
public void setExv2(String exv2) {
this.exv2 = exv2;
}
public void setExv4(String exv4) {
this.exv4 = exv4;
}
public void setExv5(String exv5) {
this.exv5 = exv5;
}
public void setExv7(String exv7) {
this.exv7 = exv7;
}
public void setExv8(String exv8) {
this.exv8 = exv8;
}
public void setExv9(String exv9) {
this.exv9 = exv9;
}
public void setTitle(String title) {
this.title = title;
}
public void setDescription(String description) {
this.description = description;
}
public void setExv1(String exv1) {
this.exv1 = exv1;
}
public void setExv3(String exv3) {
this.exv3 = exv3;
}
public void setExv6(String exv6) {
this.exv6 = exv6;
}
}
Please modify your code a bit to achieve this --
You already have --
City city = cityList.get(position);
Now add this line to get Id from the ListItem clicked --
String Id = city.getExv3(); //Use one of your actual Getter methods accordingly.
Hope this helps!
Since I'm using a CustomAdapter for my list , I have to use the following code :
TextView textView = (TextView)view.findViewById(R.id.id); /*(R.id.id) is the id of the textview */
String gettingID=textView.getText().toString();