HttpURLconnection continuously returns error - Android - java

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();
}
}

Related

I am trying to get data from different URLs and load then on background

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

AsyncTask add to class ArrayList

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;
}
}
}

How do I ensure that my list view element do not disappear when I change the orientation of my device?

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

Android - get distance using google maps api and json

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

Android read json from restful service

I am trying to get a response from a service (the response comes in json).
I made my checks if the device is connected and now I need to make the http request to the service. I found out on other questions that I have to use a background thread but I am not sure I got a working sample.
So I need to find out how I can make a connection to a given uri and read the response.
My service needs to get a content header application/json in orderto return a json, so before the request I need to set this header as well.
Thank you in advance
UPDATE
package com.example.restfulapp;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.provider.Settings;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.ExecutionException;
public class MainActivity extends Activity {
private int code = 0;
private String value = "";
private ProgressDialog mDialog;
private Context mContext;
private String mUrl ="http://192.168.1.13/myservice/upfields/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (!isOnline())
{
displayNetworkOption ("MyApp", "Application needs network connectivity. Connect now?");
}
try {
JSONObject s = getJSON(mUrl);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public class Get extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... arg) {
String linha = "";
String retorno = "";
mDialog = ProgressDialog.show(mContext, "Please wait", "Loading...", true);
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(mUrl);
try {
HttpResponse response = client.execute(get);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) { // Ok
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
while ((linha = rd.readLine()) != null) {
retorno += linha;
}
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return retorno;
}
#Override
protected void onPostExecute(String result) {
mDialog.dismiss();
}
}
public JSONObject getJSON(String url) throws InterruptedException, ExecutionException {
setUrl(url);
Get g = new Get();
return createJSONObj(g.get());
}
private void displayNetworkOption(String title, String message){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder
.setTitle(title)
.setMessage(message)
.setPositiveButton("Wifi", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
}
})
.setNeutralButton("Data", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
startActivity(new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS));
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
return;
}
})
.show();
}
private boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
}
This throws errors:
Gradle: cannot find symbol method setUrl(java.lang.String)
Gradle: cannot find symbol method createJSONObj(java.lang.String)
After derogatory responses from EvZ who think that he was born knowing everything, I ended up with a subclass MyTask that I call like this inside the onCreate of my Activity.
new MyTask().execute(wserviceURL);
private class MyTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
URL myurl = null;
try {
myurl = new URL(urls[0]);
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection connection = null;
try {
connection = myurl.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
connection.setConnectTimeout(R.string.TIMEOUT_CONNECTION);
connection.setReadTimeout(R.string.TIMEOUT_CONNECTION);
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestProperty("Content-Type", getString(R.string.JSON_CONTENT_TYPE));
int responseCode = -1;
try {
responseCode = httpConnection.getResponseCode();
} catch (SocketTimeoutException ste) {
ste.printStackTrace();
}
catch (Exception e1) {
e1.printStackTrace();
}
if (responseCode == HttpURLConnection.HTTP_OK) {
StringBuilder answer = new StringBuilder(100000);
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(httpConnection.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
String inputLine;
try {
while ((inputLine = in.readLine()) != null) {
answer.append(inputLine);
answer.append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
httpConnection.disconnect();
return answer.toString();
}
else
{
//connection is not OK
httpConnection.disconnect();
return null;
}
}
#Override
protected void onPostExecute(String result) {
String userid = null;
String username = null;
String nickname = null;
if (result!=null)
{
try {
//do read the JSON here
} catch (JSONException e) {
e.printStackTrace();
}
}
//stop loader dialog
mDialog.dismiss();
}
}
lory105's answer guided me to somewhere near the answer, thanx.
here is an example of how to process the HTTP response and convert to JSONObject:
/**
* convert the HttpResponse into a JSONArray
* #return JSONObject
* #param response
* #throws IOException
* #throws IllegalStateException
* #throws UnsupportedEncodingException
* #throws Throwable
*/
public static JSONObject processHttpResponse(HttpResponse response) throws UnsupportedEncodingException, IllegalStateException, IOException {
JSONObject top = null;
StringBuilder builder = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
for (String line = null; (line = reader.readLine()) != null;) {
builder.append(line).append("\n");
}
String decoded = new String(builder.toString().getBytes(), "UTF-8");
Log.d(TAG, "decoded http response: " + decoded);
JSONTokener tokener = new JSONTokener(Uri.decode(builder.toString()));
top = new JSONObject(tokener);
} catch (JSONException t) {
Log.w(TAG, "<processHttpResponse> caught: " + t + ", handling as string...");
} catch (IOException e) {
Log.e(TAG, "caught: " + e, e);
} catch (Throwable t) {
Log.e(TAG, "caught: " + t, t);
}
return top;
}
From Android 3+, the http connections must be done within a separate thread. Android offers a Class named AsyncTask that help you do it.
Here you can find a good example of an AsyncTask that performs an http request and receives a JSON response.
Remember that in the doInBackgroud(..) method you CAN'T modify the UI such as to launch a Toast, to change activity or others. You have to use the onPreExecute() or onPostExecute() methods to do this.
ADD
For the mDialog and mContext variables, add the code below, and when you create the JSONTask write new JSONTask(YOUR_ACTIVITY)
public abstract class JSONTask extends AsyncTask<String, Void, String> {
private Context context = null;
ProgressDialog mDialog = new ProgressDialog();
public JSONTask(Context _context){ context=_context; }
..

Categories