I'm using Retrofit library for Android.
I'm trying to connect server, sending post request and well everything, But when i'm trying to get responce.body, i get the following answer :
2020-07-04 21:37:45.931 18419-18419/com.androidapplications.mymetroword D/otvet: com.androidapplications.mymetroword.Posts#22bd74
My Pojo
public class Posts {
#SerializedName("email")
#Expose
private String email;
#SerializedName("password")
#Expose
private String password;
//getters and constructor
}
My Interface
public interface ApiServices {
#FormUrlEncoded
#POST("authuser")
Call<Posts> createPost(
#Field("email") String email,
#Field("password") String password
);
}
My MainActivity
public class MainActivity extends AppCompatActivity {
EditText email_add;
Button btn_sign_in;
EditText password;
SharedPreferences sharedPreferences;
public static final String BASE_URL = "https://shavkunov.tk/";
ApiServices apiServices;
public String stat_auth;
TextView msg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_in);
//some variables
}
public void postRequest() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
apiServices = retrofit.create(ApiServices.class);
Call<Posts> call = apiServices.createPost("1naesis#gmail.com", "1");
call.enqueue(new Callback<Posts>() {
#Override
public void onResponse(Call<Posts> call, Response<Posts> response) {
if (response.isSuccessful()) {
switch (response.code()) {
case 200 :
Log.d("otvet", "" + response.body());
break;
case 201 :
break;
}
}
else {
Toast.makeText(MainActivity.this, "упс", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<Posts> call, Throwable t) {
Toast.makeText(MainActivity.this, "error: "+ t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public void onClickSignIn(View view) { //текст-кнопка "
postRequest();
}
}
Please, help me)
You need to override the ToString() method in this class using the IDE or by typing it your self as now you are accessing the object allocation id and not the object values.
https://stackoverflow.com/a/10734148/13867485 look at this
Related
I am trying to save a message object in the firebase database, when I run the code I get no errors, everything looks to be fine but when I go to firebase website, nothing appears in the database
public class MainChatActivity extends AppCompatActivity {
private DatabaseReference mDatabaseReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_chat);
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendMessage();
}
});
}
private void sendMessage() {
String input = mInputText.getText().toString();
if(!input.equals("")){
InstantMessage chat=new InstantMessage(input, mDisplayName);
mDatabaseReference.child("children").push().setValue(chat);
mInputText.setText("");
}
}
}
public class InstantMessage {
private String message;
private String author;
public InstantMessage(String message, String author) {
this.message = message;
this.author = author;
}
public InstantMessage() {
}
public String getMessage() {
return message;
}
public String getAuthor() {
return author;
}
}
I expect to save the message with author name in a directory named "messages" in firebase, but that's not happening
Change your firebase database rules to the following:
{
"rules": {
".read": true
".write": true
}
}
It allows read/write access to all users under any conditions.
Warning: NEVER use this ruleset in production; it allows anyone to overwrite your entire database.
try this:
public class MainChatActivity extends AppCompatActivity {
private DatabaseReference mDatabaseReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_chat);
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendMessage();
}
});
}
private void sendMessage() {
String input = mInputText.getText().toString();
if(!input.equals("")){
InstantMessage chat=new InstantMessage(input, mDisplayName);
String key = mDatabaseReference.push().getKey();
mDatabaseReference.child("messages").child(key).setValue(chat) //here you can add a Listener to check success;
mInputText.setText("");
}
}
}
public class InstantMessage {
private String message;
private String author;
public InstantMessage(String message, String author) {
this.message = message;
this.author = author;
}
public InstantMessage() {
}
public String getMessage() {
return message;
}
public String getAuthor() {
return author;
}
}
It seems its permission issue
Make sure you are permission for READ/WRITE on the database, check the rules and make them public
{
"rules": {
".read": true
".write": true
}
}
I’m developing Android app that’s based on a WordPress website, so I need to get a token to login the user to the app using the JWT method.
When I send a request, I don’t get any response from the server; probably there something wrong with my code. I installed the wordpress-rest-api plugin and jwt-auth-plugin on the website.
My code contains userModel.java which contains getters and setters for the user id, email, and token.
retroFitInterface.java:
#POST ("Authorization: Bearer")
Call<User> login (#Body Login login);
#GET ("secretinfo")
Call<ResponseBody>getSecret(#Header("Authorization")String authToken);
Login.java:
private String email,password;
public Login (String email,String password) {
this.email = email;
this.password = password;
}
}
MainActivity.java
Retrofit.Builder builder = new Retrofit.Builder().baseUrl("https://taqoh.com/wp-json/jwt-auth/v1/token").addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
RetroFitInterface retroFitInterface = retrofit.create(RetroFitInterface.class);
private Button button, button1;
private static String token;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.login_btn);
button1 = findViewById(R.id.get_token_btn);
}
private void login() {
Login login = new Login("isohunter1#hotmail.com", "qweqweqwe123");
Call<User>call = retroFitInterface.login(login);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.isSuccessful()) {
Toast.makeText(MainActivity.this, response.body().getEmail(), Toast.LENGTH_LONG).show();
token = response.body().getToken();
}
}
#Override
public void onFailure(Call<User> call, Throwable t) {
Toast.makeText(MainActivity.this, "error", Toast.LENGTH_LONG).show();
}
});
}
private void getSecret() {
Call<ResponseBody>secret = retroFitInterface.getSecret(token);
secret.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.login_btn) {
login();
} else if (v.getId() == R.id.get_token_btn) {
getSecret();
}
}
Basically this it the code structure, I would like to know how i can modify my codes so that I can get the value inside onResponse and returning it. As of now, my mainReply variable return "(blank)" but im expecting it to pass the data in the arraylist called details inside my onResponse segment. Rest assure, there are values returned as I have checked, but i just cant get the value to be passed out of the onResponse segment.
I have checked for alternatives and they mentioned to use interface. However, I do not know how to modify my codes to use the solution that mentioned interface and use of callBacks.
public class MainActivity extends AppCompatActivity {
EditText et_message;
FloatingActionButton fab_send;
API api;
ListView list_view_conversation;
List<ChatModel> list_chat = new ArrayList<>();
RevealDetailsCallbacks callback;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_message = (EditText) findViewById(R.id.et_message);
fab_send = (FloatingActionButton) findViewById(R.id.fab_send);
list_view_conversation = (ListView) findViewById(R.id.list_view_conversation);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
api = retrofit.create(API.class);
fab_send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//this method ultimately is to get response and send back to user
String s = et_message.getText().toString();
ChatModel model = new ChatModel(s, true);
list_chat.add(model);
new retrieveDetails().execute(list_chat);
et_message.setText("'");
}
});
}
public class retrieveDetails extends AsyncTask<List<ChatModel>, Void, String> {
String text = et_message.getText().toString();
String mainReply = "";
List<ChatModel> models;
List<String> details = new ArrayList<String>();
#Override
public String doInBackground(List<ChatModel>[] lists) {
Call<List<Patient>> call = api.getPatients();
models = lists[0];
call.enqueue(new Callback<List<Patient>>() {
public String reply;
#Override
public void onResponse(Call<List<Patient>> call, Response<List<Patient>> response) {
List<Patient> patients = response.body();
for (int i = 0; i < patients.size(); i++) {
if (patients.get(i).getNric().equals(text)) {
details.add("Name: " + patients.get(i).getName() + "\nNRIC: " + patients.get(i).getNric()
+ "\nDOB: " + patients.get(i).getDob() + "\nContact No: " + patients.get(i).getContactno());
}
}
this.mainReply = details.get(0);
Log.i("Here Log i", reply);
}
#Override
public void onFailure(Call<List<Patient>> call, Throwable t) {
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
return mainReply;//I want to reply with the data added into the details arraylist in the onResponse segment
}
#Override
public void onPostExecute(String s) {
ChatModel chatModel = new ChatModel(s, false);
models.add(chatModel);
CustomAdapter adapter = new CustomAdapter(models, getApplicationContext());
list_view_conversation.setAdapter(adapter);
}
}
}
If you wanted to modify your existing code, you would add an interface like the one I added up top (RevealDetailsCallbacks), pass it into the asynctask constructor, and run it. The code would look like this:
public class MainActivity extends AppCompatActivity {
//Interface callback here
interface RevealDetailsCallbacks {
public void getDataFromResult(List<String> details);
}
EditText et_message;
FloatingActionButton fab_send;
API api;
ListView list_view_conversation;
List<ChatModel> list_chat = new ArrayList<>();
RevealDetailsCallbacks callback;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_message = (EditText) findViewById(R.id.et_message);
fab_send = (FloatingActionButton) findViewById(R.id.fab_send);
list_view_conversation = (ListView) findViewById(R.id.list_view_conversation);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
this.callback = new RevealDetailsCallbacks() {
#Override
public void getDataFromResult(List<String> details) {
//Do stuff here with the returned list of Strings
}
};
api = retrofit.create(API.class);
fab_send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//this method ultimately is to get response and send back to user
String s = et_message.getText().toString();
ChatModel model = new ChatModel(s, true);
list_chat.add(model);
new retrieveDetails(callback).execute(list_chat);
et_message.setText("'");
}
});
}
public class retrieveDetails extends AsyncTask<List<ChatModel>, Void, String> {
String text = et_message.getText().toString();
String mainReply = "";
List<ChatModel> models;
List<String> details = new ArrayList<String>();
private RevealDetailsCallbacks listener;
retrieveDetails(RevealDetailsCallbacks listener){
this.listener = listener;
}
#Override
public String doInBackground(final List<ChatModel>[] lists) {
Call<List<Patient>> call = api.getPatients();
models = lists[0];
call.enqueue(new Callback<List<Patient>>() {
public String reply;
#Override
public void onResponse(Call<List<Patient>> call, Response<List<Patient>> response) {
List<Patient> patients = response.body();
for (int i = 0; i < patients.size(); i++) {
if (patients.get(i).getNric().equals(text)) {
details.add("Name: " + patients.get(i).getName() + "\nNRIC: " + patients.get(i).getNric()
+ "\nDOB: " + patients.get(i).getDob() + "\nContact No: " + patients.get(i).getContactno());
}
}
this.mainReply = details.get(0);
Log.i("Here Log i", reply);
if(listener != null) {
listener.getDataFromResult(details);
}
}
#Override
public void onFailure(Call<List<Patient>> call, Throwable t) {
//Don't make a toast here, it will throw an exception due to it being in doInBackground
//Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
return mainReply;//I want to reply with the data added into the details arraylist in the onResponse segment
}
#Override
public void onPostExecute(String s) {
ChatModel chatModel = new ChatModel(s, false);
models.add(chatModel);
CustomAdapter adapter = new CustomAdapter(models, getApplicationContext());
list_view_conversation.setAdapter(adapter);
}
}
}
However, there is no need for asynctask here since you are running Retrofit and calling .enqueue, which runs on a background thread. A simpler version would look like this:
public class MainActivity extends AppCompatActivity {
//Interface callback here
interface RevealDetailsCallbacks {
public void getDataFromResult(List<String> details);
}
//Keep your same variables here
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Same setup here
this.callback = new RevealDetailsCallbacks() {
#Override
public void getDataFromResult(List<String> details) {
//Do stuff here with the returned list of Strings
}
};
fab_send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Same setup here, then call the method
makeWebCalls();
}
});
}
private void makeWebCalls(){
Call<List<Patient>> call = api.getPatients();
models = lists[0];
call.enqueue(new Callback<List<Patient>>() {
#Override
public void onResponse(Call<List<Patient>> call, Response<List<Patient>> response) {
//Run your response code here. When done, pass to the callback
}
#Override
public void onFailure(Call<List<Patient>> call, Throwable t) {
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
You can just enqueue the Retrofit call immediately in the OnClick and handle its response there
fab_send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String text = et_message.getText().toString();
// if you're trying to filter data, add a parameter to getPatients()
api.getPatients().enqueue(new Callback<List<Patient>>() {
#Override
public void onResponse(Call<List<Patient>> call, Response<List<Patient>> response) {
// Here you have a full list of patients
final List<Patient> patients = response.body();
// adapter = new PatientAdapter(MainActivity.this, patients);
// mListView.setAdapter(adapter);
}
I would like to be able to get values from a server by using their API, to be able to do that I have to send an API-key and an API-Code in the header, I have tried with Retrofit to be able to use annotations but with no luck, so if anyone can look through the code and point me in the right direction, I would appreciate it!
Below I will add some code examples:
APIService
public interface APIService {
#GET("/temperature")
#Headers({"api-key: "my api key", "code: "my-api-code"})
Call<Post> getTemperature();
ApiUtils
public class ApiUtils {
private ApiUtils() {}
public static final String BASE_URL = "my url";
public static APIService getAPIService() {
return RetrofitClient.getClient(BASE_URL).create(APIService.class);
}
Retrofit Client
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
Main Activity
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private TextView mResponseTv;
private APIService mAPIService;
#NonNull
private CompositeDisposable mDisposables;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText titleEt = (EditText) findViewById(R.id.et_title);
final EditText bodyEt = (EditText) findViewById(R.id.et_body);
Button submitBtn = (Button) findViewById(R.id.btn_submit);
mResponseTv = (TextView) findViewById(R.id.tv_response);
mAPIService = ApiUtils.getAPIService();
mDisposables = new CompositeDisposable();
submitBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String title = titleEt.getText().toString().trim();
String body = bodyEt.getText().toString().trim();
if(!TextUtils.isEmpty(title) && !TextUtils.isEmpty(body)) {
sendPost(title, body);
}
}
});
}
public void showErrorMessage() {
Toast.makeText(this, R.string.mssg_error_submitting_post, Toast.LENGTH_SHORT).show();
}
public void getTemperature() {
mAPIService.getTemperature().enqueue(new Callback<Post>() {
#Override
public void onResponse(Call<Post> call, Response<Post> response) {
if (response.isSuccessful()) {
showResponse(response.body().toString());
}
}
#Override
public void onFailure(Call<Post> call, Throwable t) {
showErrorMessage();
}
});
}
If you use Retrofit 2 you can try this
public interface APIService {
#GET("/temperature")
Call<Post> getTemperature(#Header("api-key") String my_api_key, #Header("code") String my-api-code);
And pass codes in your call
It's the first time that I'm using this library, but I was following this video tutorial to send data through Fragments, but in my case, it's just Activities.. So this how I did
Activity that I'm sending data :
public void onClick(View view) {
String passing_data = new Gson().toJson(user);
BusStation.getBus().post(new MessageData(passing_data));
Intent intent = new Intent(activity,UserAdsView.class);
activity.startActivity(intent);
}
BusStation Class :
public class BusStation {
private static Bus bus = new Bus();
public static Bus getBus() {
return bus;
}
}
MessageData Class :
public class MessageData {
private String msgData;
public MessageData(String msgData) {
this.msgData = msgData;
}
public String getMsgData() {
return msgData;
}
}
And finally at the UserAdsView Activity :
#Override
protected void onResume() {
super.onResume();
BusStation.getBus().register(this);
}
#Override
protected void onPause() {
super.onPause();
BusStation.getBus().unregister(this);
}
#Subscribe
public void recievedData(MessageData messageData){
target = messageData.getMsgData();
Toast.makeText(getApplicationContext(), target, Toast.LENGTH_SHORT).show();
}
As was mentioned on video, this method recievedData should be fired!
When you send notification in first activity at that time, UserAdsView Activity is not registered hence there are no listeners for events.
At this line
BusStation.getBus().post(new MessageData(passing_data));
you are sending notification but there is nothing registered to receive this notification. i.e. UserAdsView Activity has not started yet.
If you need to pass data to activity at launch time, simply send it via
Intent.
add in file Gradle
dependencies {
compile 'com.squareup:otto:1.3.8'
}
Create class OttoBus
public class OttoBus {
private static Bus sBus;
public static Bus getBus() {
if (sBus == null)
sBus = new Bus();
return sBus;
}
}
Create Events Class when pass data in android
public class Events {
public static class FragmentActivityMessage {
private String message;
public FragmentActivityMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
public static class ActivityFragmentMessage {
private String message;
public ActivityFragmentMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
}
function pass data
public void sendMessageToFragment(View view) {
EditText etMessage = findViewById(R.id.activityData);
OttoBus.getBus().post(String.valueOf(etMessage.getText()));
}
function event getdata
#Subscribe
public void getMessage(Events.ActivityFragmentMessage message) {
TextView messageView = findViewById(R.id.message);
messageView.setText(message.getMessage());
}
You need to make your MessageData object parcelable.
Then in your onClick() :
public void onClick(View view) {
String passing_data = new Gson().toJson(user);
Bundle extras = new Bundle();
extras.putParcelable("key",new MessageData(passing_data));
Intent intent = new Intent(activity,UserAdsView.class);
intent.putExtras(extras)
activity.startActivity(intent);
}
Then in onCreate() of your UserAdsView Activity :
MessageData data = (MessageData)getIntent().getExtras().getParcelable("key");