I am trying to write an AsyncTask that will use the Google Places API to get nearby locations. The actual functionality is working correctly, however, when my task finishes the class variables locationNames and locationIDs aren't written to. I've tried the behavior in my code as both progress updates and as a post execute and neither work. How do I add Strings to my ArrayLists in MainActivity from the AsyncTask?
package billy.cs436.googleplaces;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Location;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
String searchURL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?";
private HttpURLConnection urlConnection = null;
Location mLocation;
ArrayList<String> locationNames;
ArrayList<String> locationIDs;
ArrayList<String> locationAddresses;
ArrayList<String> locInfo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
double latitude, longitude;
locationNames = new ArrayList<String>();
locationIDs = new ArrayList<String>();
locationAddresses = new ArrayList<String>();
locInfo = new ArrayList<String>();
// location
mLocation = new Location("");
// sample coordinates
latitude = 38.989697;
longitude = -76.937760;
mLocation.setLatitude(latitude);
mLocation.setLongitude(longitude);
// ASSEMBLE URL
searchURL += "location=" + latitude + "," + longitude + "&";
// radius
searchURL += "radius=100&";
// api key
searchURL += "key=" + getString(R.string.api_key);
// Fill locationNames and locationIDs
new findLocationsNearMe().execute(mLocation);
// NOW USE PLACE IDS TO REQUEST SPECIFIC INFO TO GET FULL ADDRESS
// new getAddresses().execute(locationIDs);
printInfo();
}
public class findLocationsNearMe extends AsyncTask<Location,String[],Void> {
#Override
protected Void doInBackground(Location... locations) {
JSONObject json = getJSON();
try {
JSONArray locationParser = json.getJSONArray("results");
for (int i = 1; i < locationParser.length(); i++) {
JSONObject locationInfo = locationParser.getJSONObject(i);
String[] loc = new String[2];
loc[0] = String.valueOf(locationInfo.get("name"));
loc[1] = String.valueOf(locationInfo.get("place_id"));
publishProgress(loc);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(String[]... value) {
String name = String.valueOf(value[0][0]);
String id = String.valueOf(value[0][1]);
Log.d("PROGRESS UPDATE: ", name + " " + id);
locationNames.add(name);
locationIDs.add(id);
}
protected JSONObject getJSON() {
String JSONresult;
try {
// make request
URL url = new URL(searchURL);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuilder builder = new StringBuilder();
if (inputStream == null) {
return null;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line + "\n");
}
if (builder.length() == 0) {
return null;
}
// return json object
reader.close();
JSONresult = builder.toString();
return new JSONObject(JSONresult);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
Log.d("JSON PROBLEM", "return new object failed!");
} finally {
if (urlConnection != null) urlConnection.disconnect();
}
return null;
}
}
public void printInfo() {
System.out.println("LocationNames: " + locationNames);
System.out.println("LocationIDs: " + locationIDs);;
}
}
The log shows the correct values for Names and IDs from the ProgressUpdate, but printInfo prints LocationNames: [] and LocationIDs: []
EDIT 1:
Per the suggestion in the comments from #GhostCat, I implemented a NearbyLocation class and I also finished up my method to get addresses. Here is the full code. (I'm not sure if the correct procedure here is to replace my old code or post in this EDIT 1 format. If I should just delete the older code above to shorten this post let me know.)
package billy.cs436.googleplaces;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Location;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
String searchURL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?";
private HttpURLConnection urlConnection = null;
Location mLocation;
ArrayList<NearbyLocation> nearbyLocations;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
double latitude, longitude;
nearbyLocations = new ArrayList<>();
mLocation = new Location("");
// sample coordinates
latitude = 38.989697;
longitude = -76.937760;
mLocation.setLatitude(latitude);
mLocation.setLongitude(longitude);
// ASSEMBLE URL
searchURL += "location=" + latitude + "," + longitude + "&";
// radius
searchURL += "radius=100&";
// api key
searchURL += "key=" + getString(R.string.api_key);
// Fill locationNames and locationIDs
new findLocationsNearMe().execute(mLocation);
//NOW USE PLACE IDS TO REQUEST SPECIFIC INFO TO GET FULL ADDRESS
new getAddresses().execute();
printInfo();
}
public class findLocationsNearMe extends AsyncTask<Location,NearbyLocation,Void> {
#Override
protected Void doInBackground(Location... locations) {
JSONObject json = getJSON();
try {
JSONArray locationParser = json.getJSONArray("results");
for (int i = 1; i < locationParser.length(); i++) {
JSONObject locationInfo = locationParser.getJSONObject(i);
NearbyLocation loc = new NearbyLocation(String.valueOf(locationInfo.get("name")),
String.valueOf(locationInfo.get("place_id")), null);
publishProgress(loc);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(NearbyLocation... value) {
String name = value[0].getName();
String id = value[0].getId();
Log.d("PROGRESS UPDATE: ", name + " " + id);
nearbyLocations.add(value[0]);
}
protected JSONObject getJSON() {
String JSONresult;
try {
// make request
URL url = new URL(searchURL);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuilder builder = new StringBuilder();
if (inputStream == null) {
return null;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line + "\n");
}
if (builder.length() == 0) {
return null;
}
// return json object
reader.close();
JSONresult = builder.toString();
return new JSONObject(JSONresult);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
Log.d("JSON PROBLEM", "return new object failed!");
} finally {
if (urlConnection != null) urlConnection.disconnect();
}
return null;
}
}
public class getAddresses extends AsyncTask<Void, Void, Void> {
String detail = "https://maps.googleapis.com/maps/api/place/details/json?";
#Override
protected Void doInBackground(Void... voids) {
for(NearbyLocation loc : nearbyLocations) {
String detailURL = detail + "placeid=" + loc.getId() + "&key=" + getString(R.string.api_key);
JSONObject json = getJSON(detailURL);
JSONObject locationParser = null;
try {
locationParser = json.getJSONObject("result");
loc.setAddress(locationParser.get("formatted_address").toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
public JSONObject getJSON(String detailURL) {
String JSONresult;
try {
// make request
URL url = new URL(detailURL);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuilder builder = new StringBuilder();
if (inputStream == null) {
return null;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line + "\n");
}
if (builder.length() == 0) {
return null;
}
// return json object
reader.close();
JSONresult = builder.toString();
return new JSONObject(JSONresult);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
Log.d("JSON PROBLEM", "return new object failed!");
} finally {
if (urlConnection != null) urlConnection.disconnect();
}
return null;
}
}
public void printInfo() {
System.out.println("size... " + nearbyLocations.size());
for(NearbyLocation loc : nearbyLocations) {
System.out.println("LOCATION: " + loc.getName() + " " + loc.getAddress());
}
}
public class NearbyLocation {
String name;
String address;
String id;
public NearbyLocation(String name, String id, String address) {
this.name = name;
this.address = address;
this.id = id;
}
public void setName(String n) {
name = n;
}
public void setAddress(String a) {
address = a;
}
public void setId(String i) {
id = i;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public String getId() {
return id;
}
}
}
Related
I have built my app with one URL and it worked correctly. But there's a problem from the unmatched return of "onCreateLoader" method in the MainActivity.java.
I use a background thread to load all data without problems. The onCreateLoader method in MainActivity.java should return Loader> and there's a class NewsLoader.java that extends AsyncTaskLoader>.
I want to return new NewsLoader in the onCreateLoader method but there's an error of unmatched return for this method, even tough I have done this before in another similar app.
MainActivity.java
package com.example.newsapp;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.Loader;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.app.LoaderManager.LoaderCallbacks;
import android.app.LoaderManager;
import android.content.Context;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements LoaderCallbacks<List<Event>> {
private EventAdapter mAdapter;
private static final int LOADER_ID = 1;
private static final String REQUEST_URL_1 = "http://content.guardianapis.com/search?q=debates&api-key=test\n";
private static final String REQUEST_URL_2 = "https://content.guardianapis.com/search?q=debate&tag=politics/politics&from-date=2014-01-01&api-key=test\n";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView earthquakeListView = findViewById(R.id.list_of_news);
mAdapter = new EventAdapter(this, new ArrayList<Event>());
earthquakeListView.setAdapter(mAdapter);
earthquakeListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Event currentEvent = mAdapter.getItem(position);
assert currentEvent != null;
Uri eventUri = Uri.parse(currentEvent.getURL());
Intent websiteIntent = new Intent(Intent.ACTION_VIEW, eventUri);
startActivity(websiteIntent);
}
});
getLoaderManager().initLoader(LOADER_ID, null, this);
}
#NonNull
#Override
public Loader<List<Event>> onCreateLoader(int id, Bundle args) {
return new NewsLoader(MainActivity.this, REQUEST_URL_1, REQUEST_URL_2);
}
#Override
public void onLoadFinished(Loader<List<Event>> loader, List<Event> news) {
mAdapter.clear();
if (news != null && !news.isEmpty()) {
mAdapter.addAll(news);
}
}
#Override
public void onLoaderReset(Loader<List<Event>> loader) {
mAdapter.clear();
}
}
NewsLoader.java
package com.example.newsapp;
import android.content.Context;
import androidx.loader.content.AsyncTaskLoader;
import java.util.List;
public class NewsLoader extends AsyncTaskLoader<List<Event>> {
private static final String LOG_TAG = NewsLoader.class.getName();
private String mUrl1;
private String mUrl2;
public NewsLoader(Context context, String url1, String url2) {
super(context);
mUrl1 = url1;
mUrl2 = url2;
}
#Override
protected void onStartLoading() {
forceLoad();
}
#Override
public List<Event> loadInBackground() {
if (mUrl1 == null && mUrl2 == null) { return null; }
// Perform the network request, parse the response, and extract a list of earthquakes.
List<Event> news = QueryUtils.fetchNewsData(mUrl1, mUrl2);
return news;
}
}
QueryUtils.java
package com.example.newsapp;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class QueryUtils {
private static final String LOCATION_SEPARATOR = "T";
public static final String LOG_TAG = QueryUtils.class.getSimpleName();
private QueryUtils() {
}
public static List<Event> fetchNewsData(String requestUrl1, String requestUrl2) {
URL url1 = createUrl(requestUrl1);
URL url2 = createUrl(requestUrl2);
String jsonResponse1 = null;
String jsonResponse2 = null;
try {
jsonResponse1 = makeHttpRequest(url1);
jsonResponse2 = makeHttpRequest(url2);
} catch (IOException e) {
Log.e(LOG_TAG, "Problem making the HTTP request.", e);
}
List<Event> news = extractEvents(jsonResponse1, jsonResponse2);
return news;
}
public static List<Event> extractEvents(String eventJSON1, String eventJSON2) {
// verify that there's data in one link at list
if (TextUtils.isEmpty(eventJSON1) && TextUtils.isEmpty(eventJSON2)) {
return null;
}
List<Event> news = new ArrayList<>();
try {
//getting results array from first link
JSONObject baseJsonResponse1 = new JSONObject(eventJSON1);
JSONObject mainObject1 = baseJsonResponse1.getJSONObject("response");
JSONArray eventArray1 = mainObject1.getJSONArray("results");
//getting results array from second link
JSONObject baseJsonResponse2 = new JSONObject(eventJSON2);
JSONObject mainObject2 = baseJsonResponse2.getJSONObject("response");
JSONArray eventArray2 = mainObject2.getJSONArray("results");
// reading required data from array of first link
for (int i = 0; i<eventArray1.length(); i++){
JSONObject currentEvent = eventArray1.getJSONObject(i);
//getting url
String webUrl = currentEvent.getString("webUrl");
//getting title
String webTitle = currentEvent.getString("webTitle");
//getting sectionName
String sectionName = currentEvent.getString("sectionName");
//getting webPublicationDate
String webPublicationDate = currentEvent.getString("webPublicationDate");
String date = "0000 - 00 - 00";
String time = "00:00:00";
if (webPublicationDate.contains(LOCATION_SEPARATOR)) {
String[] parts = webPublicationDate.split(LOCATION_SEPARATOR);
date = parts[0];
time = parts[1].substring(0, parts[1].length() - 1);
}
// Make Quake Of the Strings And Assigning it to earthquakes ArrayList<Quake>
Event quake = new Event(sectionName, webTitle, date, time, webUrl);
news.add(quake);
}
// reading required data from array of first link
for (int i = 0; i<eventArray2.length(); i++){
JSONObject currentEvent = eventArray2.getJSONObject(i);
//getting url
String webUrl = currentEvent.getString("webUrl");
//getting title
String webTitle = currentEvent.getString("webTitle");
//getting sectionName
String sectionName = currentEvent.getString("sectionName");
//getting webPublicationDate
String webPublicationDate = currentEvent.getString("webPublicationDate");
String date = "0000 - 00 - 00";
String time = "00:00:00";
if (webPublicationDate.contains(LOCATION_SEPARATOR)) {
String[] parts = webPublicationDate.split(LOCATION_SEPARATOR);
date = parts[0];
time = parts[1].substring(0, parts[1].length() - 1);
}
// Make Quake Of the Strings And Assigning it to earthquakes ArrayList<Quake>
Event quake = new Event(sectionName, webTitle, date, time, webUrl);
news.add(quake);
}
} catch (JSONException e) {
Log.e("QueryUtils", "Problem parsing the news JSON results", e);
}
// Return the list of earthquakes
return news;
}
private static URL createUrl(String requestUrl) {
URL url = null;
try {
url = new URL(requestUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.connect();
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// function must handle java.io.IOException here
inputStream.close();
}
}
return jsonResponse;
}
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
}
I have found a solution.
the problem here is that Loader has been deprecated in 28-API. So, one cannot use androidx with it.
The solution here is in NewsLoader.java:
Replace: import androidx.loader.content.AsyncTaskLoader;
with: import android.content.AsyncTaskLoader;
If one needs to use a newer way: use ViewrModels
I am writing a currency exchange android app however when the app is run I do not seem to get a response from the API.
API LINK 1) https://restcountries.eu/rest/v2/all
API LINK 2) http://api.fixer.io/latest
MainActivity Code:
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import static java.lang.reflect.Modifier.FINAL;
public class MainActivity extends AppCompatActivity {
//Fill spinner with values from this URL - https://restcountries.eu/rest/v2/all
final String CURRENCY_DATA = "https://restcountries.eu/rest/v2/all";
ArrayList<String> currency_list = new ArrayList();
Button btn;
//The amount entered x's by the curreny exchange rate..
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new downloadData().execute();
new downloadExchangeRate().execute();
}
});
}
public class downloadData extends AsyncTask<String, Void, String> {
String result = "";
#Override
protected String doInBackground(String... strings) {
try {
URL url = new URL(CURRENCY_DATA);
HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
int data = inputStreamReader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = inputStreamReader.read();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(String s) {
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonArray = jsonObject.getJSONArray("currencies");
for (int i =0; i<jsonArray.length(); i++){
currency_list.add(jsonArray.getJSONObject(i).optString("code"));
Log.d("list", currency_list.toString());
}
} catch (JSONException e) {
e.printStackTrace();
}
super.onPostExecute(s);
}
}
}
downloadExchangeRate.java code:
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
public class downloadExchangeRate extends AsyncTask<String,Void,String> {
String result = "";
#Override
protected String doInBackground(String... strings) {
final String EXCHANGE_RATE = "http://api.fixer.io/latest";
try {
URL url = new URL(EXCHANGE_RATE);
HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
int data = inputStreamReader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = inputStreamReader.read();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(String s) {
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(result);
for (int i = 0; i<jsonObject.length(); i++){
ArrayList<String> rates = new ArrayList<>();
rates.add(jsonObject.optString("rates"));
Log.d("list", rates.toString());
}
} catch (JSONException e) {
e.printStackTrace();
}
super.onPostExecute(s);
}
}
Any help is appreciated, I think I am calling the JSON wrong.
Update Code as:
Use StringBuilder for result (Why? See this https://stackoverflow.com/a/14927864/5227589):
StringBuilder result=new StringBuilder();
...
......
result.append(current);
When using String it will take very long time to complete while loop due to use of result += current;: .
When using StringBuilder:
In onPostExecute
JSONArray jsonArray = new JSONArray(result.toString());
for (int i =0; i<jsonArray.length(); i++){
currency_list.add(jsonArray.getJSONObject(i).getJSONArray("currencies").getJSONObject(0).optString("code"));
//Log.d("list", currency_list.toString());
}
Full Code:
public class downloadData extends AsyncTask<String, Void, String> {
StringBuilder result=new StringBuilder();
#Override
protected String doInBackground(String... strings) {
try {
URL url = new URL(CURRENCY_DATA);
HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
int data = inputStreamReader.read();
char current = (char) data;
Log.i("data",current+"");
while (data != -1) {
current = (char) data;
result.append(current);
data = inputStreamReader.read();
// Log.i("data",current+"");
}
//Log.i("data",result+"");
} catch (IOException e) {
e.printStackTrace();
}
return result.toString();
}
#Override
protected void onPostExecute(String s) {
try {
JSONArray jsonArray = new JSONArray(result.toString());
for (int i =0; i<jsonArray.length(); i++){
currency_list.add(jsonArray.getJSONObject(i).getJSONArray("currencies").getJSONObject(0).optString("code"));
//Log.d("list", currency_list.toString());
}
Log.d("list", currency_list.toString());
} catch (JSONException e) {
e.printStackTrace();
}
super.onPostExecute(s);
}
}
Hi iam trying to post a simple json Object and get the results using Httpurlconnection. I tried but am not getting any error or any response. can some one help me to fix this. tnx.
RequestExternalResouce class
package sathyabamanan.com.duoproject.comman;
import android.content.Context;
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
/**
* Created by baman on 6/25/17.
*/
public class RequestExternalResouce extends AsyncTask<String, Void, String> {
private Context mContext;
private OnTaskDoneListener onTaskDoneListener;
private String urlStr = "";
private String requestBody = "";
public RequestExternalResouce(Context context, String url, String body, OnTaskDoneListener onTaskDoneListener) {
this.mContext = context;
this.urlStr = url;
this.requestBody= body;
this.onTaskDoneListener = onTaskDoneListener;
}
#Override
protected String doInBackground(String... params) {
try {
URL mUrl = new URL(urlStr);
HttpURLConnection httpConnection = (HttpURLConnection) mUrl.openConnection();
httpConnection.setRequestMethod("POST");
httpConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
httpConnection.setUseCaches(false);
httpConnection.setAllowUserInteraction(false);
httpConnection.setConnectTimeout(1000000);
httpConnection.setReadTimeout(1000000);
httpConnection.connect();
//get Response
int responseCode = httpConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
DataOutputStream localDataOutputStream = new DataOutputStream(httpConnection.getOutputStream());
localDataOutputStream.writeBytes(requestBody.toString());
localDataOutputStream.flush();
localDataOutputStream.close();
BufferedReader br = new BufferedReader(new InputStreamReader(httpConnection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
return sb.toString();
}
} catch (IOException e) { e.printStackTrace();
} catch (Exception ex) { ex.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (onTaskDoneListener != null && s != null) {
onTaskDoneListener.onTaskDone(s);
} else
onTaskDoneListener.onError();
}
public interface OnTaskDoneListener {
void onTaskDone(String responseData);
void onError();
}
}
Activity Methods
public void sendLloginRequest(View v){
login_email = email.getText().toString();
login_password = password.getText().toString();
String getLoginUrl = getRequestBody();
new RequestExternalResouce(context, new Utility().getLoginUrl(), getLoginUrl, new RequestExternalResouce.OnTaskDoneListener() {
#Override
public void onTaskDone(String responseData) {
System.out.println("Success : in activity"+ responseData);
}
#Override
public void onError() {
System.out.println("Error : ");
}
}).execute();
}
public String getRequestBody(){
JSONObject requestBody = new JSONObject();
JSONArray scopeArray = new JSONArray();
try {
scopeArray.put("all_all");
requestBody.put("userName", login_email);
requestBody.put("password", login_password);
requestBody.put("scope", scopeArray);
requestBody.put("console", "AGENT_CONSOLE");
requestBody.put("clientID", "e8ea7bb0-5026-11e7-a69b-b153a7c332b9");
} catch (JSONException e1) {
e1.printStackTrace();
}
return requestBody.toString();
}
JSon Object
{
"userName": "sathya#gmail.com",
"password": "AD123",
"scope": [
"all_all"
],
"console": "AGENT_CONSOLE",
"clientID": "e8ea7bb0-5026-11e7-a69b-b153a7c332b9"
}
Updated the class.
package sathyabamanan.com.duoproject.comman;
import android.content.Context;
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
/**
* Created by baman on 6/25/17.
*/
public class RequestExternalResouce extends AsyncTask<String, Void, String> {
private Context mContext;
private OnTaskDoneListener onTaskDoneListener;
private String urlStr = "";
private String requestBody = "";
public RequestExternalResouce(Context context, String url, String body, OnTaskDoneListener onTaskDoneListener) {
this.mContext = context;
this.urlStr = url;
this.requestBody= body;
this.onTaskDoneListener = onTaskDoneListener;
}
#Override
protected String doInBackground(String... params) {
try {
URL mUrl = new URL(urlStr);
HttpURLConnection httpConnection = (HttpURLConnection) mUrl.openConnection();
httpConnection.setRequestMethod("POST");
httpConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
httpConnection.setUseCaches(false);
httpConnection.setAllowUserInteraction(false);
httpConnection.setConnectTimeout(1000000);
httpConnection.setReadTimeout(1000000);
httpConnection.setDoOutput(true);
DataOutputStream localDataOutputStream = new DataOutputStream(httpConnection.getOutputStream());
localDataOutputStream.writeBytes(requestBody.toString());
localDataOutputStream.flush();
localDataOutputStream.close();
int responseCode = httpConnection.getResponseCode();
httpConnection.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(httpConnection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
if (responseCode == HttpURLConnection.HTTP_OK) {
return sb.toString();
}
} catch (IOException e) { e.printStackTrace();
} catch (Exception ex) { ex.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (onTaskDoneListener != null && s != null) {
onTaskDoneListener.onTaskDone(s);
} else
onTaskDoneListener.onError();
}
public interface OnTaskDoneListener {
void onTaskDone(String responseData);
void onError();
}
}
I am building an app that displays details of a book you have searched. The problem is that every time I change the orientation of my device the list view elements disappear. I want help in how to make them not disappear. I have a feeling that I need to use a Loader but I have no idea in how to implement it. Here are my activities.
MainActivity :-
package com.example.visha.booklistingapp;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private BookAdapter mAdapter;
EditText searchtext;
ListView earthquakeListView;
TextView empty;
TextView authorcheck;
TextView titlecheck;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
earthquakeListView = (ListView) findViewById(R.id.listView);
mAdapter = new BookAdapter(this, new ArrayList<Book>());
earthquakeListView.setAdapter(mAdapter);
searchtext = (EditText) findViewById(R.id.editText);
empty = (TextView) findViewById(R.id.textView);
earthquakeListView.setEmptyView(empty);
}
public void searchclick(View view) {
ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if(connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED ||
connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED) {
String parturl = searchtext.getText().toString();
parturl = parturl.replaceAll("\\s","");
StringBuilder urlbuilder = new StringBuilder();
urlbuilder.append(" https://www.googleapis.com/books/v1/volumes?q=");
urlbuilder.append(parturl);
urlbuilder.append("&maxResults=5");
String url = urlbuilder.toString();
BookAsyncTask task = new BookAsyncTask();
task.execute(url); }
else{
Toast.makeText(getApplicationContext(), "You are not connected to the internet",
Toast.LENGTH_LONG).show();
}
}
private class BookAsyncTask extends AsyncTask<String, Void, List<Book>> {
#Override
protected List<Book> doInBackground(String... urls) {
// Don't perform the request if there are no URLs, or the first URL is null
if (urls.length < 1 || urls[0] == null) {
return null;
}
List<Book> result = QueryUtils.fetchBookData(urls[0]);
return result;
}
#Override
protected void onPostExecute(List<Book> data) {
mAdapter.clear();
if (data != null && !data.isEmpty()) {
mAdapter.addAll(data);
}
}
}
}
QueryUtils :-
package com.example.visha.booklistingapp;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* Created by visha on 14-10-2016.
*/
public final class QueryUtils {
private static final String LOG_TAG = QueryUtils.class.getSimpleName();
private QueryUtils() {
}
public static List<Book> fetchBookData(String requestUrl) {
URL url = createUrl(requestUrl);
String jsonResponse = null;
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
Log.e(LOG_TAG, "Problem making the HTTP request.", e);
}
List<Book> Books = extractFeatureFromJson(jsonResponse);
return Books;
}
private static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Problem building the URL ", e);
}
return url;
}
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the Book JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
private static List<Book> extractFeatureFromJson(String BookJSON) {
if (TextUtils.isEmpty(BookJSON)) {
return null;
}
List<Book> Books = new ArrayList<>();
try {
JSONObject baseJsonResponse = new JSONObject(BookJSON);
JSONArray BookArray = baseJsonResponse.getJSONArray("items");
for (int i = 0; i < BookArray.length(); i++) {
JSONObject currentBook = BookArray.getJSONObject(i);
JSONObject properties = currentBook.getJSONObject("volumeInfo");
String author;
if(properties.has("authors")) {
author = properties.getString("authors");
}
else {
author = "";
}
String title = properties.getString("title");
Book Book = new Book(author, title);
Books.add(Book);
}
} catch (JSONException e) {
Log.e("QueryUtils", "Problem parsing the Book JSON results", e);
}
return Books;
}
}
You need to override onSaveInstanceState and onRestoreInstanceState methods of Activity Class.
In onSaveInstanceState, save the list data into the Bundle.
In onRestoreInstanceState, restore the list with the Bundle data and re-create the list adapter.
Cheers!!!
if you do not have a different layout for the activity landscape mode then simply putting android:configChanges="orientation|screenLayout|screenSize" will do the job for you.
Example:
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenLayout|screenSize" />
and if you do have different layout for landscape mode the you need to override the savedInstanceState and save and restore the list accordingly in OnCreate
I could retreive data from web with this code:
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick (View v){
new GetMethodDemo().execute("https://maps.googleapis.com/maps/api/directions/json?origin=Breclav&destination=Brno&sensor=false&units=metric&mode=driving");
}
public class GetMethodDemo extends AsyncTask<String , Void ,String> {
String server_response;
#Override
protected String doInBackground(String... strings) {
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(strings[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int responseCode = urlConnection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
server_response = readStream(urlConnection.getInputStream());
Log.v("CatalogClient", server_response);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.e("Response", "" + server_response);
}
}
private String readStream(InputStream in) {
BufferedReader reader = null;
StringBuffer response = new StringBuffer();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
response.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return response.toString();
} }
I am able to see in debug that I received data like in this link, but I found that I should use code below for selecting only distance from the data I received. Dont know how to combinate these codes together.. I would like to have in textView how far is the distance between two cities from url.
final JSONObject json = new JSONObject(response);
JSONArray routeArray = json.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONArray newTempARr = routes.getJSONArray("legs");
JSONObject newDisTimeOb = newTempARr.getJSONObject(0);
JSONObject distOb = newDisTimeOb.getJSONObject("distance");
JSONObject timeOb = newDisTimeOb.getJSONObject("duration");
Log.i("Diatance :", distOb.getString("text"));
Log.i("Time :", timeOb.getString("text"));
I am not the author of these codes... Thank You