Overwriting the JsonHttpResponseHandler class to add a param pass to onSuccess - java

OK i am not sure if i am asking the right question, but this is the only way i can think of to fix my problem.
I have to call an API to get information that needs to be used inside of this method.
public void setBuses(JSONArray theBuses)
{
try {
for(int x = 0; x < theBuses.length() ; x++)
{
busExists = false;
if(x >= buses.size())
{
currentBus = new Bus();
}
else
{
busExists = true;
currentBus = buses.get(x);
currentMarker = busMarkers.get(x);
}
if(theBuses.getJSONObject(x).has("name"))
{
currentBus.setName(theBuses.getJSONObject(x).getString("name"));
}
if(theBuses.getJSONObject(x).has("driver"))
{
currentBus.setDriver(theBuses.getJSONObject(x).getString("driver"));
}
if(theBuses.getJSONObject(x).has("route"))
{
currentBus.setRoute(theBuses.getJSONObject(x).getString("route"));
}
if(theBuses.getJSONObject(x).has("active"))
{
currentBus.setActive(theBuses.getJSONObject(x).getBoolean("active"));
}
if(theBuses.getJSONObject(x).has("lastStop"))
{
currentBus.setLastStop(theBuses.getJSONObject(x).getString("lastStop"));
}
if(theBuses.getJSONObject(x).has("lastLong"))
{
currentBus.setLongi(theBuses.getJSONObject(x).getDouble("lastLong"));
}
if(theBuses.getJSONObject(x).has("lastLat")) {
currentBus.setLat(theBuses.getJSONObject(x).getDouble("lastLat"));
}
if(currentMarker != null)
{
currentMarker.remove();
}
if(currentBus.isActive())
{
BusStop nextStop = routes.getNextStop(currentBus.getLastStop(), currentBus.getRoute());
AsyncHttpClient client = new AsyncHttpClient();
client.setTimeout(5000);
client.get("https://maps.googleapis.com/maps/api/directions/json?origin="+currentBus.getLat()+"," +
""+currentBus.getLongi()+"&destination="+nextStop.getLat()+","+nextStop.getLongi()+"&departure_time=1541202457&traffic_model=best_guess&key=AIzaSyCADdN-VW0vFCKz4uWqdL97Idk8ezENfHk"
, new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject distanceObject) {
setBusHelper(distanceObject);
}
#Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
}
});
}
if(busExists) //this needs to be moved to the helper function and the varibles x, currentBus, mMap, and nextStop need to be passed to that function
{
Bus temp = buses.set(x,currentBus);
Marker tempM = busMarkers.set(x,currentMarker);
}
else
{
buses.add(currentBus);
busMarkers.add(currentMarker);
}
}
} catch (JSONException ex) {
ex.printStackTrace();
}
}
The pull from google calls this method to get the data from the API
private void setBusHelper(JSONObject distanceObject) {
String timeToNextStop = "Unknown";
try {
timeToNextStop = distanceObject.getJSONArray("routes").getJSONObject(0).getJSONArray("legs").getJSONObject(0).getJSONObject("duration").getString("text");
currentMarker = mMap.addMarker(new MarkerOptions().position(new LatLng(currentBus.getLat(), currentBus.getLongi())).title("Time to Next Stop:" + timeToNextStop).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)));
} catch (JSONException e) {
e.printStackTrace();
}
}
The problem i am having is since the call is aSync i don't have the marker to store in my array. I need to be able to pass the information i need for the adding of the marker and storage of the array to the onSuccess method in the JSONhandler. I have no idea how do this and i cant find any examples online. Any help you can provide would be very appreciated.
I will mention i have tried using SyncHttpClient but it does not seem to work synchronously.

OK so the answer was to not use AsyncHttpClient at all. I used AsyncTask to call Apaches HTTP client which kept everything in the same thread and allowed me to make multiple calls. Program is working great now.

Related

How to return value after calling web service in Util Class using Volley?

I want to return string value after getting response from web service in Volley and call value in activity.
Below is my code;
Utils.java
public static String getitemCountPrice(String cartId) {
try {
if (Utils.isNetworkAvailable(mContext)) {
HashMap<String, String> params = new HashMap<>();
params.put(CONSTANTS.API_param_cartid, cartId);
params.put(CONSTANTS.API_param_token, Utils.getToken());
JSONObject postdata = new JSONObject(params);
try {
YupITApplication.getJsonWithHTTPPostResponse(params, mContext, 1, (id, jsonResult) -> {
if (jsonResult.getString(mContext.getString(R.string.status)).equalsIgnoreCase(mContext.getString(R.string.success))) {
itemCountPrice = jsonResult.getJSONObject("Data").getString("Count") + ","
+ jsonResult.getJSONObject("Data").getString("TotalPrice");
Log.e("itemCountPrice.............", "" + itemCountPrice);
// Here I get value
} else {
itemCountPrice = "0,0";
}
}, Utils.cartitemcount, postdata);
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(mContext, mContext.getString(R.string.no_server_found), Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
return itemCountPrice;
// Here I get null and this is called before web service call
}
MainActivity.java
Utils.getitemCountPrice(cart_id));
Every time I get null from above method
Your return statement will execute right after the making the API call and wouldn't wait for the response because it is written in synchronous way. You can notify the result with help of an interface
interface APIListener{
public void onResponse(String itemPrice);
}
your method would look like this
public static void getitemCountPrice(String cartId, APIListener apiListener) {
try {
if (Utils.isNetworkAvailable(mContext)) {
HashMap<String, String> params = new HashMap<>();
params.put(CONSTANTS.API_param_cartid, cartId);
params.put(CONSTANTS.API_param_token, Utils.getToken());
JSONObject postdata = new JSONObject(params);
try {
YupITApplication.getJsonWithHTTPPostResponse(params, mContext, 1, (id, jsonResult) -> {
if (jsonResult.getString(mContext.getString(R.string.status)).equalsIgnoreCase(mContext.getString(R.string.success))) {
itemCountPrice = jsonResult.getJSONObject("Data").getString("Count") + ","
+ jsonResult.getJSONObject("Data").getString("TotalPrice");
Log.e("itemCountPrice.............", "" + itemCountPrice);
apiListener.onResponse(itemCountPrice);
// Here I get value
} else {
itemCountPrice = "0,0";
apiListener.onResponse(itemCountPrice);
}
}, Utils.cartitemcount, postdata);
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(mContext, mContext.getString(R.string.no_server_found), Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
You are mixing async call with sync call.
When you call method getItemCountPrice, you will actually receive your value from volley call when it will be available from network.
You need to use callback or some futurecall.
You can do it using callback like mentioned:
public static String getitemCountPrice(String cartId, onDataListener pDataListener) {
// some code
YupITApplication.getJsonWithHTTPPostResponse(params, mContext, 1, (id, jsonResult) -> {
if (jsonResult.getString(mContext.getString(R.string.status)).equalsIgnoreCase(mContext.getString(R.string.success))) {
itemCountPrice = jsonResult.getJSONObject("Data").getString("Count") + ","
+ jsonResult.getJSONObject("Data").getString("TotalPrice");
Log.e("itemCountPrice.............", "" + itemCountPrice);
// Here I get value
} else {
itemCountPrice = "0,0";
}
//pass value through callback
pDataListener.onItemCountPriceReceived(itemCountPrice)
}, Utils.cartitemcount, postdata);
// some code
}
Take one interface to pass data back to calling activity
interface OnDataListener{
void onItemCountPriceReceived(String itemCountPrice);
}
YourActivity code will look like this
Utils.getItemCountPrice(cart_id,new OnDataListener(){
#Override
void onItemCountPriceReceived(String itemCountPrice){
//you will get your value here when received from network call
}
})

How to correctly use HTTP POST method from android in the background

The task is simple, but I want to do it in the right way and I would love to hear your expert advice because I am novice in android developing.
First the application is just for me so I really don't care about security and stuff.
So my objective is like this:
I have a large amount of data that I want to transfer to my MYSQL database, the easiest way for me is to use HTTP POST method, but I am concerned about the part that the application may get stuck or some data won't pass because of the many POST requests that are gonna be.
So how exactly should I pass the data using POST request with insuring that all of the requests will be sent one by one without skipping any or losing data ?
Just the logic behind this would be enough I don't really need the code part.
Hopefully I was clear enough.
Retrofit FTW. Makes networking easy on Android (RESTful) and it include Gson.
Speaking of Gson... You mention you might be making many POSTs? If so, you should probably convert your data to JSON instead, and send it over the network that way. Google's Gson is a fantastic way to easily convert a Java object to JSON.
http://square.github.io/retrofit/
https://github.com/google/gson
Before reading: this is my way for implementing posts and gets, this is not the best way ever, but just the best way for my needs, feel free to edit/not use/implement it yourself
I personally prefer OkHTTP library, it is easy to use and easy to implement.
Implementation is really easy, just add this row in your Gradle app-level
implementation 'com.squareup.okhttp3:okhttp:3.9.0'
Then I created an helper class for get and post calls (I don't need many configurations, so a static one for me was enough, if you need more stuff you can easily implement. Also the timeouts are set for my needs and you can chenge them freely)
private String ConsumeGetRequest(String path) {
int tries = 0;
boolean isMyException = true;
while (tries <= 3 && isMyException) {
try {
isMyException = false;
tries++;
Response response = executeRequestBody(path, null);
if (response != null && response.body() != null)
return response.body().string();
else
return "";
} catch (ConnectException e) {
e.printStackTrace();
if (e.getMessage().contains("Failed to connect to") && tries <= 3) {
isMyException = true;
}
} catch (Exception ex) {
ex.printStackTrace();
return "";
}
}
return "";
}
private Pair<Boolean, String> ConsumePostRequest(String path, String postData) {
int tries = 0;
String errorMsg = null;
boolean isMyException = true;
//you can ignore this while, it was for our internal reasons and it's just a check.
while (tries <= 3 && isMyException) {
try {
isMyException = false;
tries++;
Response response = executeRequestBody(path, postData);
if (response != null && response.body() != null)
return new Pair<>(response.isSuccessful(), response.body().string());
else
return new Pair<>(false, null);
} catch (ConnectException e) {
errorMsg = e.getMessage();
if (e.getMessage().contains("Failed to connect to") && tries <= 3) {
isMyException = true;
}
} catch (Exception ex) {
errorMsg = ex.getMessage();
}
}
return new Pair<>(false, errorMsg);
}
private Response executeRequestBody(String path, String postData) throws IOException {
String url = String.format("%s%s/", RuntimeHelper._baseWebServiceIP, path);
if (okHttpClient == null) {
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.readTimeout(120, TimeUnit.SECONDS)
.build();
}
Request.Builder builder = new Request.Builder().url(url);
if (postData != null && !postData.isEmpty()) {
RequestBody body = RequestBody.create(RuntimeHelper._okHttpTypeJson, postData);
builder = builder.post(body);
}
Request request = builder.build();
return okHttpClient.newCall(request).execute();
}
with those two methods (a couple of examples) I create my path and I call the proper method for my needs.
//Post
public boolean setAlerts(String postData) {
String path = String.format("api/wfm/v1/set-alerts/%s/%s", authToken, resourceId);
return ConsumePostRequest(path, postData).first;
}
//Post
public String isAlertUpdated(String lastDownloadDate) {
String path = String.format("api/wfm/v1/is-alert-updated/%s/%s", authToken, lastDownloadDate);
return ConsumeGetRequest(path);
}
Then with an AsyncTask you can perform the operation without blocking UI
public class NewAlertAsyncTask extends AsyncTask<String, String, Boolean> {
Context context;
private WebApiMethodsController webApiMethodsController;
AuthenticatedUser authenticatedUser;
public NewAlertAsyncTask(Context ctx) {
this.context = ctx;
authenticatedUser = AuthenticatedUser.getIstance(context);
webApiMethodsController = new WebApiMethodsController(authenticatedUser.getAuthenticationTokenID().toString(), authenticatedUser.getResourceID().toString(), context);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
}
#Override
protected Boolean doInBackground(String... datas) {
Boolean result;
try {
result = webApiMethodsController.setAlerts(datas[0]);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return result;
}
#Override
protected void onPostExecute(Boolean s) {
if(s){
//manage succes, I use this
mCallback.onNewAlertCreated();
}
else{
//manage error
}
}
}
mine is a really simple structure, you can implement it with callbacks, status progress, deeper return status check, ...
You can simply call the asynctask with this
NewAlertAsyncTask newAlertAsyncTask = new NewAlertAsyncTask(getActivity());
newAlertAsyncTask.execute(gson.toJson(alertList));

keep data obtained in onResponse method available throughout the class

Basically in my android app I want user to search cities around the world, thus I am using an api to get all the cities of the world and storing in an ArrayList, this has been done in the onResponse method of okhttp library and after that the list becomes empty. This array list holds values only in onResponse but I want to use it in my entire class after the execution. Can anyone give me any ideas on that? Here is the code.
onCreate(){
OkHttpClient client = new OkHttpClient();
final Request request = new Request.Builder()
.url("https://raw.githubusercontent.com/David-Haim/CountriesToCitiesJSON/master/countriesToCities.json")
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
}
#Override
public void onResponse(Response response) throws IOException {
try {
fullObject = new JSONObject(response.body().string());
JSONArray s = fullObject.names();
for(int i=0; i<s.length(); i++) {
JSONArray citiesOfOneCoutry = null;
citiesOfOneCoutry = fullObject.getJSONArray(s.getString(i));
for(int j=0; j<citiesOfOneCoutry.length();j++) {
allCities.add(citiesOfOneCoutry.getString(j));
}
Log.d(TAG, "onResponse: in for "+allCities.size());
}
Log.d(TAG, "onResponse: outside for "+allCities.size()); //gives full size.
} catch (JSONException e) {
e.printStackTrace();
}
Log.d(TAG, "onResponse: outside try "+allCities.size()); //gives full size
}
});
Log.d(TAG, "outside response inside oncreate"+allCities.size()); //gives 0
}
I see in the logs that message from outside onResponse one is first and then the callback is getting executed. that is quite understandable but I want trick to get this ArrayList after response execution.
That is the nature of asynchronous operations, they don't complete in the order you wrote them. allCities data will not be available in your onCreate method because it hasn't had a chance to execute yet. The trick to using it outside of onResponse is to move the code that relies on the response to its own method.
private void updateUI() {
// Your code that relies on 'allCities'
}
and then in onResponse, call updateUI (or whatever you call it) after you populate allCities --
#Override
public void onResponse(Response response) throws IOException {
try {
fullObject = new JSONObject(response.body().string());
JSONArray s = fullObject.names();
for(int i=0; i<s.length(); i++) {
JSONArray citiesOfOneCoutry = null;
citiesOfOneCoutry = fullObject.getJSONArray(s.getString(i));
for(int j=0; j<citiesOfOneCoutry.length();j++) {
allCities.add(citiesOfOneCoutry.getString(j));
}
Log.d(TAG, "onResponse: in for "+allCities.size());
}
Log.d(TAG, "onResponse: outside for "+allCities.size()); //gives full size.
} catch (JSONException e) {
e.printStackTrace();
}
Log.d(TAG, "onResponse: outside try "+allCities.size()); //gives full size
updateUI();
}

Sending POST Request and Receive Json Responds using Retrofit Unable to use Responds data I need to pass it to another activity

I am using Retrofit for sending POST request.Server return's a JSON Response and i am able to parse the response in the callback method. I need to pass the data from server to another activity. But i can't use the response data outside.
api.LoginUser(
Email.getText().toString(), // passing value to interface of retrofit
Password.getText().toString(),
new Callback<Response>() {
#Override
public void success(Response result, Response response) {
BufferedReader reader = null;
String output = "";
try {
reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
output = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
//Json PArsing
try {
JSONObject mainObject = new JSONObject(output);
JSONObject dataObj = mainObject.getJSONObject("data");
String id = dataObj.getString("id");
String name = dataObj.getString("name");
n=name;
Log.d("jsontext", n); //This works
}
catch(JSONException e)
{
e.printStackTrace();
}
Toast.makeText(MainActivity.this, output, Toast.LENGTH_LONG).show();
}
#Override
public void failure(RetrofitError error) {
//If any error occured displaying the error as toast
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
}
}
);
I can't use this when it executes App crashes.its ok now there is no value in the variable.how to get values out of the callback Responds OnSuccess method???
Log.d("outer",n);
Intent dash = new Intent(this,Dashboard.class);
dash.putExtra("Value",fi);
startActivity(dash);
}
You can create an object and implement Serializable:
class User implements Serializable {
...
}
Then put object User to bundle, add to intent:
Bundle bundle = new Bundle();
bundle.putSerializable("data", user);
Intent intent = new Intent(this, YourClass.class);
intent.putExtras(bundle);
startActivity(intent);
Hope it help you.
Hold all data in a string and using intent app another activity and parse it;
You can do it as follows
public void onSuccess(int statusCode, Header[] headers,
byte[] response) {
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(new ByteArrayInputStream(
response)));
String st = "";
String st1 = "";
while ((st = br.readLine()) != null) {
st1 = st1 + st;
}
showStoreData(st1);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(int statusCode, Header[] headers,
byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
Log.e("FAIL", "FAIl" + statusCode);
}
#Override
public void onRetry(int retryNo) {
// called when request is retried
}
});
after that
public void showStoreData(String st) {
Intent intent = new Intent(this, YourClass.class);
intent.putExtras(st);
startActivity(intent);
}
You should use an interface that you initialize from the calling method and pass as a parameter into you request class, that way you can call the requests from anywhere and get the callback response back to where you called it from, an example would be:
A general interface, separated in another file:
public interface SomeCustomListener<T>
{
public void getResult(T object);
}
In the class holding your call (complete the stuff you need):
public void someRequestReturningString(Object param1, final SomeCustomListener<String> listener)
{
//here you initialize what you need... it's your stuff
response.enqueue(new Callback<ResponseBody>()
{
#Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> rawResponse)
{
try
{
String response = rawResponse.body().string();
// do what you want with it and based on that...
//return it to who called this method
listener.getResult("someResultString");
}
catch (Exception e)
{
e.printStackTrace();
listener.getResult("Error1...");
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable throwable)
{
try
{
// do something else in case of an error
listener.getResult("Error2...");
}
catch (Exception e)
{
throwable.printStackTrace();
listener.getResult("Error3...");
}
}
});
}
Then from where you're calling the request (could be anywhere, Fragments, onClicks, etc):
public class BlaBla
{
//.....
public void someMethod()
{
NetworkManager.getInstance().someRequestReturningString(someObject, new SomeCustomListener<String>()
{
#Override
public void getResult(String result)
{
if (!result.isEmpty())
{
//do what you need with the result...
}
}
});
}
}
If you need more context, you can refer to this SO thread.
Hope this helps!

How to get an android service return message from a phonegap plugin

I am trying to make a plugin for Phonegap (Android) that allows my javascript to send and receive messages to / from a service.
My exact problem is, that because the messages return asynchronous, I cannot send the PluginResult to the execute function of the plugin.
This is the plugin code:
public class ServiceClient_plugin extends Plugin {
Messenger messenger_service=null;
boolean connected_to_service=false;
final Messenger messenger_receive = new Messenger(new IncomingHandler());
#Override
public PluginResult execute(String action, JSONArray data, String callbackId) {
PluginResult result = null;
try {
if (action.toUpperCase().equals("CONNECT")) {
result = ConnectService();
} else if (action.toUpperCase().equals("DISCONNECT")) {
result = DisconnectService();
} else if (action.toUpperCase().equals("IS_CONNECTED")) {
result = new PluginResult(Status.OK,connected_to_service);
} else if (action.toUpperCase().equals("COMMAND")) {
sendMSG (data.getString(0));
result = new PluginResult(Status.OK);
} else {
result = new PluginResult(Status.INVALID_ACTION);
}
} catch(JSONException e) {
result= new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
return result;
}
private PluginResult ConnectService() {
doBindService();
return new PluginResult(Status.OK);
}
private PluginResult DisconnectService() {
doUnbindService();
return new PluginResult(Status.OK);
}
class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MoMe_Service.MSG_COMMAND:
Log.i("CLIENT","Received from service: " + msg.getData().getString("MSG"));
break;
default:
super.handleMessage(msg);
}
}
}
private ServiceConnection service_connection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
messenger_service = new Messenger(service);
connected_to_service=true;
try {
Message msg = Message.obtain(null, My_Service.MSG_REGISTERED);
msg.replyTo = messenger_receive;
messenger_service.send(msg);
} catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
messenger_service = null;
connected_to_service=false;
}
};
private void doBindService() {
// Establish a connection with the service. We use an explicit
// class name because there is no reason to be able to let other
// applications replace our component.
this.ctx.bindService(new Intent(this.ctx, My_Service.class), service_connection, Context.BIND_AUTO_CREATE);
}
private void doUnbindService() {
if (connected_to_service) {
if (messenger_service != null) {
try {
Message msg = Message.obtain(null, My_Service.MSG_UNREGISTERED);
msg.replyTo = messenger_receive;
messenger_service.send(msg);
} catch (RemoteException e) {
// There is nothing special we need to do if the service
// has crashed.
}
}
// Detach our existing connection.
this.ctx.unbindService(service_connection);
connected_to_service = false;
}
}
private void sendMSG (String message) {
try {
Message msg=Message.obtain(null, My_Service.MSG_COMMAND);
Bundle msg_bundle=new Bundle();
msg_bundle.putString("MSG", message);
msg.setData(msg_bundle);
messenger_service.send(msg);
} catch (RemoteException e) {
doUnbindService();
}
}
}
From this plugin the real trouble comes with this part of code, which handles the return messages and the plugin return (which goes to the javascript):
#Override
public PluginResult execute(String action, JSONArray data, String callbackId) {
PluginResult result = null;
try {
result = new PluginResult(Status.ok);
}
} catch(JSONException e) {
result= new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
return result;
}
class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MoMe_Service.MSG_COMMAND:
msg.getData().getString("MSG")); // THIS IS THE DATA I NEED RETURNED
break;
default:
super.handleMessage(msg);
}
}
}
The only solution I can think of, is storing the response in either a database or a variable and have the javascript do a setInterval to keep checking for changes. However I am not very fond of this solution. I would like to use some sort of callback function to let the javascript know the message has returned but I have no idea how. I would greatly appreciate any help and ideas.
Thank you,
Vlad
This might be a late answer but I started to work with Cordova Plugin around 5 months ago and I just saw your question. Since you did not choose the correct answer I wanted to answer your question.
Assuming you have asynchronous process and you have a listener and methods, success and fail , lets call it onSuccess() and onFail(). As long as you send true with pluginResult.setKeepCallback(true), the process will remain as unfinished, so you can send your plugin result data later on when you are done with background process. Here is an example take a look.
#Override
public boolean execute(String action, JSONArray data, String callbackId) throws JSONException {
if (action.equals("start")) {
start();
} else {
PluginResult pluginResult = new PluginResult(PluginResult.Status.INVALID_ACTION);
callbackContext.sendPluginResult(pluginResult);
return false;
}
}
private boolean start() throws JSONException {
MyClass.startProcess(new MyInterface() {
#Override
public void onSuccess(String data) {
PluginResult result = new PluginResult(PluginResult.Status.OK, data);
result.setKeepCallback(false);
callbackContext.sendPluginResult(result);
}
#Override
public void onFail() {
PluginResult result = new PluginResult(PluginResult.Status.ERROR);
result.setKeepCallback(false);
callbackContext.sendPluginResult(result);
}
});
PluginResult.Status status = PluginResult.Status.NO_RESULT;
PluginResult pluginResult = new PluginResult(status);
pluginResult.setKeepCallback(true);
callbackContext.sendPluginResult(pluginResult);
return true;
}
The answer to my problem was actually in the the PluginResult object and success method.
I've found a plugin that had to face the same problem in order to work, and from this code i was able to figure out my answer.This is a onPhoneStatusChange plugin, which can be found here!
The mystery lies in these lines:
PluginResult res = new PluginResult(PluginResult.Status.OK, obj);
res.setKeepCallback(true);
success(res, callbackId);
The generic solution to this problem is to have the service store the response into persistent storage (like a database) and then fire off a broadcast intent. Then just have a BroadcastReciever in your ServiceClient_plugin class listening for the broadcast. This way you woun't have to keep polling to see if the data has arrived yet.
You can send PluginResult using success() function like this:
public PluginResult execute(String action, JSONArray data, String callbackId) {}
private BroadcastReceiver Wifi_Receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
MyClass.this.success(new PluginResult(PluginResult.Status.OK,"count"+count),callback);
}
}
here callback is callbackId of execute() function

Categories

Resources