How can I return data in method from Retrofit i am confused? - retrofit2

I am confused please can you help me? I read similar questions but its is not clear for me, thanks in advance for your patient and attention.
I want to return to onCreate data which retrieved from API call using Retrofit. Here is my function where i call Retrofit.
private void loadTimeZoneAPI(double latitude, double longitude, long timestamp, String apiKeyTz) {
String lat = Double.toString(latitude);
String lon = Double.toString(longitude);
String time = Long.toString(timestamp);
serviceTZ.getDataTZ(lat+","+lon, time, apiKeyTz).enqueue(new Callback<TimeZoneGoogle>() {
#Override
public void onResponse(Call<TimeZoneGoogle> call, Response<TimeZoneGoogle> response) {
TimeZoneGoogle result = response.body();
timeZone = result.getTimeZoneId();
}
#Override
public void onFailure(Call<TimeZoneGoogle> call, Throwable t) {
}
});
}
How i will return timeZone value to onCreate where i will use for calculation.

You need a callback listener for your data in MainActivity or any activity you have used for view.
for example:make interface like this
interface RetrofitListener{
onDataLoad(TimeZoneGoogle timeZoneGoogle);
}
then give a reference in Activity from which you are calling Retrofit class
public class ActivityTest extends AppCompatActivity implements ActivityTest.RetrofitListener {
RetrofitCall retrofitListener;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
retrofitListener = new RetrofitCall(this);
}
}
and here in RetrofitCall class
private class RetrofitCall {
private RetrofitListener retrofitListener;
public RetrofitCall(RetrofitListener retrofitListener) {
this.retrofitListener = retrofitListener;
}
void getData(){
getDataTZ(lat+","+lon, time, apiKeyTz).enqueue(new Callback<TimeZoneGoogle>() {
#Override
public void onResponse(Call<TimeZoneGoogle> call, Response<TimeZoneGoogle> response) {
TimeZoneGoogle result = response.body();
timeZone = result.getTimeZoneId();
}
#Override
public void onFailure(Call<TimeZoneGoogle> call, Throwable t) {
}
});
}
}

Related

How to showing response string in a textview?

Result: {"Status":"OK","Message":"Report Genarated.","Result":"JVBERi0xLjUKJeLjz9MKMSAwIG9iago8PC9UeXBlL0ZvbnQvU3VidHlw"}
I am getting these response from the post api calling.Now How can i am get the Result string value.
Code:
holder.downloadBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
manager = new UtilityBillManager(context, AppBaseController.get().getUserSettings());
manager.UserTransactionReceiptReport(listener,billReceiptReport); //This the api calling
}
});
}
private final TransactionReportListener listener = new TransactionReportListener() {
#Override
public void didFetch(UserReportResponse response, String message) {
}
#Override
public void didError(String message) {
}
};
UserReponse is a Model which have String status,message, result.
Just use getResult() getter of Model class
See the below code
// add this condition to prevent app crashing.
if (response.body().getResult()!=null){
textView.setText(response.body().getResult()); // getResult() is your getters of the Model Class.
}
Hope it helps.

I Want To Itemonclicklister in Fragment on Spinner

This Is Main Fragment
Fragment:
private void getStock() {
dialog.show();
Retrofit retrofit = RetrofitClient.getRetrofitInstance();
apiInterface api = retrofit.create(apiInterface.class);
Call<List<Blocks>>call = api.getVaccineBlocks();
call.enqueue(new Callback<List<Blocks>>() {
#Override
public void onResponse(Call<List<Blocks>>call, Response<List<Blocks>> response) {
if (response.code() == 200) {
block = response.body();
spinnerada();
dialog.cancel();
}else{
dialog.cancel();
}
}
#Override
public void onFailure(Call<List<Blocks>> call, Throwable t) {
dialog.cancel();
}
});
}
private void spinnerada() {
String[] s = new String[block.size()];
for (int i = 0; i < block.size(); i++) {
s[i] = block.get(i).getBlockName();
final ArrayAdapter a = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item, s);
a.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//Setting the ArrayAdapter data on the Spinner
spinner.setAdapter(a);
}
}
This Is Blocks Model
model:
package com.smmtn.book.models;
import java.io.Serializable;
public class Blocks implements Serializable {
public String id;
public String blockName;
public String blockSlug;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getBlockName() {
return blockName;
}
public void setBlockName(String blockName) {
this.blockName = blockName;
}
public String getBlockSlug() {
return blockSlug;
}
public void setBlockSlug(String blockSlug) {
this.blockSlug = blockSlug;
}
}
here i need onitemclick with blockslug please any one can help, am new to android so i need some example.when on click i want take blockslug and load another method with that blockslug,like will get data from u "http://example.com/block/"+blockslug
i want to get blockslug from selected block
i hope guys i will get help
and sorry for my bad English,
First of all, you need to implement setOnItemSelectedListener. Refer to this https://stackoverflow.com/a/20151596/9346054
Once you selected the item, you can call them by making a new method. Example like below
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
Toast.makeText(parent.getContext(),
"OnItemSelectedListener : " + parent.getItemAtPosition(pos).toString(),
Toast.LENGTH_SHORT).show();
final String itemSelected = parent.getItemAtPosition(pos).toString();
showBlockSlug(itemSelected);
}
And then, at the method showBlockSlug() , you can call Retrofit.
private void showBlockSlug(final String blockslug){
final String url = "http://example.com/block/"+ blockslug;
//Do your stuff...
}

how to fix error 'int java.util.List.size()'

I am all time worked by one source! but now get error
int java.util.List.size()
now my adapter source its :
public class MessagesAdapter extends RecyclerView.Adapter<MessagesAdapter.msgsViewHoler> {
List<QueryMessages> queryMessages;
Context mtContext;
public MessagesAdapter(List<QueryMessages> queryMessages, MainActivity mainActivity){
this.queryMessages=queryMessages;
}
#NonNull
#Override
public msgsViewHoler onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.message_row,parent,false);
return new msgsViewHoler(view);
}
#Override
public void onBindViewHolder(#NonNull msgsViewHoler holder, int position) {
final QueryMessages queryMessageses=queryMessages.get(position);
Picasso.get()
.load(queryMessageses.getMpic())
.error(R.mipmap.ic_launcher)
.fit()
.into(holder.mpic);
holder.mname.setText(queryMessageses.getMname());
holder.message.setText(queryMessageses.getMessage());
holder.tarikh.setText(queryMessageses.getTarikh());
}
#Override
public int getItemCount() {
return queryMessages.size();
}
public class msgsViewHoler extends RecyclerView.ViewHolder{
int id;
CardView parent;
ImageView mpic;
TextView mname,message,tarikh;
public msgsViewHoler(View itemView) {
super(itemView);
parent=itemView.findViewById(R.id.message_row);
mpic=itemView.findViewById(iv_profile);
mname=itemView.findViewById(R.id.tv_mastername);
message=itemView.findViewById(R.id.tv_msg);
tarikh=itemView.findViewById(R.id.tv_date);
}
}
and give this error :
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at ir.arvandit.channeleto.adapter.MessagesAdapter.getItemCount(MessagesAdapter.java:62)
thats line is :
return queryMessages.size();
my Activity Main its :
RecyclerView rvmsg;
CardView message_row;
List<QueryMessages> queryMessages;
MessagesAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cast();
onClick();
ApiService service=ApiClient.getClient().create(ApiService.class);
Call<List<QueryMessages>> call=service.getQueryMessages();
call.enqueue(new Callback<List<QueryMessages>>() {
#Override
public void onResponse(Call<List<QueryMessages>> call, Response<List<QueryMessages>> response) {
pros.setVisibility(View.GONE);
queryMessages=response.body();
adapter=new MessagesAdapter(queryMessages,MainActivity.this);
rvmsg.setAdapter(adapter);
}
#Override
public void onFailure(Call<List<QueryMessages>> call, Throwable t) {
pros.setVisibility(View.GONE);
nonet.setVisibility(View.VISIBLE);
}
});
}
public void cast(){
rvmsg=findViewById(R.id.rv_message);
rvmsg.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
}
now I need help for fix this error!
Issue is in bellow code
private static final String TAG = "CurrentActivity";
#Override
public void onResponse(Call<List<QueryMessages>> call,
Response<List<QueryMessages>> response) {
Log.v(TAG, "onResponse=" + response.body().toString());
}
check weather response.body() or response is the ArrayList of <List<QueryMessages>>
in new version retrofit if in your json have free parameter , get this error
for example i need id,name,number
but in my json have id,name,number,date ....
i give this error!
and some time if in ApiService have false url!
tanks for help all

RxJava subscribe onNext is not called when adding element asynchronously

I have a Observable like this
Observable<String> gitHubRepoModelObservable;
I have this code
repoNames = new ArrayList<String>();
gitHubRepoModelObservable = Observable.fromIterable(repoNames);
repoNames.add("Hello");
gitHubRepoModelObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onNext(String s) {
System.out.println(s);
}
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
});
repoNames is just a list of string. When I am adding a string "hello" manually the onNext is getting called but when I am adding string from a API call like bellow
call.enqueue(new Callback<List<GitHubRepoModel>>() {
#Override
public void onResponse(Call<List<GitHubRepoModel>> call, Response<List<GitHubRepoModel>> response) {
for (GitHubRepoModel repo : response.body()) {
repoNames.add(repo.getName());
}
}
#Override
public void onFailure(Call<List<GitHubRepoModel>> call, Throwable t) {
}
});
I am adding strings from the API into the repoNames the "onNext" is not getting called.
I have seen
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
can be added while initializing retrofit but I want to better understand the rxjava so in this experiment it is not working.
Please help!
It can't not be work.
When you create you api request and try subscribe you list is emty, so Observable does not work.
You need to create Observable such, that your subcribe will run your request!
Observable<String> gitHubRepoModelObservable = Observable.create(
new Observable.OnSubscribe<String>() {
#Override
public void call(final Subscriber<? super String> sub) {
call.enqueue(new Callback<List<GitHubRepoModel>>() {
#Override
public void onResponse(Call<List<GitHubRepoModel>> call, Response<List<GitHubRepoModel>> response) {
for (GitHubRepoModel repo : response.body()) {
sub.onNext(repo.getName()); //send result to rx
}
sub.onCompleted();
}
#Override
public void onFailure(Call<List<GitHubRepoModel>> call, Throwable t) {
}
});
}
}
);
gitHubRepoModelObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
#Override
public void onNext(String s) {
System.out.println(s);
}
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
});
Why would onNext get called if you are just adding element to plain List?
In the first example you are seeing onNext being called because modified list is passed through the stream during subscribe.
Create Subject ex. PublishSubject and pass list to Subject.onNext in onResponse, subscribe to it and you will get what you want.
Second option is adding RxJava2CallAdapterFactory and return Observable<Response<List<GithubRepoModel>>>. This way you don't need to create stream yourself.

How do I pass JSON data to CalenderView onSelectedDayChange()?

I want to pass the data from the API (called using Retrofit) to calendar date onClick() event (onSelectedDayChange).
public class MainActivity extends AppCompatActivity {
List<APIData> dataList;
private CalendarView mCalendarView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCalendarView= findViewById(R.id.calendarView);
Calendar rightNow = Calendar.getInstance();
mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
#Override
public void onSelectedDayChange(#NonNull CalendarView view, int year, int month, int dayOfMonth) {
month = 1+month;
Toast.makeText(getApplicationContext(), ""+year+"-"+month+"-"+dayOfMonth,Toast.LENGTH_SHORT).show();
}
});
APIInterface apiInterface = APIClient.getClient().create(APIInterface.class);
Call<APIData> call = apiInterface.gethistorydetails("s10-1", "2018-08-01");
call.enqueue(new Callback<APIData>() {
#Override
public void onResponse(Call<APIData> call, Response<APIData> response) {
Log.d("TAG",response.code()+"");
APIData apiData = response.body();
}
#Override
public void onFailure(Call<APIData> call, Throwable t) {
}
});
}
}
As you can see in this pic, there are 4 different fields where I need to show data called from API. So whenever I click any dates on the calendar, the respective data from API should fill up the fields.
Assuming you are having all the 4 dates from APIData object. Convert the date(2018-09-09) into timeInMillis and set the date into calendarView on click of respective date fields:-
bus_arrival.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCalendarView.setDate(timeInMillis);
}
});
check_in.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCalendarView.setDate(timeInMillis);
}
});
In this use case you have to call the api every time whenever you change the date in calendar, This api will give you data in its response, simply set this data in your fields.
There are few steps to follow.
1- In datePicker dailog's onSelectedDayChange method you are getting "int year, int month, int dayOfMonth". Convert these fields into that date format that your API can understand.
To know how to convert these fields into date format follow this link
Creating java date object from year,month,day
2- Now call this APi , this api will return you result of those 4 fields in its response.
3- Simply display this data on those fields.
You code will be liked that
#Override
public void onSelectedDayChange(#NonNull CalendarView view, int year, int month, int dayOfMonth) {
Calendar cal= Calendar.getInstance();
cal.set(year, month - 1, dayOfMonth, 0, 0);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String date=format.formate(cal.getTime());
APIInterface apiInterface = APIClient.getClient().create(APIInterface.class);
Call<APIData> call = apiInterface.gethistorydetails("s10-1", date);
call.enqueue(new Callback<APIData>() {
#Override
public void onResponse(Call<APIData> call, Response<APIData> response) {
Log.d("TAG",response.code()+"");
APIData apiData = response.body();
// Here you will get data from this api and display it on your required fields
}
#Override
public void onFailure(Call<APIData> call, Throwable t) {
}
});

Resources