I try to parse my JSON into my Java with Retrofit - java

I tried someone's tutorial to parse JSON in Java using retrofit.
I change the url in the tutorial with mine http://umkmkabupatenmalang.xyz/api/config/ . But when I try to run it on Android, I get an error like this
this is my MainActivity.java
import ...
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private ArrayList<AndroidVersion> data;
private DataAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view();
}
private void view(){
recyclerView = (RecyclerView)findViewById(R.id.card_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
loadJSON();
}
private void loadJSON(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://umkmkabupatenmalang.xyz/")
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface request = retrofit.create(RequestInterface.class);
Call<JSONResponse> call = request.getJSON();
call.enqueue(new Callback<JSONResponse>() {
#Override
public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
JSONResponse jsonResponse = response.body();
data = new ArrayList<>(Arrays.asList(jsonResponse.getAndroid()));
adapter = new DataAdapter(data);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call<JSONResponse> call, Throwable t) {
Log.d("Error", t.getMessage());
}
});
}
}
this is my json that i want to parse
can someone explain to me whats the error mean, and give a solution?
this is my JSONResponse
import com.example.skripsi.model.AndroidVersion;
public class JSONResponse {
private AndroidVersion[] android;
public AndroidVersion[] getAndroid() {
return android;
}
}

In your JSONResponse class, you should also provide a setter.
import com.google.gson.annotations.SerializedName;
import com.example.skripsi.model.AndroidVersion;
public class JSONResponse {
#SerializedName("data")
private AndroidVersion[] android;
public AndroidVersion[] getAndroid() {
return android;
}
public setAndroid(AndroidVersion[] androids){
this.android = androids;
}
}
Let me know if this works for you.

You can use this website to convert your JSON to java classes in the future
Convert JSON into java classes

Related

java.lang.IllegalArgumentException: HTTP method annotation is required (e.g., #GET, #POST, etc.).Error when trying call apiInterface GET request

I get error when trying to call API interface get request. I am trying to pass a value through GET method. But I get this error in logcat Caused by: java.lang.IllegalArgumentException: HTTP method annotation is required (e.g., #GET, #POST, etc.). for method ApiInterface.name
Here is my java code. Here I call the function namely getname()to pass a string value through GET request. Here I also have one more function getdata() which display output in the recyclerview.
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
ListAdapter1 listAdapter;
// List<SupermarketModels> supermarketModelsList = new ArrayList<>();
ApiInterface apiInterface;
String hi;
Button badd;
EmptyAdapterl emptyAdapter = new EmptyAdapterl();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
badd=findViewById(R.id.btadd);
badd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent= new Intent(MainActivity.this,Insert.class);
startActivity(intent);
}
});
String tablen= getIntent().getStringExtra("name");
// supermarketModelsList.add(new SupermarketModels(1,"sugar cane","20kg",
// "50rs","31/12/2021"));
//
// supermarketModelsList.add(new SupermarketModels(2,"sugar cane","20kg",
// "50rs","31/12/2021"));
// supermarketModelsList.add(new SupermarketModels(3 ,"sugar cane","20kg",
// "50rs","31/12/2021"));
initialization();
hi=tablen;
Toast.makeText(MainActivity.this,"oo"+hi,Toast.LENGTH_SHORT).show();
getname(hi);
// recyclerView.setAdapter(emptyAdapter);
// getdata();
}
private void initialization(){
recyclerView = findViewById(R.id.recyclerview1);
Retrofit retrofit = APIClient.getclient();
apiInterface = retrofit.create(ApiInterface.class);
// apiInterface = APIClient.getRetrofitInstance().create(ApiInterface.class);
}
private void setadapter(List<SupermarketModels> supermarketModels){
listAdapter = new ListAdapter1(this, supermarketModels,hi);
// LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
#SuppressLint("WrongConstant")
RecyclerView.LayoutManager lm = new LinearLayoutManager(getApplicationContext(), LinearLayout.VERTICAL, false);
recyclerView.setLayoutManager(lm);
// linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(lm);
recyclerView.setAdapter(listAdapter);
}
private void getname(String n) {
apiInterface.name(n).enqueue(new Callback<DeleteResponse>() {
#Override
public void onResponse(Call<DeleteResponse> call, Response<DeleteResponse> response) {
try {
if (response.body().getStatus().equals("1")){
Toast.makeText(MainActivity.this,"Successfully inserted",Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(MainActivity.this,"Error while inserting",Toast.LENGTH_SHORT).show();
}
} catch (Exception e){
}
}
#Override
public void onFailure(Call<DeleteResponse> call, Throwable t) {
}
});
}
private void getdata(){
apiInterface.getList().enqueue(new Callback<GetListResponse>() {
#Override
public void onResponse(Call<GetListResponse> call, Response<GetListResponse> response) {
try {
if (response!= null){
if (response.body().getStatus().equals("1")){
// category_adapter category_adapter = new category_adapter(getContext(),datalist);
setadapter(response.body().getData());
}
else {
Toast.makeText(MainActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e){
Log.e("exp", e.getLocalizedMessage());
}
}
#Override
public void onFailure(Call<GetListResponse> call, Throwable t) {
}
});
}
}
This is my apiInterface class
public interface ApiInterface {
#GET("user-controller.php?operation=list")
Call<GetListResponse> getList();
Call<DeleteResponse> name(#Field("name") String name1);
}
make sure you are using Retrofit2 in your #GET Imports (maybe you are using the wrong #Get)

Unable to call API from another class using retrofit

I am trying to call an API in APICaller.java from MainActivity.java. And then to put the data into recyclerview in MainActivity.java. However, it seems like it fails to call the API and restaurantList is empty. How can I go about to fix this? Thank you in advance.
MainActivity.java
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
List<Restaurant> restaurantList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
restaurantList = new ArrayList<>();
APICaller apiCaller = new APICaller();
apiCaller.getRestaurants(new APICaller.OnRestaurantListReceivedCallback() {
#Override
public void onRestaurantListReceived(List<Restaurant> list) {
String name = list.get(0).toString();
PutDataIntoRecyclerView(list);
}
});
}
private void PutDataIntoRecyclerView (List<Restaurant> restaurantList) {
Adapter adapter = new Adapter(this, restaurantList);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
}
APICaller.java
public class APICaller {
private List<Restaurant> restaurantList;
interface OnRestaurantListReceivedCallback{
void onRestaurantListReceived(List<Restaurant> list);
}
public void getRestaurants(OnRestaurantListReceivedCallback callback){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://example123.com/wp-json/wp/")
.addConverterFactory(GsonConverterFactory.create())
.build();
WordpressAPICall wordpressAPICall = retrofit.create(WordpressAPICall.class);
Call<List<Restaurant>> call = wordpressAPICall.getData();
call.enqueue(new Callback<List<Restaurant>>() {
#Override
public void onResponse(Call<List<Restaurant>> call, Response<List<Restaurant>> response) {
List<Restaurant> restaurantModels = response.body();
for(int i = 0; i < restaurantModels.size(); i++){
int id = restaurantModels.get(i).getId();
String title = restaurantModels.get(i).getTitle().getRendered();
restaurantList.add(restaurantModels.get(i));
}
callback.onRestaurantListReceived(restaurantList);
}
#Override
public void onFailure(Call<List<Restaurant>> call, Throwable t) {
Log.d("ON FAILURE API CALL", t.toString());
}
});
}

set value of a static field in Intent service

I have a static ArrayList categories in MainActivity. I want to load data to category in a IntentService which is call Retrofit 2 response.
when i debugged. Retrofit response work well it return a arraylist of category and add to categories but when I run the project the categories is null.
I donn't know why i get this error. Is there any way to fix it?
MainActivity.java
public class MainActivity extends AppCompatActivity {
public static final String TAG="MainActivity";
public static User user = new User();
public static ArrayList<Category> categories = new ArrayList<>();
private Context context;
TextView textCartItemCount;
AppInfomation appInfo;
Retrofit retrofit;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
appInfo = new AppInfomation(context);
retrofit = ApiClient.getApiClient();
Intent intent = new Intent(this, GetCategoryService.class);
startService(intent);
...
GetCategoryService.java.
public class GetCategoryService extends IntentService {
public GetCategoryService(){
super("GetCategoryService");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Retrofit retrofit = ApiClient.getApiClient();
Api api = retrofit.create(Api.class);
Call<ArrayList<Category>> getCategory = api.getCategories();
try {
Response<ArrayList<Category>> response = getCategory.execute();
for(Category c: response.body()){
MainActivity.categories.add(c);
}
} catch (IOException e) {
Log.d("GetCategoryService", "Cannot call API");
}
}
public void parseCategories(ArrayList<Category> cate){
MainActivity.categories = cate;
}
}

How to send 2 parameters in body with retrofit?

Good night everybody.
I need to do a POST request and I'm using Retrofit 2 to do this.
But the Api I'm consuming does not give me these parameters in the API response, just in the body.
Api Response
I already searched in some places but I did not find anything that could help me.
My interface Class
public interface LoginApi {
#POST("api/login")
Call<UserAccount> doLogin(#Body Login login);
}
My Model Class
public class Login {
public String user;
public String password;
}
My API response class
public class UserAccount {
#SerializedName("userId")
#Expose
private Integer userId;
#SerializedName("name")
#Expose
private String name;
#SerializedName("bankAccount")
#Expose
private String bankAccount;
#SerializedName("agency")
#Expose
private String agency;
#SerializedName("balance")
#Expose
private Double balance;
}
My call class
public class LoginPresenter {
private LoginView loginView;
private ServiceConfig serviceConfig;
public LoginPresenter() {
this.loginView = loginView;
if (this.serviceConfig == null) {
this.serviceConfig = new ServiceConfig();
}
}
public void doLogin(Login login) {
serviceConfig
.login()
.doLogin(login)
.enqueue(new Callback<UserAccount>() {
#Override
public void onResponse(Call<UserAccount> call, Response<UserAccount> response) {
UserAccount userAccount = response.body();
assert userAccount != null;
Log.e("Agency:",userAccount.getAgency());
Log.e("BankAccount:", userAccount.getBankAccount());
Log.e("Name:", userAccount.getName());
}
#Override
public void onFailure(Call<UserAccount> call, Throwable t) {
Log.d("Erro", t.getMessage());
}
});
}
}
My Activity
public class LoginActivity extends Activity implements LoginView {
private EditText edtUser, edtPassword;
private Button btnLogin;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
init();
}
private void init() {
edtUser = findViewById(R.id.edt_user);
edtPassword = findViewById(R.id.edt_password);
btnLogin = findViewById(R.id.btn_login);
final LoginPresenter loginPresenter = new LoginPresenter();
final Login login = new Login();
login.user = edtUser.getText().toString();
login.password = edtPassword.getText().toString();
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loginPresenter.doLogin(login);
}
});
}
#Override
public void userAccount(List<UserAccount> userAccount) {
}
}
I hope I have made my problem clear and that someone who has been through it can help me.
Appreciate.
Pass #Body JsonObject body instead of #Body Login login
Here is full code:
Your interface will be:
public interface LoginApi {
#POST("api/login")
Call<UserAccount> doLogin(#Body JsonObject body);
}
How to Create JsonObject :
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("user", userValue);
jsonObject.addProperty("password", passwordValue);
Pass it from your activity to presenter.
Hope it will works for you.
Thank you.
Pass Like This:-
You Interface
public interface ApiInterface {
String URL_BASE = "Base Url";
#Headers("Content-Type: application/json")
#POST("login")
Call<User> getUser(#Body String body);
}
Activity
public class SampleActivity extends AppCompatActivity implements Callback<User> {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiInterface.URL_BASE)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiInterface apiInterface = retrofit.create(ApiInterface.class);
// prepare call in Retrofit 2.0
try {
JSONObject paramObject = new JSONObject();
paramObject.put("email", "sample#gmail.com");
paramObject.put("pass", "4384984938943");
Call<User> userCall = apiInterface.getUser(paramObject.toString());
userCall.enqueue(this);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onResponse(Call<User> call, Response<User> response) {
}
#Override
public void onFailure(Call<User> call, Throwable t) {
}
}

need to wait answer from retrofit request in MainActivity

i have request in retrofit where return List which assign for my dataSet field. i did it in onResponse method. But initializing of recycle view in MainActivity is faster than request and view is showing nothing. What i can to do for waiting onResponse method.
I have this two methods in class NewsRepository.java
private void setNews(){
GetDataService service = RetrofitClientInstance.getRetrofitInstance().create(GetDataService.class);
Call<ItemsAPI> call = service.getAllItems();
call.enqueue(new Callback<ItemsAPI>() {
#Override
public void onResponse(Call<ItemsAPI> call, Response<ItemsAPI> response) {
Log.d(TAG, "onResponse");
items = response.body();
dataSet = items.getItems();
Log.d(TAG, dataSet.get(0).getTitle());
}
#Override
public void onFailure(Call<ItemsAPI> call, Throwable t) {
Log.d(TAG, "onFailure "+ t.getMessage());
}
});
}
public MutableLiveData<List<News>> getNews(){
setNews();
MutableLiveData<List<News>> data = new MutableLiveData<>();
data.setValue(dataSet);
return data;
}
And have this in MainActivityModelView.java
public void init(){
if(mNews != null){
return;
}
mRepo = NewsRepository.getInstance();
mNews = mRepo.getNews();
}
And this is MyActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private RecyclerView mRecycleView;
private RecycleViewAdapter mAdapter;
private MainActivityViewModel mMainActivityViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecycleView = findViewById(R.id.recyclev_view);
mMainActivityViewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
mMainActivityViewModel.init();
mMainActivityViewModel.getNews().observe((LifecycleOwner) this, new Observer<List<News>>() {
#Override
public void onChanged(#Nullable List<News> news) {
mAdapter.notifyDataSetChanged();
}
});
mMainActivityViewModel.getIsUpdating().observe((LifecycleOwner) this, new Observer<Boolean>() {
#Override
public void onChanged(#Nullable Boolean aBoolean) {
if(aBoolean){
}
else{
mRecycleView.smoothScrollToPosition(mMainActivityViewModel.getNews().getValue().size()-1);
}
}
});
initRecyclerView();
Log.d(TAG, "RecycleView is inited");
}
private void initRecyclerView(){
mAdapter = new RecycleViewAdapter(this, mMainActivityViewModel.getNews().getValue());
RecyclerView.LayoutManager linearLayoutManager = new LinearLayoutManager(this);
mRecycleView.setLayoutManager(linearLayoutManager);
mRecycleView.setAdapter(mAdapter);
}
}
The Activity is init is faster then my request.
2019-05-18 09:32:12.299 13859-13859/com.krasnov.rxjavalearning D/MainActivity: RecycleView is inited
2019-05-18 09:32:13.098 13859-13859/com.krasnov.rxjavalearning D/NewsRepository: onResponse
I think it's better to move this code above othre code below findViewById
initRecyclerView();
Log.d(TAG, "RecycleView is inited");
In this function its better to not use this constractor
mAdapter = new RecycleViewAdapter(this, mMainActivityViewModel.getNews().getValue());
Use this instead (create this constractor)
mAdapter = new RecycleViewAdapter(this);
And when your data arrive fire this function in adapter
public void setData( List<News> list) {
this.list= list
notifyDataSetChanged()
}
So your code is like
mMainActivityViewModel.getNews().observe((LifecycleOwner) this, new Observer<List<News>>() {
#Override
public void onChanged(#Nullable List<News> news) {
mAdapter.setData(news)
}
});
in your onResponse you should notify adapter add this:
yourAdapter.notifyDataSetChanged();
On resume call the retrofit service,
after response create a callback
method in ViewModel to notify in Activty class, after notified then
initialise recyclerview.
.

Categories

Resources