Im trying to get a website content but my app keeps crashing on upon calling DownloadTask
This is my DownloadTask and onCreate code
and the debug also goes to Log.i and my guess is that the result string isnt getting the content ? or the downloadtask code is all wrong?
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
URL url;
HttpURLConnection urlConnection = null;
String result = "";
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data !=1) {
char current = (char) data;
result += current;
data = reader.read();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
"onCreate"
DownloadTask task = new DownloadTask();
String result = null;
try {
result = task.execute("https://samples.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=API_KEY/").get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("Contents", result);
I figured it out
I didn't add return result; to the code, adding it fixed my problem.
protected String doInBackground(String... urls) {
URL url;
HttpURLConnection urlConnection = null;
String result = "";
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Related
I have 3 url's of pages which content has a json structure. I must read a page from an url in an async task.
How can I read the 3 urls sequentially, so that I can work with the 3 json's maintaining their order?
private class JsonTask extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]); //params[0] = my first url
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
return buffer.toString();
//read also the second and the third url
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
#Override
protected void onPostExecute(String result) {
// ... do something with the first json
// ... do something with the second json
// ... do something with the third json
}
}
Just move the logic for mapping one URL to JSON out into a method, and call it for each argument you pass in. Then, modify your AsyncTask so it outputs List<String> and not String from doInBackground().
protected List<String> doInBackground(String... params) {
final List<String> out = new ArrayList<>(paramas.length);
for(String url : params) {
out.add(downloadJson(url));
}
return out;
}
#Override
protected void onPostExecute(List<String> results) {
//A list of your JSON results...
}
private String downloadJson(String url) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
connection = (HttpURLConnection) new URL(url).openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder buffer = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line).append("\n");
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "{}"; //Default to an empty JSON object
}
I have cleaned and rebuild my code as well but still the issue is not solved.
Below is the code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String result = null;
String stringUrl = "https://www.ecowebhosting.co.uk/";
DownloadTask downloadTask = new DownloadTask();
downloadTask.execute(stringUrl);
}
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection httpURLConnection = null;
try {
url = new URL(urls[0]);
//It is like opening a browser
httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream in = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char currentChar = (char) data;
result = result + currentChar;
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
return "Failed";
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.i("Results",s);
}
}
}
The code is running fine but nothing is printed in the logs. The following is the log:
AsyncTask is an asynchronous process. So when you call Log.i("Result:", result);, the AsyncTask is not finished and result is still empty.
You should print your result from onPostExecute() method.
You can look on this page.
Here is some examples on how to implement an AsyncTask correctly:
https://www.upwork.com/hiring/mobile/why-you-should-use-asynctask-in-android-development/
How to use AsyncTask correctly in Android
Best
You only have to change code inside your doInBackGround
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result;
String inputLine;
try {
URL myUrl = new URL(urls[0]);
HttpURLConnection connection =(HttpURLConnection)
myUrl.openConnection();
connection.setReadTimeout(150000);
connection.setConnectTimeout(15000);
connection.setRequestMethod("GET");
connection.connect();
InputStreamReader streamReader = new InputStreamReader(connection.getInputStream());
//Create a new buffered reader and String Builder
BufferedReader reader = new BufferedReader(streamReader);
StringBuilder stringBuilder = new StringBuilder();
//Check if the line we are reading is not null
while((inputLine = reader.readLine()) != null){
stringBuilder.append(inputLine);
}
//Close our InputStream and Buffered reader
reader.close();
streamReader.close();
//Set our result equal to our stringBuilder
result = stringBuilder.toString();
} catch (Exception e) {
e.printStackTrace();
return "error";
}
return result;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.i("Results",s);
}
}
I'm trying to send POST request via HttpURLConnection, here is the code
public class BackgroundTask extends AsyncTask<String, Void, Void> {
Context context;
Activity activity;
StringBuffer str = null;
int responseCode;
String responseMessage;
public BackgroundTask(Context context) {
this.context = context;
this.activity = (Activity) context;
}
#Override
protected Void doInBackground(String... params) {
HttpURLConnection connection = null;
OutputStream outputStream = null;
InputStream inputStream = null;
BufferedReader reader = null;
BufferedWriter writer = null;
String method = params[1];
if(method.equals("post")) {
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
outputStream = connection.getOutputStream();
writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String data = URLEncoder.encode(params[2] + "=" + params[3], "UTF-8");
writer.write(data);
responseCode = connection.getResponseCode();
responseMessage = connection.getResponseMessage();
inputStream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
str = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
str.append(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null)
connection.disconnect();
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (writer != null) {
try {
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else if(method.equals("get")) {
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Void aVoid) {
TextView txt = (TextView) activity.findViewById(R.id.txt);
if(str != null)
txt.setText(str.toString());
Toast.makeText(activity, responseMessage, Toast.LENGTH_LONG).show();
}
}
responseCode is 200 which means everything went OK, however it says Undefined index: id
id is well defined inside php file
$user = User::find_by_id($_POST['id']);
echo json_encode($user);
and it works fine when I send post request from an html file yet when i send it from application it says id undefined which means that POST data is not sent.
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
BackgroundTask myTask = new BackgroundTask(MainActivity.this);
myTask.execute(link, "post", "id", "5");
}
});
this is how i instantiate asynctask object inside main activity
UPDATE: when i send not encoded string it works fine!
writer.write("id=5"); // works perfectly!
what is wrong with URLEncoder i use in the code?
I believe you have a problem in this line:
String data = URLEncoder.encode(params[2] + "=" + params[3], "UTF-8");
You are url-encoding the = as well as the params, that's why the server cannot recognise the form fields. Try to encode the params only:
String data = URLEncoder.encode(params[2], "UTF-8") + "=" + URLEncoder.encode(params[3], "UTF-8");
The reason is that URL encoding is for passing special characters like = in the value(or key). Basically, the server will split and parse the key-value pairs with & and = before doing the decoding. And when you url-encode the = character, the server simply couldn't recognise it during the split and parse phase.
When i need to communicate with the server i use this
Server Class
public static String sendPostRequest(String requestURL,
HashMap<String, String> postDataParams) {
URL url;
String response = "";
try {
url = new URL(requestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();
int responseCode = conn.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
response = br.readLine();
} else {
response = "Error Registering";
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
private static String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, String> entry : params.entrySet()) {
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
return result.toString();
}
OtherClass
//Run this inside an Asynctask
HashMap<String,String> data = new HashMap<>();
data.put("id", id);
String serverResponce = Server.sendPostRequest(URL,data);
I'm implementing JSP page in my Android application. I don't know how to use JSP Url in Android. I tried and run the application. But the page is blank does not show any info in Android layout and also in log cat. Here is my code.
public class JSP_Activity extends Activity
{
public static String strUrl=null;
String strText = null;
public void OnCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.jsp_page);
connectWithGet_JspPage();
}
private void connectWithGet_JspPage()
{
class GetJspPage extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... strUrls)
{
// TODO Auto-generated method stub
strUrl="http://test.window2india.com/mobile/home.jsp";
Log.e("strUrl :=","" + strUrl);
String strOutPut = null;
strOutPut=getOutPutFromUrl(strUrl);
Log.e("strOutPut :="," "+strOutPut);
return strOutPut.toString();
}
protected void onPostExecute(String output1)
{
//outputText.setText(output1);
Log.e("strOutPut :="," "+output1);
}
}
GetJspPage getJspPageAsyncTask = new GetJspPage();
getJspPageAsyncTask.execute();
}
private String getOutPutFromUrl(String url)
{
StringBuffer output = new StringBuffer("");
try
{
InputStream stream = getHttpConnection(url);
BufferedReader buffer = new BufferedReader(new InputStreamReader(stream));
String s = "";
while ((s = buffer.readLine()) != null)
output.append(s);
}
catch (IOException e1)
{
e1.printStackTrace();
}
return output.toString();
}
private InputStream getHttpConnection(String urlString)
throws IOException
{
InputStream stream = null;
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
try
{
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK)
{
stream = httpConnection.getInputStream();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
return stream;
}
}
Try this code,it will help for display the content send by the jsp.This code is useful for normal layout not for webview.You have to parse the content and display in your custom layout.
new Thread(new Runnable()
{
public void run()
{
try
{
URL url = new URL("http://test.window2india.com/mobile/home.jsp");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader r = new BufferedReader(new InputStreamReader(in));
String x = "";
String total = "";
int i=0;
ArrayList<String> content = new ArrayList();
while((x = r.readLine()) != null)
{
content.add(x);
}
in.close();
r.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}).start();
I'm new to Java and Android development and try to create a simple app which should contact a web server and add some data to a database using a http get.
When I do the call using the web browser in my computer it works just fine. However, when I do the call running the app in the Android emulator no data is added.
I have added Internet permission to the app's manifest. Logcat does not report any problems.
Can anyone help me to figure out what's wrong?
Here is the source code:
package com.example.httptest;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class HttpTestActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
setContentView(tv);
try {
URL url = new URL("http://www.mysite.se/index.asp?data=99");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.disconnect();
tv.setText("Hello!");
}
catch (MalformedURLException ex) {
Log.e("httptest",Log.getStackTraceString(ex));
}
catch (IOException ex) {
Log.e("httptest",Log.getStackTraceString(ex));
}
}
}
Try getting the input stream from this you can then get the text data as so:-
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL("http://www.mysite.se/index.asp?data=99");
urlConnection = (HttpURLConnection) url
.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader isw = new InputStreamReader(in);
int data = isw.read();
while (data != -1) {
char current = (char) data;
data = isw.read();
System.out.print(current);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
You can probably use other inputstream readers such as buffered reader also.
The problem is that when you open the connection - it does not 'pull' any data.
Here is a complete AsyncTask class
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);
}
}
// Converting InputStream to String
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();
}
To Call this AsyncTask class
new GetMethodDemo().execute("your web-service url");
I have created with callBack(delegate) response to Activity class.
public class WebService extends AsyncTask<String, Void, String> {
private Context mContext;
private OnTaskDoneListener onTaskDoneListener;
private String urlStr = "";
public WebService(Context context, String url, OnTaskDoneListener onTaskDoneListener) {
this.mContext = context;
this.urlStr = url;
this.onTaskDoneListener = onTaskDoneListener;
}
#Override
protected String doInBackground(String... params) {
try {
URL mUrl = new URL(urlStr);
HttpURLConnection httpConnection = (HttpURLConnection) mUrl.openConnection();
httpConnection.setRequestMethod("GET");
httpConnection.setRequestProperty("Content-length", "0");
httpConnection.setUseCaches(false);
httpConnection.setAllowUserInteraction(false);
httpConnection.setConnectTimeout(100000);
httpConnection.setReadTimeout(100000);
httpConnection.connect();
int responseCode = httpConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
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();
}
}
where
public interface OnTaskDoneListener {
void onTaskDone(String responseData);
void onError();
}
You can modify according to your needs. It's for get
If you just need a very simple call, you can use URL directly:
import java.net.URL;
new URL("http://wheredatapp.com").openStream();
Simple and Efficient Solution : use Volley
StringRequest stringRequest = new StringRequest(Request.Method.GET, finalUrl ,
new Response.Listener<String>() {
#Override
public void onResponse(String){
try {
JSONObject jsonObject = new JSONObject(response);
HashMap<String, Object> responseHashMap = new HashMap<>(Utility.toMap(jsonObject)) ;
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("api", error.getMessage().toString());
}
});
RequestQueue queue = Volley.newRequestQueue(context) ;
queue.add(stringRequest) ;
A more contemporary way of doing it on a separate thread using Tasks and Kotlin
private val mExecutor: Executor = Executors.newSingleThreadExecutor()
private fun createHttpTask(u:String): Task<String> {
return Tasks.call(mExecutor, Callable<String>{
val url = URL(u)
val conn: HttpURLConnection = url.openConnection() as HttpURLConnection
conn.requestMethod = "GET"
conn.connectTimeout = 3000
conn.readTimeout = 3000
val rc = conn.responseCode
if ( rc != HttpURLConnection.HTTP_OK) {
throw java.lang.Exception("Error: ${rc}")
}
val inp: InputStream = BufferedInputStream(conn.inputStream)
val resp: String = inp.bufferedReader(UTF_8).use{ it.readText() }
return#Callable resp
})
}
and now you can use it like below in many places:
createHttpTask("https://google.com")
.addOnSuccessListener {
Log.d("HTTP", "Response: ${it}") // 'it' is a response string here
}
.addOnFailureListener {
Log.d("HTTP", "Error: ${it.message}") // 'it' is an Exception object here
}
URL url = new URL("https://www.google.com");
//if you are using
URLConnection conn =url.openConnection();
//change it to
HttpURLConnection conn =(HttpURLConnection )url.openConnection();