How To Convert HttpURLConnection to Volley - java

I have google a lot but i can find solution about my issue my old code for call web service from my activity i have pass two parameter one is link means URL and second is parameters is for data i have to send to server.
problem is i have to use volley in place of following code
call retrieveStream("www.xyz.com/abc.php","data=dfsds");
public static String retrieveStream(String link, String parameters) {
try {
link = link.replace(" ", "%20");
URL url = new URL(link);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestMethod("POST");
OutputStreamWriter request = new OutputStreamWriter(
connection.getOutputStream());
request.write(parameters);
request.flush();
request.close();
String line = "";
InputStreamReader isr = new InputStreamReader(
connection.getInputStream());
BufferedReader reader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null) {
sb.append(line);
}
// Response from server after login process will be stored in
// response variable.
String response = sb.toString();
// You can perform UI operations here
isr.close();
reader.close();
return response;
} catch (IOException ignored) {
ignored.printStackTrace();
}
return "";
}`
I have implement in volley
StringRequest sr = new StringRequest(Request.Method.POST,
JSONUtils.WEB_SERVICE + "pausetest.php",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// mPostCommentResponse.requestCompleted();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// mPostCommentResponse.requestEndedWithError(error);
Toast.makeText(getActivity().getApplicationContext(),
error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("allanswer", alldata);
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
};
AppController.getInstance().addToRequestQueue(sr);`

FYI. This is assuming that your using application/x-www-form-urlencoded, as to a multi-part-form. I believe the Volley document/videos state somewhere that it is not meant for large data transfers.
I usually make a separate class for my various distinct Volley call, especially for restful processing or reuse as follows:
package com.your.package;
public class MyVolleyRequest1 {
public void myUniqueVolleyRequest(final String _parameter1, final String _parameter2) {
if (!isNetworkAvailable()) {
apiNetworkUnAvailableMsg("No network for this function.");
return;
}
RequestQueue queue = MyVolley.getRequestQueue();
StringRetroFIXRequest myReq = new StringRetroFIXRequest(Method.POST,
getMyContext().getString(R.string.http_url),
createMyReqSuccessListener(),
createMyReqErrorListener()) {
public Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("parameter 1", _parameter1);
params.put("parameter 2", _parameter2);
return params;
}
;
};
queue.add(myReq);
}
private Response.Listener<String> createMyReqSuccessListener() {
return new Response.Listener<String>() {
#Override
public void onResponse(String response) {
setResponseSuccess(response);
}
};
}
private Response.ErrorListener createMyReqErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
setResponseSuccess(error.toString());
}
};
}
private void setResponseSuccess(String result) {
EventBus.getDefault().post(new EventBusResultsClassResponseDone(result));
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getMyContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
private void apiNetworkUnAvailableMsg(String _purpose) {
String mReturn = "Internet connection unavailable. Try " + _purpose + " at a later time.";
EventBus.getDefault().post(new VolleyReturnEvent(mReturn));
}
}
I also use EventBus, so that I can loosely couple the return value(s), especially, if I decide I want to put those results into a model (pojo), like for using MVC/MVP type processing or say specialized processing of json, etc.
Optionally I also like to use OKHttp in combination Volley, here are the dependencies for gradle in Android Studio.
compile 'de.greenrobot:eventbus:2.1.0'
compile 'com.squareup.okio:okio:1.1.0'
compile 'com.squareup.okhttp:okhttp:2.2.0'
If you are just going to do restful processing Retrofit is a cool library.
Implementing in your Activity or Fragment you then define the above class and instantiate with the parameters, if needed. My example has 2 parameters. Then you implement EventBus, define the eventbus class, and include the return events via EventBus in your app, including the generic VolleyError which is returned as a separate event for error processing.
Here's a gist of what I'd put in my activity to call and then get responses from Volley/OKHttp.
#Override
protected void onResume() {
super.onResume();
EventBus.getDefault().register(this);
requestMyVolleyResponse1();
}
#Override
protected void onPause() {
EventBus.getDefault().unregister(this);
super.onPause();
}
private void requestMyVolleyResponse1() {
MyVolleyRequest1 mVolleyRequest1 = new MyVolleyRequest1();
mVolleyRequest1.MyVolleyRequest1("Parameter 1 value","Parameter 2 value");
}
public void onEventMainThread(MyVolleyRequest1Done event) {
// Your successful response processing.
}
public void onEventMainThread(VolleyReturnEvent event) {
// Your Error Processing
;
}
The EventBus return classes that you have to define (VolleyReturnEvent, MyVolleyRequest1Done) are really simple, i.e.
public class VolleyReturnEvent {
public final String message;
public VolleyReturnEvent(String message) {
this.message = message;
}
}

Related

How to implement LoginActivity in Android?

I'm trying to implement the premade LoginActivity in Android Studio to no avail. I'm stuck in the file LoginDataSource.java. Below is the class in it's entirety.
public class LoginDataSource {
public Result<LoggedInUser> login(final String username, final String password) {
try {
String url = "http://192.168.1.10:1234/my/api";
// Instantiate the RequestQueue.
RequestQueue requestQueue;
// Instantiate the cache
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
// Set up the network to use HttpURLConnection as the HTTP client.
Network network = new BasicNetwork(new HurlStack());
// Instantiate the RequestQueue with the cache and network.
requestQueue = new RequestQueue(cache, network);
requestQueue.start();
// 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) {
Log.i("Response:", response);
// Display the first 500 characters of the response string.
// textView.setText("Response is: " + response.substring(0, 500));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// textView.setText("That didn't work!");
Log.e("Error:", error.toString());
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("user", username);
params.put("pass", password);
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
};
requestQueue.add(stringRequest);
LoggedInUser fakeUser =
new LoggedInUser(
java.util.UUID.randomUUID().toString(),
"John Doe");
return new Result.Success<>(fakeUser);
} catch (Exception e) {
return new Result.Error(new IOException("Error logging in", e));
}
}
public void logout() {
// TODO: revoke authentication
}
}
getCacheDir() gets highlighted with red and the reason states Cannot resolve method 'getCacheDir' in 'LoginDataSource'. I tried changing the parameter to context.getCacheDir() but there's no context available in the file and I can't import one from anywhere.
What am I doing wrong here? This is driving me insane.
getCacheDir() has to be invoked on a Context object, so you need to pass in a Context into to login. So change login to login(final String username, final String password, final Context context)
and then invoke context.getCacheDir()

How do I make a call OK HttpRequest post from an isolated class using async?

I was using this in another place as async but I wanted to refactor to make it reusable, how can I reorganize the code in order to work as a consumable class?. It doesn't work if it's not async and the ip of the backend is well defined so it's not that. Any ideas?
public class HTTPRequestManager {
public static JSONArray fetchData(){
return null;
}
public static String postData(Context context, String url, String JSONData) {
return null;
}
/* #Override
protected Integer doInBackground(String... strings) {
try {
//1.create client Object
OkHttpClient client = new OkHttpClient();
//2.Define request being sent to server
RequestBody postData = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JSONData);
Request request = new Request.Builder()
.url(context.getResources().getString(R.string.backend_base_url) + url)
.post(postData)
.build();
//3.Transport the request and wait for response to process next
Response response = client.newCall(request).execute();
String resultData = response.body().string();
if (resultData.equals("OK")) {
} else {
//post failed
return "FAILED";
}
return resultData;
} catch (Exception e) {
Log.d("API_CONNECTION_ERROR", "Couldn't connect to the API");
return "API_CONNECTION_ERROR";
}
}*/
}
I used to have this annonymous class embeeded in another class and it works(it's a get request) but the problem is that it's not reusable in that way:
public class AsyncHttpTask extends AsyncTask<String, Void, Integer> {
URL url = null;
#Override
protected void onPreExecute() {
getActivity().setProgressBarIndeterminateVisibility(true);
}
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
url = new URL (getResources().getString(R.string.backend_base_url) +
"api/flrcks/user/id/0/latitude/3000/longitude/300/within/9999999999999999999999999");
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
parseResult(response.toString());
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(Integer result) {
// Download complete. Let us update UI
progressBar.setVisibility(View.GONE);
if (result == 1) {
adapter = new MyRecyclerAdapter_Nearby(getActivity(), feedsList);
mRecyclerView.setAdapter(adapter);
checkAdapterIsEmpty();
} else {
Toast.makeText(getActivity(), "Failed to fetch data!", Toast.LENGTH_SHORT).show();
t.setVisibility(View.VISIBLE);
}
}
private void parseResult(String result) {
try {
JSONObject response = new JSONObject(result);
JSONArray posts = response.getJSONArray("rows");
feedsList = new ArrayList<>();
JSONArray members;
for (int i = 0; i < posts.length(); i++) {
memberList = new ArrayList<>();
final JSONObject post = posts.optJSONObject(i);
members=post.getJSONArray("members");
final FeedItem item = new FeedItem();
//for (int i = 0; i < posts.length(); i++) {
//JSONObject post = posts.optJSONObject(i);
//FeedItem item = new FeedItem();
item.setId(post.optString("id"));
item.setTitle(post.optString("name"));
item.setDescription(post.optString("description"));
item.setPrivacy(post.optString("privacy_mode_description"));
item.setInitial_date(post.optString("initial_date"));
item.setThumbnail(post.optString("thumbnail"));
item.setColor_hex(post.optString("color_hex"));
item.setTag(post.optString("tag"));
item.setDistance(post.optInt("st_distance"));
//item.setThumbnail(post.optString("thumbnail"));
for(int k=0; k <members.length();k++)
{
MemberItem memberItem = new MemberItem();
JSONObject member = members.optJSONObject(k);
memberItem.setName(member.optString("name"));
memberItem.setUsername(member.optString("username"));
memberItem.setProfile_pic(member.optString("profile_pic"));
memberItem.setIs_moderator(member.optBoolean("is_moderator"));
memberItem.setFacebookId(member.optString("facebook_id"));
memberList.add(memberItem);
}
item.setMemberList(memberList);
feedsList.add(item);
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
}
What changes do I need to make to put it in an isolated file to be consumed by the whole app like for example in a file called OkHTTPRequests.class???
Create an interface
public interface OnWebResponseListener {
void onWebResponse(CommonUtilities.services service, String result);
}
create a public enum for identifying service. in my case i created a CommonUtilities java where i declared
public enum services {
LOGIN
}
Your Common File
public class CallAddr extends AsyncTask<String, Void, String> {
CommonUtilities.services service;
OnWebResponseListener onWebResponseListener;
String url;
FormBody.Builder body;
Request request;
OkHttpClient client;
final static String TAG = "CallAddr";
public CallAddr(Map<String, String> data, CommonUtilities.services service, OnWebResponseListener onWebResponseListener, String url) {
this.service = service;
this.onWebResponseListener = onWebResponseListener;
this.url = url;
body = new FormBody.Builder();
for (String key : data.keySet()) {
body.add(key, data.get(key));
}
client = new OkHttpClient();
}
#Override
protected String doInBackground(String... strings) {
String result = "";
request = new Request.Builder().url(url).post(body.build()).build();
try {
Response response = client.newCall(request).execute();
result = response.body().string();
} catch (Exception e) {
Log.e(TAG,Log.getStackTraceString(e));
}
return result;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (onWebResponseListener != null) {
onWebResponseListener.onWebResponse(service, s);
}
}
}

Parsing JSONArray using Gson + Volley not getting response

So I am trying to parse an array of objects from json using Google's Gson library and Volley for HTTP requests. My issue is it's as if the code isn't 'hitting' the OnResponse call. I've tried adding a simple Log printout within the function just to see if it does anything.
My GsonRequest class comes straight from Google's Training Docs. I constructed these methods based on an answer to this question.
This is my code:
private void runVolleyJson() throws AuthFailureError {
GsonRequest<Meetings> getMeetings = new GsonRequest<Meetings>(AUTH_URL, Meetings.class, getHeaders(),
createMyReqSuccessListener(),
createMyReqErrorListener());
helper.add(getMeetings);
}
private Response.Listener<Meetings> createMyReqSuccessListener() {
return new Response.Listener<Meetings>() {
#Override
public void onResponse(Meetings response) {
// NOTHING HAPPENS FROM HERE!
try {
Log.d("response", response.toString());
} catch (Exception e) {
e.printStackTrace();
}
// Do whatever you want to do with response;
// Like response.tags.getListing_count(); etc. etc.
}
};
}
private Response.ErrorListener createMyReqErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Do whatever you want to do with error.getMessage();
}
};
}
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> map = new HashMap<>();
map.put("Content-Type", "application/json;");
map.put("Authorization", "Bearer <sometoken>");
return map;
}
There is absolutely no error. It is authorizing the request, but nothing happens in OnResponse, it just seems to ignore that function.
Now I've tried using a standard StringRequest with volley and it works flawlessly, like this:
private void runVolleyTest() {
StringRequest request = new StringRequest(Request.Method.GET, AUTH_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonarray = new JSONArray(response);
for(int i = 0; i < jsonarray.length(); i++) {
Gson gson = new Gson();
Meeting m = gson.fromJson(jsonarray.get(i).toString(), Meeting.class);
Log.e("Meeting", m.getMeetingId() + " " + m.getStatus());
}
} catch (JSONException e) {
e.printStackTrace();
}
;
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
txtError(error);
}
}) {
#Override
public Map<String, String> getHeaders() {
HashMap<String, String> map = new HashMap<>();
map.put("Content-Type", "application/json;");
map.put("Authorization", "Bearer <sometoken>");
return map;
}
};
//request.setPriority(Request.Priority.HIGH);
helper.add(request);
}
Try adding this line at the beginning
RequestQueue helper = Volley.newRequestQueue(mContext);
Add these line
RequestQueue requestQueue = Volley.newRequestQueue(context);
requestQueue.add(stringRequest);
if you don't want to the save response in cache memory then add this
requestQueue.add(stringRequest);
According to my personal opinion its better if you pass the application context.

Android anonymous asyncTask return value in method

Now in my app i try to do http parsing from url, but i didn't carry about threads, before this time...
I have such class and method:
public class TwitterOAuthHelper {
public String httpQueryToApi(String url) {
HttpGet get = new HttpGet(url);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setUseExpectContinue(params, false);
get.setParams(params);
String response = null;
try {
SharedPreferences settings = context.getSharedPreferences("my_app", 0);
String userKey = settings.getString("user_key", "");
String userSecret = settings.getString("user_secret", "");
consumer.setTokenWithSecret(userKey, userSecret);
consumer.sign(get);
DefaultHttpClient client = new DefaultHttpClient();
response = client.execute(get, new BasicResponseHandler());
} catch (Exception e) {
displayToast("Failed to get data.");
}
return response;
}
}
and now i try to move this logic into asyncTask:
String result;
public String httpQueryToApi(String url) {
new AsyncTask<String,Void,String>(){
#Override
protected String doInBackground(String... params) {
HttpGet get = new HttpGet(String.valueOf(params));
HttpParams param = new BasicHttpParams();
HttpProtocolParams.setUseExpectContinue(param, false);
get.setParams(param);
String response = null;
try {
SharedPreferences settings = context.getSharedPreferences("my_app", 0);
String userKey = settings.getString("user_key", "");
String userSecret = settings.getString("user_secret", "");
consumer.setTokenWithSecret(userKey, userSecret);
consumer.sign(get);
DefaultHttpClient client = new DefaultHttpClient();
response = client.execute(get, new BasicResponseHandler());
} catch (Exception e) {
displayToast("Failed to get data.");
}
result = response;
return response;
}
}.execute(url);
return result;
}
but how can i return my response result value to method?
what is the best practice of doing that?
dd below method to asynctask body (below doInBackground method):
#Override
protected void onPostExecute(String result) {
// result is your returned value from doInBackground
// now we are in main ui thread
}
If you want a callback to antoher method it should be interface
public interface ResultInterface {
public void resultFromHttp(String result);
}
then your method
public String httpQueryToApi(String url, final ResultInterface ri){
//as bove
#Override
protected void onPostExecute(String result) {
if(ri!=null)
ri.resultFromHttp(result);
}
}
implement ResultInterface in your Activity/Fragment/whatever is calling httpQueryToApi, pass this as second param (ri interface)
You can't since the Task will be executed in another thread.
However you could use a callback to get the result.
Take a look at: https://stackoverflow.com/a/19520293/4299154.
Initially your function returned a string which you then further processed. Fine.
But you can not use threading like that. You can not return result from the function, because it has not been set yet (well you can but it will return null). The correct way of doing this is
public void httpQueryToApi(String url) {
new AsyncTask<String,Void,String>(){
#Override
protected String doInBackground(String... params) {
HttpGet get = new HttpGet(String.valueOf(params));
HttpParams param = new BasicHttpParams();
HttpProtocolParams.setUseExpectContinue(param, false);
get.setParams(param);
String response = null;
try {
SharedPreferences settings = context.getSharedPreferences("my_app", 0);
String userKey = settings.getString("user_key", "");
String userSecret = settings.getString("user_secret", "");
consumer.setTokenWithSecret(userKey, userSecret);
consumer.sign(get);
DefaultHttpClient client = new DefaultHttpClient();
response = client.execute(get, new BasicResponseHandler());
} catch (Exception e) {
displayToast("Failed to get data.");
}
return response;
}
#Override
protected void onPostExecute(String s) {
//here s is the response string, do what ever you want
super.onPostExecute(s);
}
}.execute(url);
}
You will have to shift your further processing logic to onPostExecute, no other way :)
If you want do dig a little deeper look into Future<>
1) Create separate class for you Async (not anonymous).
2) Create interface class.
public interface AsyncResponse {
void onProcessFinish(String output);
}
3) In your Async class, you need to declare it (interface : AsyncResponse):
public class MyAsyncTask extends AsyncTask<String,Void,String>(){
public AsyncResponse listener = null;
public MyAsyncTask(AsyncResponse l) {
this.listener = l;
}
{...}
#Override
protected String doInBackground(String... params) {
HttpGet get = new HttpGet(String.valueOf(params));
HttpParams param = new BasicHttpParams();
HttpProtocolParams.setUseExpectContinue(param, false);
get.setParams(param);
String response = null;
try {
SharedPreferences settings = context.getSharedPreferences("my_app", 0);
String userKey = settings.getString("user_key", "");
String userSecret = settings.getString("user_secret", "");
consumer.setTokenWithSecret(userKey, userSecret);
consumer.sign(get);
DefaultHttpClient client = new DefaultHttpClient();
response = client.execute(get, new BasicResponseHandler());
} catch (Exception e) {
displayToast("Failed to get data.");
}
result = response;
return response;
}
#Override
protected void onPostExecute(String result) {
listener.onProcessFinish(result);
}
}
4) In your class (where you call AssyncClass, for example in your Activity) you need to implements interface you created earlier AsyncResponse.
public class MainActivity implements AsyncResponse{
{...}
void onProcessFinish(String output){
//this you will received result fired from async class of onPostExecute(result) method.
}
}
6) now you can call in MainActivity:
new MyAsyncTask(this).execute("your_url");

Return data from AsyncTask class

How do I get the data from my AsyncTask? My MainActivity is calling the DataCall.getJSON function that triggers the AsyncTask but I am not sure how to get the data back to the original Activity.
MainActivity with call to DataCall that should return a string and save it in state_data
String state_data = DataCall.getJSON(spinnerURL,spinnerContentType);
DataCall:
public class DataCall extends Activity {
private static final String TAG = "MyApp";
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(
new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
protected void onPostExecute(String result) {
//THIS IS WHERE I NEED TO RETURN MY DATA TO THE MAIN ACTIVITY. (I am guessing)
}
}
public void getJSON(String myUrlString, String contentType) {
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { "http://www.mywebsite.com/" + myUrlString });
}
}
modify your AsyncTask as below:
public class GetData extends AsyncTask<String, Void, String>
{
DataDownloadListener dataDownloadListener;
public GetData()
{
//Constructor may be parametric
}
public void setDataDownloadListener(DataDownloadListener dataDownloadListener) {
this.dataDownloadListener = dataDownloadListener;
}
#Override
protected Object doInBackground(Object... param)
{
// do your task...
return null;
}
#Override
protected void onPostExecute(Object results)
{
if(results != null)
{
dataDownloadListener.dataDownloadedSuccessfully(results);
}
else
dataDownloadListener.dataDownloadFailed();
}
public static interface DataDownloadListener {
void dataDownloadedSuccessfully(Object data);
void dataDownloadFailed();
}
}
and use it in your Activity
GetData getdata = new GetData();
getdata.setDataDownloadListener(new DataDownloadListener()
{
#SuppressWarnings("unchecked")
#Override
public void dataDownloadedSuccessfully(Object data) {
// handler result
}
#Override
public void dataDownloadFailed() {
// handler failure (e.g network not available etc.)
}
});
getdata.execute("");
NOTE: For the people who are reading this.
Please consider this post for the best and perhaps right implementation.
The key for me was to create a class called URLWithParams or something because AsyncTask will allow only 1 type to be sent IN, and I needed both the URL and the params for the HTTP request.
public class URLWithParams {
public String url;
public List<NameValuePair> nameValuePairs;
public URLWithParams()
{
nameValuePairs = new ArrayList<NameValuePair>();
}
}
and then I send it to a JSONClient:
public class JSONClient extends AsyncTask<URLWithParams, Void, String> {
private final static String TAG = "JSONClient";
ProgressDialog progressDialog ;
GetJSONListener getJSONListener;
public JSONClient(GetJSONListener listener){
this.getJSONListener = listener;
}
#Override
protected String doInBackground(URLWithParams... urls) {
return connect(urls[0].url, urls[0].nameValuePairs);
}
public static String connect(String url, List<NameValuePair> pairs)
{
HttpClient httpclient = new DefaultHttpClient();
if(url == null)
{
Log.d(TAG, "want to connect, but url is null");
}
else
{
Log.d(TAG, "starting connect with url " + url);
}
if(pairs == null)
{
Log.d(TAG, "want to connect, though pairs is null");
}
else
{
Log.d(TAG, "starting connect with this many pairs: " + pairs.size());
for(NameValuePair dog : pairs)
{
Log.d(TAG, "example: " + dog.toString());
}
}
// Execute the request
HttpResponse response;
try {
// Prepare a request object
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(pairs));
response = httpclient.execute(httpPost);
// Examine the response status
Log.i(TAG,response.getStatusLine().toString());
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String json = reader.readLine();
return json;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String json ) {
getJSONListener.onRemoteCallComplete(json);
}
public interface GetJSONListener {
public void onRemoteCallComplete(String jsonFromNet);
}
}
Then call it from my main class like this
public class BookCatalog implements GetJSONListener {
private final String TAG = this.getClass().getSimpleName();
private String catalog_url = "URL";
private void getCatalogFromServer() {
URLWithParams mURLWithParams = new URLWithParams();
mURLWithParams.url = catalog_url;
try {
JSONClient asyncPoster = new JSONClient(this);
asyncPoster.execute(mURLWithParams);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onRemoteCallComplete(String jsonBookCatalogList) {
Log.d(TAG, "received json catalog:");
Log.d(TAG, jsonBookCatalogList);
JSONObject bookCatalogResult;
try {
bookCatalogResult = (JSONObject) new JSONTokener(jsonBookCatalogList).nextValue();
JSONArray books = bookCatalogResult.getJSONArray("books");
if(books != null) {
ArrayList<String> newBookOrdering = new ArrayList<String>();
int num_books = books.length();
BookCatalogEntry temp;
DebugLog.d(TAG, "apparently we found " + Integer.toString(num_books) + " books.");
for(int book_id = 0; book_id < num_books; book_id++) {
JSONObject book = books.getJSONObject(book_id);
String title = book.getString("title");
int version = book.getInt("price");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Although i disagree creating a new activity for that simple task there is
startActivityForResult()
to get data from another activity.
Check this. You can store your data to the Intent's extras. But still if you have a large amount of data you better off write it to a file get the result from the other activity that is done downloading and then read the file.
Serialize it and then read it. The only way I'm aware of.
Some options:
a) Make your bean implement Serializable interface, you can then pass your bean through Intent.
b) Implement Application interface (you need to make an entry in manifest), Have setter\getter method in your Application class. You can set your bean in Application from AsyncTask and later retrieve from Activity.
Sorry for answering so late, i think by this time you might have solved this problem. when i was searching for something else, i came across your question. I'm pasting a link here which might of some help for others.

Categories