Trying to connect with openweather api but SSLHandshakeException occurs - android

Here is how am trying to connect to openweathermap
public class MainActivity extends AppCompatActivity {
String jsonData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try{
JsonDownloader jsonDownloader = new JsonDownloader();
jsonData = jsonDownloader.execute("https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=439d4b804bc8187953eb36d2a8c26a02").get();
Log.i("Json data downloaded : ",jsonData);//trying to print json data to logcat
}catch (Exception e) {
e.printStackTrace();
}
}
//below is class to download json data
public class JsonDownloader extends AsyncTask<String,Void,String>{
URL url;
HttpURLConnection connection;
InputStream inputStream;
String jsonData;
#Override
protected String doInBackground(String... urls) {
try {
url = new URL(urls[0]);
connection = (HttpURLConnection) url.openConnection();
inputStream = connection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
int data = inputStreamReader.read();
while(data != -1){
char currentChar = (char)data;
jsonData+=currentChar;
data = inputStreamReader.read();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Exact Exception : java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Also i want to know is it okay to catch multiple exceptions with single 'Exception' class instead of exact exception type class.

Related

How to fix this error : org.json.JSONException: Expected literal value at character 0

I am building a weather app using api from openweathermap.org and when i run the program it shows an error.How to fix that?
I have created an account on openweathermap.org to create api key and used url="https://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=2ee7238c0e02a5b1efef8418a075c72c"
public class MainActivity extends AppCompatActivity {
public class DownloadTask extends AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... urls) {
URL url;
HttpURLConnection conn=null;
try {
String result="";
url=new URL(urls[0]);
conn=(HttpURLConnection) url.openConnection();
conn.connect();
InputStream is=conn.getInputStream();
InputStreamReader reader=new InputStreamReader(is);
int data=reader.read();
while(data!=-1){
char current=(char)data;
result=current+result;
data=reader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONObject json=new JSONObject(result);
String weatherInfo=json.getString("weather");
Log.i("Contents ",weatherInfo);
JSONArray arr=new JSONArray(weatherInfo);
for(int i=0;i<arr.length();i++){
JSONObject jsonPart=arr.getJSONObject(i);
Log.i("main",jsonPart.getString("main"));
Log.i("decription",jsonPart.getString("description"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadTask task=new DownloadTask();
try {
task.execute("https://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=2ee7238c0e02a5b1efef8418a075c72c").get();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output is:
org.json.JSONException: Expected literal value at character 0 of }002:"doc","nodnoL":"eman",3473462:"di",0063:"enozemit",}2114941651:"tesnus",8424341651:"esirnus","BG":"yrtnuoc",1900.0:"egassem",4141:"di",1:"epyt"{:"sys",1880741651:"td",}09:"lla"{:"sduolc",}033:"ged",1.3:"deeps"{:"dniw",00001:"ytilibisiv",}62.992:"xam_pmet",51.092:"nim_pmet",37:"ytidimuh",8101:"erusserp",24.592:"pmet"{:"niam","snoitats":"esab",]}"d01":"noci","niar thgil":"noitpircsed","niaR":"niam",005:"di"{[:"rehtaew",}15.15:"tal",31.0-:"nol"{:"drooc"{
Here is your problem:
InputStream is=conn.getInputStream();
InputStreamReader reader=new InputStreamReader(is);
int data=reader.read();
while(data!=-1){
char current=(char)data;
result=current+result; // <<==== HERE
data=reader.read();
}
Your code is storing the JSON in result in the reverse order!
Naturally, the reversed JSON is not parseable.
To fix this, change:
result = current + result;
to
result = result + current;
Or better still, use one of the "bulk read" options described in https://www.baeldung.com/java-convert-reader-to-string
(At least, wrap the Reader in a BufferedReader. Reading one character or byte at a time from an unbuffered input pipeline is very inefficient.)
The object you are trying to parse/read does not start with the character "{". And a JSON Object/file always starts with a "{"
result=current+result; // this line should be replaced
result += current; //-----by this line

Android - How to download a URL’s http contents which appear on scrolling down?

I have written an Android application to download HTTP contents of following URL: https://www.forbes.com/celebrities/list/
I want to use RegEx to extract image and name of the celebrities from HTML. But unfortunately, HTML content of celebrities list (<tr></tr> tags) only appears when user is “scrolling down”. In fact, my program doesn’t download any <tr></tr> tags inside <tbody> tag.
<tbody id="list-table-body">
</tbody>
How can I fix this problem?
DownloadWebContent Class:
public class DownloadWebContent extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
StringBuilder output = new StringBuilder();
try {
URL url = new URL(urls[0]);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
int read = inputStreamReader.read();
while (read != -1) {
char character = (char) read;
output.append(character);
read = inputStreamReader.read();
}
return output.toString();
} catch (Exception e) {
Log.i("HTML_Error", e.getMessage());
return "Failed!";
}
}
}
onCreate Method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.textView);
DownloadWebContent downloadWebContent = new DownloadWebContent();
try {
String htmlContent = downloadWebContent.execute("https://www.forbes.com/celebrities/list/").get();
String htmlContentReplaced= htmlContent.replace("\"", "");
textView.setText(htmlContentReplaced);
} catch (Exception e) {
e.printStackTrace();
}
}

method execute in AsyncTask does not work with String

I try to execute an AsyncTask like this
private static final String REQUESTED_URL = "//my url";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.earthquake_activity);
EarthQuakeAsyncTask task = new EarthQuakeAsyncTask();
task.execute(REQUESTED_URL); //this is where the error is
}
but Android Studio said that it cannot resolve method execute(String). I'm having a tutorial from Udacity, their sample is pretty much similar
/** URL for earthquake data from the USGS dataset */
private static final String USGS_REQUEST_URL =
"//url";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EarthquakeAsyncTask task = new EarthquakeAsyncTask();
task.execute(USGS_REQUEST_URL); //it works
}
Can someone tell me why this possibly occurs?
Edit: this is my EarthQuakeAsyncTask class:
private class EarthQuakeAsyncTask extends AsyncTask<URL,Void,ArrayList<EarthQuake>> {
#Override
protected ArrayList<EarthQuake> doInBackground(URL... urls) {
if(urls.length==0||urls[0]== null){
return null;
}
// Create URL object
URL url = createUrl(REQUESTED_URL);
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
// TODO Handle the IOException
}
ArrayList<EarthQuake> earthquake = QueryUtils.extractEarthquakes(jsonResponse);
return earthquake;
}
#Override
protected void onPostExecute(ArrayList<EarthQuake> earthquake) {
if (earthquake == null) {
return;
}
updateUi();
}
private URL createUrl(String stringUrl) {
URL url;
try {
url = new URL(stringUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
private String makeHttpRequest(URL url) throws IOException {
// If the URL is null, then return early.
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 the request was successful (response code 200),
// then read the input stream and parse the response.
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) {
inputStream.close();
}
}
return jsonResponse;
}
private 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();
}
}
}
Your class signature suggests that you are expecting a URL type as parameter, but you are passing a String type in the execute() method. All you need to do is to change your class signature to expect a String as in the one in this code.
private class EarthQuakeAsyncTask extends AsyncTask<String,Void,ArrayList<EarthQuake>> {
#Override
protected ArrayList<EarthQuake> doInBackground(String... urls) {
if(urls.length==0||urls[0]== null){
return null;
}
// Create a URL object from the String passed to the execute method
URL url = createUrl(urls[0]);
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
// TODO Handle the IOException
}
ArrayList<EarthQuake> earthquake = QueryUtils.extractEarthquakes(jsonResponse);
return earthquake;
}
#Override
protected void onPostExecute(ArrayList<EarthQuake> earthquake) {
if (earthquake == null) {
return;
}
updateUi();
}
private URL createUrl(String stringUrl) {
URL url;
try {
url = new URL(stringUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
private String makeHttpRequest(URL url) throws IOException {
// If the URL is null, then return early.
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 the request was successful (response code 200),
// then read the input stream and parse the response.
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) {
inputStream.close();
}
}
return jsonResponse;
}
private 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();
}
}
}
That is because your AsyncTask class isn't defined in a manner to handle the execute method with a String parameter. Let me explain myself.
The AsyncTask class you develop will look like this:
private class MyAsyncTask extends AsyncTask<TYPE1, TYPE2, TYPE3> {
protected TYPE3 doInBackground(TYPE1... type1_variables) {
// Do some long process here..
return variable_of_type_TYPE3;
}
protected void onPostExecute(TYPE3 result) {
// Do something here
}
}
So for you to call task.execute(REQUESTED_URL); you'd need to implement your AsyncTask class correctly.
For example it might look like this:
private class EarthQuakeAsyncTask extends AsyncTask<String, Void, Void> {
...
}

App not able to extract json data

I am trying to extract Json data, but somehow the code is not working.
Can somebody please help me ? Can't seem to understand what i am doing wrong.
(I dont really hav any more details to add)
public class MainActivity extends AppCompatActivity{
TextView t;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t=(TextView)findViewById(R.id.exchangeRate);
Anindya task = new Anindya();
task.execute("xyz");
}
public class Anindya extends AsyncTask<String,Void,String>
{
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection=null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection)url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(System.in);
int data = reader.read();
while (data!= 0)
{
char current = (char)data;
result += current;
data = reader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i("website content",result);
}
}
}
Try replacing InputStreamReader reader = new InputStreamReader(System.in) with InputStreamReader reader = new InputStreamReader(in)
If it still doesn't solve your problem then try to check the value of data and post details about returned value.

Android HttpUrlConnection Url doesn't work on emulator

I am trying to get json object as string from this url http://digitalcollections.tcd.ie/home/getMeta.php?pid=MS4418_021. It doesn't work I get an error after downloadUrl function.
java.io.IOException: unexpected end of stream on Connection{digitalcollections.tcd.ie:80, proxy=DIRECT# hostAddress=134.226.115.12 cipherSuite=none protocol=http/1.1} (recycle count=0)
Although it does work for this androidhive url http://api.androidhive.info/volley/person_object.json.
I am new to httpconnection below is my download url function. Error seems to show in this line HttpURLConnection conn = (HttpURLConnection) url.openConnection(); In the debugger after that line conn.getInputStream() shows the IO exception and the cause java.io.EOFException: \n not found: size=0 content=...
// Given a string representation of a URL, sets up a connection and gets
// an input stream.
private InputStream downloadUrl(String urlString) throws IOException {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(20000 /* milliseconds */);
conn.setConnectTimeout(30000 /* milliseconds */);
conn.setRequestMethod("GET");
//conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream stream = conn.getInputStream();
return stream;
}
Other functions.
// Uses AsyncTask to create a task away from the main UI thread. This task takes a
// URL string and uses it to create an HttpUrlConnection. Once the connection
// has been established, the AsyncTask downloads the contents of the webpage as
// an InputStream. Finally, the InputStream is converted into a string, which is
// displayed in the UI by the AsyncTask's onPostExecute method.
private class DownloadXMLTask extends AsyncTask<String, Void, List<Entry>> {
private String urlFront = "";
#Override
protected List<Entry> doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return loadJsonFromNetwork(urls[0]);
} catch (IOException e) {
Log.d(TAG, "Unable to retrieve web page. URL may be invalid.");
return null;
} catch (JSONException e) {
Log.d(TAG, "XMLPULLPARSER ERROR IN download json task function");
return null;
}
}
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(List<Entry> result) {
//post execution stuff
}
}
Loading json and parser, the parser might not work haven't tested it yet.
private List<Entry> loadJsonFromNetwork(String urlString) throws IOException, JSONException {
InputStream stream = null;
int len = 20000; //max amount of characters to display in string
List<Entry> entries = new ArrayList<Entry>();
try {
stream = downloadUrl(urlString); //IOException
String jsonStr = readit(stream,len);
if(jsonStr.equals(null)){
Log.d(TAG, "ERROR json string returned null");
return entries;
}
JSONObject jsonObj = new JSONObject(jsonStr);
//Not sure if the json parser works yet haven't got that far
// Getting JSON Array node
identifier = jsonObj.getJSONArray("identifier");
// looping through All Contacts
for (int i = 0; i < identifier.length(); i++) {
JSONObject c = identifier.getJSONObject(i);
String id = c.getString("type");
if(id.equals("DRIS_FOLDER")) {
String folder = c.getString("$");
entries.add(new Entry(null,null,null,folder));
}
}
// Makes sure that the InputStream is closed after the app is
// finished using it.
//This is where IOexception is called and stream is null
} catch (IOException e) {
Log.d(TAG, "Unable to retrieve json web page. URL may be invalid."+ e.toString());
return entries;
}
finally {
if (stream != null) {
stream.close();
}
}
return entries;
}
I am running this on a Nexus_5_API_23 emulator.
Thanks in advance.
UPDATE:
Doesn't work on Nexus_5_API_23 emulator?? Although it works on a Samsung GT-ST7500 external phone. Want it to work for the emulator.
The problem was my antivirus/firewall on my computer. It was blocking my connection and that's why it was working on a external phone and not emulator. I disabled my antivirus/firewall and it worked. There is a list of network limitations here http://developer.android.com/tools/devices/emulator.html#networkinglimitations
I just tried that URL on my device and didn't get any errors. Here is the code I used.
An Interface to get back onto the UI Thread
public interface AsyncResponse<T> {
void onResponse(T response);
}
A generic AsyncTask that returns a String - Feel free to modify this to parse your JSON and return a List.
public class WebDownloadTask extends AsyncTask<String, Void, String> {
private AsyncResponse<String> callback;
public void setCallback(AsyncResponse<String> callback) {
this.callback = callback;
}
#Override
protected String doInBackground(String... params) {
String url = params[0];
return readFromUrl(url);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (callback != null) {
callback.onResponse(s);
} else {
Log.w(WebDownloadTask.class.getSimpleName(), "The response was ignored");
}
}
private String streamToString(InputStream is) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
return sb.toString();
}
private String readFromUrl(String myWebpage) {
String response = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(myWebpage);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
response = streamToString(inputStream);
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return response;
}
}
Section of my Activity to call the AsyncTask.
String url = "http://digitalcollections.tcd.ie/home/getMeta.php?pid=MS4418_021";
WebDownloadTask task = new WebDownloadTask();
task.setCallback(new AsyncResponse<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
}
});
task.execute(url);
Make sure to use https instead of http to avoid these kind of errors on your Android Emulators.
private static final String BASE_URL = "https://content.guardianapis.com/search?";

Categories

Resources