I have two classes in my android Java Project:
one is API which is inside a local android Module Library that has this code
package com.example.validationchecklib;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.widget.Toast;
import android.app.Application;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class API extends Application{
public static int result;
public static int resultInApi;
public int checkSubscription(String packageName, String purchaseCode, RequestQueue q) {
String apiUrl = "https://package.evisions.tech/check_validation.php?package_name=" + packageName;
// creating a new variable for our request queue
//RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
// in this case the data we are getting is in the form
// of array so we are making a json array request.
// below is the line where we are making an json array
// request and then extracting data from each json object.
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, apiUrl, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
//creating a new Json object and getting each
//object from our json array.
try {
// we are getting each json object.
JSONObject responseObj = response.getJSONObject(i);
// now we get our response from API in json object format.
// in below line we are extracting a string with
// its key value from our json object.
// similarly we are extracting all the strings from our json object.
String apiPackage = responseObj.getString("package_name");
String apiPurchaseCode = responseObj.getString("purchase_code");
int apiStatus = responseObj.getInt("status");
if (apiStatus == 1) {
if (apiPackage.equalsIgnoreCase(packageName) && apiPurchaseCode.equalsIgnoreCase(purchaseCode)) {
//subcription status is valid and user inputed data matches with api data
result = 1;
System.out.println("Result in Api = "+result);
break;
}
} else if (apiStatus == 0) {
result = 0;
System.out.println("Result in Api = "+result);
break;
} else {
result = 2;
System.out.println("Result in Api = "+result);
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
result = 3;
System.out.println("Result in Api = Failed to get the data...");
}
});
q.add(jsonArrayRequest);
return result;
}
}
The second class is MainActivity where I want to retrieve the value from the checkSubsccription() method that is on API class but I am getting 0 even when the request from volley has value 1.
You can test the request using this URL: https://package.evisions.tech/check_validation.php?package_name=aaaa
this is the code for MainActivity
package com.example.aaaa;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import com.example.validationchecklib.Subscription;
import com.example.validationchecklib.API;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
//Sample implementation of the Purchase validation android Library
public String packageName, purchaseCode;
public TextView txtPackageName, txtPurchaseCode;
public Button btnResult;
int serverResponse;
public String r;
private ArrayList<Subscription> subscriptionModalArrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
subscriptionModalArrayList = new ArrayList<>();
txtPackageName = findViewById(R.id.edtPackageName);
txtPurchaseCode = findViewById(R.id.edtPurchaseCode);
btnResult = findViewById(R.id.btnVerify);
RequestQueue queue = Volley.newRequestQueue(this);
API api = new API();
btnResult.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
packageName = txtPackageName.getText().toString().trim();
purchaseCode = txtPurchaseCode.getText().toString().trim();
serverResponse = api.checkSubscription(packageName,purchaseCode, queue);
System.out.println("Result = "+serverResponse);
if(api.result == 1){
subscriptionModalArrayList.add(new Subscription(packageName,purchaseCode));
Intent intent = new Intent(MainActivity.this, ValidationResult.class);
startActivity(intent);
}
if(api.result == 0){
Toast.makeText(MainActivity.this, "Inactive Subscription", Toast.LENGTH_LONG).show();
System.exit(1);
}
if(serverResponse == 2 || serverResponse == 3){
Toast.makeText(MainActivity.this, "Failed to fetch data from API or other Error...", Toast.LENGTH_LONG).show();
System.exit(1);
}
txtPackageName.setText("");
txtPurchaseCode.setText("");
}
});
}
}
The request you are making is asynchronous and you must wait to get the response from it.
The behavior you are seeing (always returning zero) because the result variable has not been initialized and defaults to zero.
public static int result;
You can pass a callback to your checkSubscription method which will be called when you have a result from the request (either failure or success).
You can do this by defining an interface like so:
public interface Callback {
public void onSuccess(int result);
public void onFailure(String error);
}
And making your activity implement this method:
public class MainActivity extends AppCompatActivity implements Callback {
...
public void onSuccess(int result) {
//Your logic here
}
public void onFailure(String error) {
//Your logic here
}
}
And make sure to pass the activity to your API:
public int checkSubscription(String packageName, String purchaseCode, RequestQueue q, Callback callback) {
.....
callback.onSuccess(result)
public void onErrorResponse(VolleyError error) {
result = 3;
System.out.println("Result in Api = Failed to get the data...");
callback.onError("YOUR_ERROR_MESSAGE");
}
}
Disclaimer : the above code is just a rough outline and should be
tested
Related
I have a MySQL database on a webserver and I read the data from this database in my application, but after I read the variables I can't use the "volt" variable outside the onPostExecute. I try t use adapter, but i can't use the data in the adapter like a intiger variable, just i can add to listview. So far i Don't find a solution for my problam.
I hope you can help me.
package com.example.wifis;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
public class MainActivity extends AppCompatActivity {
ListView listView;
ArrayAdapter<String> adapter;
// int tomb []={};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=(ListView)findViewById(R.id.list_item);
adapter= new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
listView.setAdapter(adapter);
new Conection().execute();
}
class Conection extends AsyncTask<String, String, String>{
#Override
public String doInBackground(String... strings) {
String result="";
String host="http://localhost/store/cars.php";
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(host));
HttpResponse response = client.execute(request);
BufferedReader reader= new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer stringBuffer= new StringBuffer("");
String line = "";
while ((line = reader.readLine()) !=null ){
stringBuffer.append(line);
break;
}
reader.close();
result = stringBuffer.toString();
}
catch (Exception e){
return new String("There exeption: "+ e.getMessage());
}
return result;
}
#Override
public void onPostExecute(String result){
// Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
JSONObject jsonResult = null;
try {
jsonResult = new JSONObject(result);
int success = jsonResult.getInt("success");
if(success==1){
JSONArray cars = jsonResult.getJSONArray("cars");
JSONObject car = cars.getJSONObject(0);
int id = car.getInt("id");
int volt = car.getInt("szam");
String line = id + "-" + volt;
adapter.add(line);
// tomb[0]=szam;
}else{
Toast.makeText(getApplicationContext(), "NOT OK ", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
As I have tried to explain in my post here
the values you're trying to access aren't synchronous, meaning that your code does not execute top down. The AsyncTask returns a value at some point. we don't know when that will be, but when it returns the value, you'll have access to it within onPostExecute. this means that you can make use of the values as they are received there and only there, as that is the only place where you'll actually receive those values.
to get this value returned to your main activity, you can do something like this :
create an interface
public interface MyCallback {
void myResult(YourResultType output); //here, i believe this will be string for your specific case
}
This interface allows us to move the value we receive to another class when it's received
Next,
Go to your AsyncTask class, and declare interface MyCallback as a variable :
public class MyAsyncTask extends AsyncTask<String, String, String> {
public MyCallback callback = null;
#Override
protected void onPostExecute(String result) {
callback.myResult(result);
}
}
#Override
protected void onPostExecute(String result) {
callback.myResult(result);
}
now for your main activity:
public class MainActivity implements MyCallback {
MyAsyncTask asyncTask = new MyAsyncTask();
#Override
public void onCreate(Bundle savedInstanceState) {
//set your listener to this class
asyncTask.callback = this;
//execute the async task
asyncTask.execute();
}
//this overrides the implemented method from asyncTask
#Override
void myResult(YourResultType output){
//Here you will receive the result returned from the async task
}
}
please also note that async tasks are deprecated
also note, my java is quite rusty, I am fortunate enough to only use kotlin these days, feel free to correct me on any mistakes :)
When tapping an image (from a previous activity) I get to this activity (where I pass the clientid) that reads a JSONArray and use a setter to set the nick.
I then use a getter to do a textview setText.
The problem is that the first time no nick is set. When I go back to the previous activity and tap the same image again, only then the nick is set.
Why isn't the nick displayed from the first time.
(ps: I'm quite new to Java/Android Studio)
package com.smartvibes.smartbeat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONException;
import org.json.JSONObject;
public class profileViewActivity extends AppCompatActivity {
RequestQueue rs;
String url, id, nick, age, city, mainpic, numpics, extrapic0, extrapic1, extrapic2, extrapic3, extrapic4, extrapic5;
TextView profileIntro;
static String pnick;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile_view);
Bundle getProfileId = getIntent().getExtras();
if (getProfileId == null) {
return;
}
String profileid = getProfileId.getString("profileid");
url = "https://www.smartvibes.be/profiles/api/profileview.php?id=" + profileid;
rs = Volley.newRequestQueue(this);
sendjsonrequest();
profileIntro = (TextView) findViewById(R.id.profileIntro);
profileIntro.setText(getPnick());
}
public void sendjsonrequest() {
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
setPnick(response.getString("nick"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
rs.add(jsonObjectRequest);
}
public static void setPnick(String nick) {
pnick = nick;
}
public static String getPnick(){
return pnick;
}
}
Because sendjsonrequest is an async call
You need to update textView in onResponse Method itself, like below
setPnick(response.getString("nick"));
profileIntro.setText(getPnick());
I have one method with this url:
String url = "http://brunos.000webhostapp.com/teste/obter_id.php?descricao=" + value;
And i want to return the result of this method.
i have tried the VolleyCallback callback but i cant send the value to the method
package com.example.fabio.domoticaa;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.EditText;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Divi_Dispo extends AppCompatActivity {
String x;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_divi__dispo);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
final String[] count = new String[1];
final String[] id = new String[1];
Intent intent = getIntent();
String value = intent.getStringExtra("divisao");
final EditText nomediv = (EditText) findViewById(R.id.editText4);
Count(value);
nomediv.setText(x);//want set th result of Count(value)
}
public void Count(String value) {
final String[] count = new String[1];
// Send data
try {
RequestQueue queue = Volley.newRequestQueue(Divi_Dispo.this);
String url = "http://brunos.000webhostapp.com/teste/obter_id.php?descricao=" + value ;
JsonArrayRequest jsonRequest = new JsonArrayRequest
(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
JSONObject jObj = new JSONObject(String.valueOf(response.get(0)));
count[0] = jObj.getString("COUNT(id)");//want return this valor
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
queue.add(jsonRequest);
} catch (Exception ex) {
} finally {
}
}
public interface VolleyCallback {
void onSuccess(String result);
}
}
package com.newsak.services;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.util.Log;
import com.android.volley.Cache;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.newsak.controller.NewsakContoller;
import com.newsak.data.FeedItem;
import com.newsak.parse.XmlParser;
import com.newsak.constants.SportsUrls;
public class FetchBackgroundData extends IntentService {
private List<FeedItem> feedItems;
public static List<FeedItem> largeFeedItems;
boolean cachedFalg = false;
public static final int FINISHED_STATE = 0;
ResultReceiver receiver;
int counter = 0 ;
public String [] MY_URLS = SportsUrls.SPORTS_URLS;
public FetchBackgroundData() {
super("FetchBackgroundData");
}
#Override
protected void onHandleIntent(Intent intent) {
receiver = intent.getParcelableExtra("receiver");
GO();
}
public void GO() {
feedItems = new ArrayList<FeedItem>();
largeFeedItems = new ArrayList<FeedItem>();
// check for the cache
Cache cache = NewsakContoller.getInstance().getRequestQueue().getCache();
List<Cache.Entry> entry = new ArrayList<Cache.Entry>();
for(String url : MY_URLS){
entry.add(cache.get(url));
}
for (Cache.Entry en : entry) {
if (en != null) {
// fetch the data from the cache ...
try {
String data = new String(en.data, "UTF-8");
feedItems = XmlParser.getItem(data);
largeFeedItems.addAll(feedItems);
cachedFalg = true;
Log.d("cache_start", "cache start");
if(feedItems.size() > 0){
counter++;
feedItems = null ;
if(counter == 7){
receiver.send(FINISHED_STATE, Bundle.EMPTY);
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
if (!cachedFalg) {
for(String url : MY_URLS){
getRequest(url);
}
Log.d("without_cache_start", "cache start");
}
}
public void getRequest(String url) {
StringRequest request = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
public void onResponse(String result) {
feedItems = XmlParser.getItem(result);
largeFeedItems.addAll(feedItems);
if(feedItems.size() > 0){
counter++;
feedItems = null ;
if(counter == 7){
receiver.send(FINISHED_STATE, Bundle.EMPTY);
}
}
}
}, new Response.ErrorListener() {
public void onErrorResponse(VolleyError arg0) {
}
});
//handle return twice data
request.setRetryPolicy(new DefaultRetryPolicy( 0,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES ,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
NewsakContoller.getInstance().addToRequestQueue(request);
}
}
this is my intentservice get the data by xml parser .
so can any one help me to figure what the problem is ?? I used this
Android volley sending data twice
but this solution doesn't wotk with my code
Your this code
request.setRetryPolicy(new DefaultRetryPolicy(
0,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Replace this code
request.setRetryPolicy(new DefaultRetryPolicy(
30000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
I am not sure what causing the request not to execute. I was trying to call a WCF Restful service in android, and I receive the error message "Request Error". Looking at the example, I don't see any reason why this example should not work. See below:
Here is the .Net Service:
[ServiceContract]
public interface ISampleService
{
[OperationContract]
[WebInvoke(
Method="POST", UriTemplate="/Login", BodyStyle= WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
string Login(string value);
}
public class SampleService : ISampleService
{
public string Login(string value)
{
string t = "";
try
{
//foreach (string s in value)
//{
// t = s;
//}
return t;
}
catch (Exception e)
{
return e.ToString();
}
}
}
Java:
package com.mitch.wcfwebserviceexample;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONStringer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity implements OnClickListener {
private String values ="";
Button btn;
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)this.findViewById(R.id.btnAccess);
tv = (TextView)this.findViewById(R.id.tvAccess);
btn.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
try
{
AsyncTaskExample task = new AsyncTaskExample(this);
task.execute("");
String test = values;
tv.setText(values);
} catch(Exception e)
{
Log.e("Click Exception ", e.getMessage());
}
}
public class AsyncTaskExample extends AsyncTask<String, Void,String>
{
private String Result="";
//private final static String SERVICE_URI = "http://10.0.2.2:8889";
private final static String SERVICE_URI = "http://10.0.2.2:65031/SampleService.svc";
private MainActivity host;
public AsyncTaskExample(MainActivity host)
{
this.host = host;
}
public String GetSEssion(String URL)
{
boolean isValid = true;
if(isValid)
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://10.0.2.2:65031/SampleService.svc/Login");
try
{
List<NameValuePair> value = new ArrayList<NameValuePair>(1);
value.add(new BasicNameValuePair("value", "123456"));
post.setEntity(new UrlEncodedFormEntity(value));
HttpResponse response = client.execute(post) ;
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line ="";
while((line = rd.readLine()) != null)
{
System.out.println(line);
}
}catch(Exception e)
{
Log.e("Error", e.getMessage());
}
}
return Result;
}
#Override
protected String doInBackground(String... arg0) {
android.os.Debug.waitForDebugger();
String t = GetSEssion(SERVICE_URI);
return t;
}
#Override
protected void onPostExecute(String result) {
// host.values = Result;
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
super.onCancelled();
}
}
}
I finally got it to work they way that I want it to. The issue was that I was building the Array this way (see below section 1) and pass it to the JSONObject or JSONArray. I switched and build the Array using JSONArray and pass it to the JSONObject (see section 2). It works like a charm.
Section1: Wrong way to do it - (It may work this way if you were to look through the array and put them in a JSONArray. It's will be too much work when it can be done directly.)
String[][] Array = {
new String[]{"Example", "Test"},
new String[]{"Example", "Test"},
};
JSONArray jar1 = new JSONArray();
jar1.put(0, Array);
// Did not work
Section 2: The way I did it after long hours of trying and some very helpful tips and hints from #vorrtex.
**JSONArray jar1 = new JSONArray();
jar1.put(0, "ABC");
jar1.put(1, "Son");
jar1.put(2, "Niece");**
**JSONArray jarr = new JSONArray();
jarr.put(0, jar1);**
JSONArray j = new JSONArray();
j.put(0,"session");
JSONObject obj = new JSONObject();
obj.put("value", jarr);
obj.put("test", j);
obj.put("name","myName");
Log.d("Obj.ToString message: ",obj.toString());
StringEntity entity = new StringEntity(obj.toString());
Looking at the web service, and it has exactly what I was looking for.
Thanks for you help!!!!