Android - Intent data after AsyncTask - android

Server connection is working on background (AsyncTask), and server response JSON.
I want to send data from server to other Activity, but it is not working.
I have tried to solve this but nothing work. How I can solve this?
My code is below:
public class LoginRequest extends AsyncTask<Void, Void, String> {
String errorMsg = LOGIN_ERROR;
String builder;
#Override
protected String doInBackground(Void... voids) {
JSONObject requestJsonObject = new JSONObject();
try {
requestJsonObject.put("email", userEmail);
requestJsonObject.put("password", userPassword);
} catch (JSONException e) {
e.printStackTrace();
}
requestQueue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.POST,
BASE_URL,
requestJsonObject,
response -> {
errorMsg = LOGIN_SUCCESS;
Log.d(TAG, "response = " + response);
builder = response.toString();
},
error -> errorMsg = LOGIN_ERROR
);
requestQueue.add(request);
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (errorMsg.equals(LOGIN_ERROR)) {
textViewError.setText(R.string.login_failure);
} else {
Toast.makeText(getApplicationContext(), "Login Success", Toast.LENGTH_SHORT).show();
// Send data from server to UserMainActivity
Intent intent = new Intent(LoginActivity.this, UserMainActivity.class);
intent.putExtra("serverMessage", builder);
startActivity(intent);
}
}
}

You should pass your activity context to your asyncTask and start Activity from that context
Your AsyncTask should look like this
private class LoginRequest extends AsyncTask<Void, Void, String> {
Context context;
LoginRequest(Context context)
{
this.context=context;
}
String builder;
#Override
protected String doInBackground(Void... voids) {
//your code here
return null;
}
#Override
protected void onPostExecute(String s) {
//your code here
Intent intent = new Intent(context, NewActivity.class);
intent.putExtra("serverMessage", builder);
context.startActivity(intent);
}
}
Call this asyncTask like this
LoginRequest asyncTaskForceUpdate=new LoginRequest(this);
asyncTaskForceUpdate.execute();

Try to change your code as below:
public class LoginRequest extends AsyncTask<Void, Void, String> {
String errorMsg = "ERROR";
String builder = "";
#Override
protected String doInBackground(Void... voids) {
JSONObject requestJsonObject = new JSONObject();
try {
requestJsonObject.put("email", userEmail);
requestJsonObject.put("password", userPassword);
} catch (JSONException e) {
e.printStackTrace();
}
requestQueue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.POST,
BASE_URL,
requestJsonObject,
response -> {
errorMsg = "SUCCESS";
Log.d(TAG, "response = " + response);
builder = response.toString();
},
error -> errorMsg = "ERROR"
);
requestQueue.add(request);
return errorMsg;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (s.equals("ERROR")) {
textViewError.setText(R.string.login_failure);
} else {
Toast.makeText(getApplicationContext(), "Login Success", Toast.LENGTH_SHORT).show();
// Send data from server to UserMainActivity
Intent intent = new Intent(LoginActivity.this, UserMainActivity.class);
intent.putExtra("serverMessage", builder);
startActivity(intent);
}
}
}
I changed the return value to errorMsg for doInBackground. As it is more common practice. Tell me if this does or doesn't work.

Related

Return response of Volley of Android [duplicate]

This question already has answers here:
Can I do a synchronous request with volley?
(8 answers)
Closed 4 years ago.
I have written a function that makes an HTTP request and the response stores in a Bundle to subsequently initialize an activity.
public static void communicate(final Context context, String url, final String typeResponse, final Intent intent) {
RequestQueue queue = Volley.newRequestQueue(context);
RequestFuture<String> future = RequestFuture.newFuture();
StringRequest stringRequest = new StringRequest(Request.Method.POST, BASE_URL + url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//Toast.makeText(context, response, Toast.LENGTH_SHORT).show();
Bundle bundle = new Bundle();
switch (typeResponse) {
case "text":
bundle.putString("response", response);
break;
case "json":
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray names = jsonObject.names();
for (int i = 0; i < names.length(); i++) {
//Toast.makeText(context, names.getString(i), Toast.LENGTH_SHORT).show();
bundle.putString(names.getString(i), jsonObject.getString(names.getString(i)));
}
} catch (JSONException e) {
e.printStackTrace();
}
break;
}
intent.putExtras(bundle);
context.startActivity(intent);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(context, "error", Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("test", "hi!!");
return params;
}
};
queue.add(stringRequest);
}
But I want return the Bundle object for use that function like this:
Bundle myBundle = communicate('httl://qwe.asd', 'json')
How can I to modifier my function?
Thanks.
Volley request are asynchronous, so i recommend you put inner your onResponse other function to be process your bundle.
As well, you can create an interface to send your response in other place. Something like this
interface
public interface onResponseCallback {
void onResponse(Bundle bundle);
}
activity
public MyActivity extends AppCompatActivity implements onResponseCallback{
public void onCreate(Bundle....){
MyRequest myrequest = new MyRequest(this);
..}
public void onResponse(Bundle bundle){
//bundle argument is your response from request,
// do some with your response
Intent intent = new Intent....
intent.putExtras(bundle);
startActivity(intent);
}
}
Request class
public class MyRequest{
OnResponseCallback onResponseCallback= null;
public MyRequest(onResponseCallback onResponseCallback)
this.onResponseCallback = onResponseCallback;
}
public void communicate(final Context context, String url, final String typeResponse, final Intent intent) {
RequestQueue queue = Volley.newRequestQueue(context);
RequestFuture<String> future = RequestFuture.newFuture();
StringRequest stringRequest = new StringRequest(Request.Method.POST, BASE_URL + url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//Toast.makeText(context, response, Toast.LENGTH_SHORT).show();
Bundle bundle = new Bundle();
switch (typeResponse) {
case "text":
bundle.putString("response", response);
break;
case "json":
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray names = jsonObject.names();
for (int i = 0; i < names.length(); i++) {
//Toast.makeText(context, names.getString(i), Toast.LENGTH_SHORT).show();
bundle.putString(names.getString(i), jsonObject.getString(names.getString(i)));
}
} catch (JSONException e) {
e.printStackTrace();
}
break;
}
onResponseCallback.onResponse(bundle);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(context, "error", Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("test", "hi!!");
return params;
}
};
queue.add(stringRequest);
}
}
and if you dont like nothing of this, maybe you can use constants or put in sharedpreferences to save your bundle object.
I hope that helps you.

How can I post data with Volly and receive JSON object

I want to post an int to an https address and pass 3 JSON objects to text views and I can't get JSON results. I've tried to use methods in onResponse but it's not working. How can I POST an integer and parse some JSON objects to text views? I'm a beginner in Android developing and I don't know how to resolve this problem.
What's the problem? please help
if(isNetworkAvailable()){
RequestQueue queue = Volley.newRequestQueue(this);
String url = "https://example.com/api";
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response) {
try {
Log.d("Response", response);
} catch (JSONException e) {
e.printStackTrace();
alertUserAboutError();
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error
mStoreName.setText("Error");
}
}
) {
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("category_id", "28");
return params;
}
};
queue.add(postRequest);
}
Toast.makeText(this, "Network is unavailable!", Toast.LENGTH_LONG).show(); }
private void updateDisplay() {
mStoreName.setText(mStoreDetails.getStoreName());
mInstagram.setText(mStoreDetails.getInstagram());
mTelegram.setText(mStoreDetails.getTelegram());
}
private StoreDetails getStoreDetails(String jsonData) throws JSONException {
JSONObject JSONRequest = new JSONObject(jsonData);
StoreDetails storeDetails = new StoreDetails();
storeDetails.setStoreName(JSONRequest.getString("store_name"));
storeDetails.setInstagram(JSONRequest.getString("instagram"));
storeDetails.setTelegram(JSONRequest.getString("telegram"));
return storeDetails;
}
private boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}
private void alertUserAboutError() {
AlertDialogFragment dialog = new AlertDialogFragment();
dialog.show(getFragmentManager(), "error_dialog");
}
This works for me. Use an stringrequest to put the post data to the request. After onResponse was called I create an JSON-Object from the string:
public void doServerRequest(final Context context, final String url, final Map<String,String> postParameters, final HashMap<String,String> getParameters, final OnFinishTaskListener<String, JSONObject> listener){
Log.d(TAG,"Start new server request (" + url + ")");
StringRequest request = new StringRequest(Request.Method.POST, addParametersToUrl(url, getParameters), new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, response);
try {
JSONObject json = new JSONObject(response);
if (json.getInt(CODE_TAG) == 0){
listener.getResult(SUCCESS_TAG, json);
} else {
listener.getResult(ERROR_TAG, null);
}
} catch (Exception e){
e.printStackTrace();
listener.getResult(ERROR_TAG, null);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
listener.getResult(ERROR_TAG, null);
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
if(postParameters == null){
return new HashMap<String, String>();
}
return postParameters;
}
};
requestQueue.add(request);
}
This adds the get-Paramters to the URL (if exist):
private String addParametersToUrl(String url, HashMap<String,String> getParameters){
if(getParameters == null || getParameters.size() == 0){
return url;
}
Log.d(TAG,"Preparing URL: "+url);
StringBuilder stringBuilder = new StringBuilder(url);
stringBuilder.append("?");
int i = 0;
for (String key : getParameters.keySet()) {
if(i>0) stringBuilder.append("&");
stringBuilder.append(key).append("=").append(getParameters.get(key));
i++;
}
url = stringBuilder.toString();
Log.d(TAG,"Prepared URL: "+url);
return url;
}
I use this listener interface:
public interface OnFinishTaskListener<S,J> {
public void getResult(S string, J json);
}

Android Volley framework how to unit test

I use the volley framework for my controllers in an android application
One of my controllers is as below:
public class LoginApi extends AppCompatActivity {
private static final String LOGIN_URL = "example"
private static final int timeOutInMs = 10000;
private static final int numberOfTries = 1;
public LoginApi() {
}
public void doLogin(final Context context, JSONObject jsonObject) {
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, LOGIN_URL, jsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
User user=new User();
try {
user.setAccessToken(response.getString("access_token"));
user.setExpireToken(response.getString("expires_in"));
user.setRefreshToken(response.getString("refresh_token"));
user.setTokenType(response.getString("token_type"));
Intent intent=new Intent(context,MenuCustomer.class);
Gson myGson=new Gson();
String myJson = myGson.toJson(user);
intent.putExtra("myjson", myJson);
context.startActivity(intent);
} catch (JSONException e) {
e.printStackTrace();
}
Log.d("", "");
Toast.makeText(context, "Successfull login", Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("", "");
Toast.makeText(context, "Please enter a valid email and password", Toast.LENGTH_SHORT).show();
}
}) {
#Override
public Map<String, String> getHeaders() {
Map<String, String> map = new HashMap<>();
map.put("Accept", "application/json");
map.put("Content-Type", "application/json");
return map;
}
};
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(timeOutInMs, numberOfTries, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Singleton.getmInstance(context).addToRequestQueue(jsonObjectRequest);
}
}
I have tried to make mock classes (FakeHttpStack,FakeRequestQueue) and I tried to make tests from mock volley classes from here
I cant find a solution to unit test my class.

doinBackground cannot save field values

I'm trying to figure out reason doInBackground() cannot save field values. Even return value changes back to initial after return statement. I have initialed AsyncTask onCreate() in the main class. Everything works fine until onPostExecute().
Thanks in advance
private class UserRegisterTask extends AsyncTask<Void, Void, Boolean> {
JSONObject jsonObj;
String uuid;
String ok;
String errorMessage;
Boolean noErrors = false;
public UserRegisterTask() {
}
Here is doInBack...
#Override
protected Boolean doInBackground(Void... params) {
final String url = "https://webaddress/register.php";
final Context context = getContext();
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
jsonObj = new JSONObject(response);
String error = jsonObj.getString("error");
if (error.equals("false")) {
uuid = jsonObj.getString("unique_id");
noErrors = true;
Log.e("####ยค%", String.valueOf(noErrors.booleanValue()));
mEmail = jsonObj.getString("email");
ok = jsonObj.getString("ok");
} else {
errorMessage = jsonObj.getString("error_msg");
Log.d("XXXXXXXXXXXXX", errorMessage);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//mTextView.setText("That didn't work!");
Log.e("ERROR", error.getMessage());
error.printStackTrace();
}
})
{
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("password", mpassword);
params.put("email", mEmail);
return params;
}
};
AppController.getInstance().addToRequestQueue(stringRequest);
return noErrors;
}
And here is onPostExecute()
#Override
protected void onPostExecute(Boolean success) {
urt = null;
if (success.booleanValue()) {
Toast toast = Toast.makeText(getApplicationContext(), ok, Toast.LENGTH_LONG);
toast.show();
new Thread(new Runnable() {
public void run() {
new SendEmail(mEmail, sb.toString(), uuid);
}
}).start();
Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
intent.putExtra("email", mEmail);
startActivity(intent);
// finish();
} else {
Toast toast = Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_SHORT);
toast.show();
Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(intent);
}
}

async method is not running when clicking on button

There is a button in my app and when I click on it , it declares the method insertintodatabase. But, nothing is happening when I am clicking on it , even the log is not showing anything.
Where is the problem ? Please suggest.
private final OkHttpClient client = new OkHttpClient();
public void SignUp(View view)
{
insertToDatabase();
}
private void insertToDatabase(){
class SendPostReqAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute()
{
name = usernam.getText().toString();
pass = passw.getText().toString();
emails = email.getText().toString();
Log.e("GetText","called");
}
#Override
protected String doInBackground(String... params) {
String json = "";
try {
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("name", name);
jsonObject.accumulate("password", pass);
jsonObject.accumulate("email", emails);
json = jsonObject.toString();
Log.e("MYAPP", "getjson");
} catch (JSONException e) {
Log.e("MYAPP", "unexpected JSON exception", e);
}
try{
RequestBody formBody = new FormEncodingBuilder()
.add("result", json)
.build();
Request request = new Request.Builder()
.url("https://justedhak.comlu.com/receiver.php")
.post(formBody)
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
} catch (IOException e){
Log.e("MYAPP", "unexpected JSON exception", e);
}
return "success";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
}
php
$username= $_POST['username'];
$password= $_POST['password'];
$email= $_POST['email'];
$image =$_POST['image'];
$sql = "insert into USERS (username,password,email) values ('$username','$password','$email')";
if(mysqli_query($con,$sql)){
echo 'success';
}
else{
echo 'failure';
}
mysqli_close($con);
Because OkHttp supports asynchronous, I think you can also refer to the following way:
Let's assume you have mHandler = new Handler(Looper.getMainLooper()); inside onCreate
private void updateToDatabase() {
// POST request
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new FormEncodingBuilder()
.add("key1", "value1")
.add("key2", "value2")
.build();
Request request = new Request.Builder()
.url("http://...")
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(final Request request, final IOException e) {
mHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(mContext, e.toString(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onResponse(Response response) throws IOException {
mHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(mContext, response.body().string(), Toast.LENGTH_SHORT).show();
}
});
}
});
}
If you still want to use with AsyncTask, update your code as the following:
public class MainActivity extends AppCompatActivity {
...
public void SignUp(View view)
{
new SendPostReqAsyncTask().execute();
}
...
private class SendPostReqAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
name = usernam.getText().toString();
pass = passw.getText().toString();
emails = email.getText().toString();
Log.e("GetText", "called");
}
#Override
protected String doInBackground(String... params) {
String json = "";
try {
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("name", name);
jsonObject.accumulate("password", pass);
jsonObject.accumulate("email", emails);
json = jsonObject.toString();
Log.e("MYAPP", "getjson");
} catch (JSONException e) {
Log.e("MYAPP", "unexpected JSON exception", e);
}
try {
OkHttpClient client = new OkHttpClient();
RequestBody formBody = new FormEncodingBuilder()
.add("result", json)
.build();
Request request = new Request.Builder()
.url("https://justedhak.comlu.com/receiver.php")
.post(formBody)
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
} catch (IOException e) {
Log.e("MYAPP", "unexpected JSON exception", e);
}
return "success";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
}
}
}
Somewhere you have to create object of SendPostReqAsyncTask and call execute method passing arguments ...
// Example class
class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
// some code
}
// Call the execute method of Async Task
new DownloadFilesTask().execute(url1, url2, url3);
// Use like this ..
public class <Your Root class> extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
// some code
private final OkHttpClient client = new OkHttpClient();
public void SignUp(View view)
{
new SendPostReqAsyncTask().execute();
}
}
class SendPostReqAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute()
{
name = usernam.getText().toString();
pass = passw.getText().toString();
emails = email.getText().toString();
Log.e("GetText","called");
}
#Override
protected String doInBackground(String... params) {
String json = "";
try {
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("name", name);
jsonObject.accumulate("password", pass);
jsonObject.accumulate("email", emails);
json = jsonObject.toString();
Log.e("MYAPP", "getjson");
} catch (JSONException e) {
Log.e("MYAPP", "unexpected JSON exception", e);
}
try{
RequestBody formBody = new FormEncodingBuilder()
.add("result", json)
.build();
Request request = new Request.Builder()
.url("https://justedhak.comlu.com/receiver.php")
.post(formBody)
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
} catch (IOException e){
Log.e("MYAPP", "unexpected JSON exception", e);
}
return "success";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
}
}

Categories

Resources