App Downloading web page not working - java

I am learning android development and in a tutorial i am following demonstrated how to download a web page and print it into logs with AsyncTask class but the problem is, app is hanging ( ui elements not appearing neither in emulator nor in my phone ) and when the ui elements appear ( after a long time say 5 minutes) the html source in log is not showing
here is the code
package com.example.slimshady.downloadhtml;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
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 javax.net.ssl.HttpsURLConnection;
public class MainActivity extends AppCompatActivity {
public class DownloadTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... buttoks) {
URL url;
HttpURLConnection httpURLConnection = null;
String result = "";
// try catch for if malformed url
try {
url = new URL(buttoks[0]);
httpURLConnection = (HttpURLConnection)url.openConnection();
InputStream in = httpURLConnection.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 "failed";
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadTask downloadTask = new DownloadTask();
try {
String content = downloadTask.execute("https://www.google.com").get();
Log.i("returned STring", content.toString());
}catch (Exception e)
{
e.printStackTrace();
}
}
}
everything seems ok but still no html source logging and what can be the cause for the ui elements appearing alot later than they should ? i mean the whole reason for an AsyncTask is that they run independent of the main thread so the ui elements are not effected by the task am i right ?

The issue is , you are invoking get which will block your thread until you get the response so simply use
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadTask().downloadTask.execute("https://www.google.com");
}
and update UI in onPostExecute
You can also improve the code using StringBuffer and BufferReader as
public class DownloadTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... buttoks) {
URL url;
HttpURLConnection httpURLConnection = null;
String result = "";
StringBuffer buf = new StringBuffer();
// try catch for if malformed url
try {
url = new URL(buttoks[0]);
httpURLConnection = (HttpURLConnection)url.openConnection();
InputStream in = httpURLConnection.getInputStream();
BufferedReader reader =new BufferedReader(new InputStreamReader(in));
if (is != null) {
while ((result = reader.readLine()) != null) {
buf.append(result);
}
}
return buf.toString();
} catch (Exception e) {
e.printStackTrace();
return "failed";
}
}
#Override
... onPostExecute(String str){
// update UI here
}
}

Related

error: illegal start of expression in my Android studio code

I wrote some code in Android Studio for downloading content from the web. The build shows
"error: illegal start of expression"
and I'm not able to figure out the error. While checking for the error, I was asked to search for missing semi-colons and opening or closing braces. I have checked both and can't find any error.
The code is:
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
public class DownloadTask 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(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;
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadTask task = new DownloadTask();
String result = null;
try {
// result = task.execute("http://www.posh24.se/kandisar").get();
}
catch (Exception e){
e.printStackTrace();
}
}
}
I think you have space between result + = current; try below line
result += current;

How to add parameter to Url in HttpURLConnection

I'm trying to pass the matchday to the URL for the Http connection. I know I can't get a value from the EditText in the doInBackground method so I thought to get the value in the onPreExecute method. Of I then add the variable to the URL, the program doesn't recognise the String. I saw on StackOverflow you need to add the parameters in the execute method but I don't really have got that part of the explanation.
Does anyone have an idea how to add the matchday to the URL, entered in the EditText matchdayText?
Thanks in advance!
Rob Nickmans
CODE:
package ga.rndevelopment.footballpronostics;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
EditText matchdayText;
TextView responseView;
ProgressBar progressBar;
static final String API_KEY = "HIDDEN";
static final String API_URL = "http://api.football-data.org/v2/competitions/PL/matches/?matchday=";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
responseView = findViewById(R.id.responseView);
matchdayText = findViewById(R.id.matchdayText);
progressBar = findViewById(R.id.progressBar);
Button queryButton = findViewById(R.id.queryButton);
queryButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new FetchData().execute();
}
});
}
class FetchData extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
progressBar.setVisibility(View.VISIBLE);
responseView.setText("");
String matchDay = matchdayText.getText().toString();
String apiUrl = API_URL + matchDay;
}
#Override
protected String doInBackground(Void... params) {
try {
URL url = new URL(apiUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.addRequestProperty("X-Auth-Token", API_KEY);
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
bufferedReader.close();
return stringBuilder.toString();
} finally {
urlConnection.disconnect();
}
} catch (Exception e) {
Log.e("ERROR", e.getMessage(), e);
return null;
}
}
#Override
protected void onPostExecute(String response) {
if (response == null) {
response = "THERE WAS AN ERROR";
}
progressBar.setVisibility(View.GONE);
Log.i("INFO", response);
responseView.setText(response);
}
}
}
First Create the connection using URL Connection.There by create
buffer writer and pass the all requested data in one single String
buffer variable there by it will take to concern URL and along with
Requested parameter and its values. Please go Through this Below
sample Example
URL url = new URL("give your URL ");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
final StringBuilder reqstData = new StringBuilder(100);
reqstData.append("&userId=").append(userId);
reqstData.append("&roleId=").append(roleId);
reqstData.append("&userName=").append(userName);
out.write(reqstData);
out.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

I would like to effect the TextView from the json data I get from httpurlconnection

//[(START)File:ThirdActivity.java] -->
package com.example.caleb.splash_screen;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.io.IOException;
import java.io.OutputStream;
public class ThirdActivity extends AppCompatActivity {
//public String text = "https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt";
public TextView text;
private void writeStream(OutputStream out){
String output = "Hello world";
// out.write(output.getBytes());
//out.flush();
}
/*private String readStream(InputStream is) {
try {`enter code here`
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int i = is.read();
while(i != -1) {
bo.write(i);
i = is.read();
}
return bo.toString();
} catch (IOException e) {
return "";
}
}*/
//[(START) readStream -->
private String readStream(InputStream in) throws IOException {
BufferedReader bin = new BufferedReader(new InputStreamReader(in));
//temporary
try {
StringBuilder sb = new StringBuilder();
String inputLine;
while ((inputLine = bin.readLine()) != null) {
sb.append(inputLine);
}
return sb.toString();
} finally {
}
}
//[(END) readStream -->
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third2);
text = (TextView)findViewById(R.id.textView);
new JSONTask().execute("https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt");
}
}
//[(END)File:ThirdActivity] -->
//[(START)File:JSONTask] -->
package com.example.caleb.splash_screen;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.widget.TextViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
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;
/**
* Created by Caleb on 12/17/2017.
*/
public class JSONTask extends AsyncTask<String,String,String> {
//final TextView txt = (TextView)findViewById(R.id.textView);
private Context context;
public JSONTask(Activity ThirdActivity) {
context = ThirdActivity;
}
#Override
protected String doInBackground(String... params) {
BufferedReader reader = null;
HttpURLConnection urlConnection = null;
//{(START)] Working Connection:ALERT! Error within code will cause crash -->
try {
URL url = new URL(params[0]);
Log.w("testing", "test");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(false);
urlConnection.connect();
//urlConnection.setChunkedStreamingMode(0);
//OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
//writeStream(out);
/*int a = urlConnection.getResponseCode();
String b = String.valueOf(a);
Log.e(b, "yesssssssssssssssss");*/
InputStream in = urlConnection.getInputStream();
//InputStream in = new BufferedInputStream(urlConnection.getInputStream());
reader = new BufferedReader(new InputStreamReader(in));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
/*String data = readStream(in);
/*final TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("hello");
*/
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//{(END)] Working Connection -->
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
TextView text = (TextView) ((AppCompatActivity) context).findViewById(R.id.textView);
text.setText(result);
}
}
//[(END)File:JSONTask] -->
/Desired Effect/
Blockquote
I would like to pull data from the json file that the url points to and change the TextView within the UI called textView. I don't understand how to access the findviewbyid within the AsyncTask. I've looked all throughout the internet and couldn't find anything :( Any suggestions are greatly appreciated!!
try weak reference to get textview in asynctask
//call async task
new JSONTask(yourTextView).execute();
//in your async task
private final WeakReference<TextView> textViewReference;
public JSONTask (TextView textView){
textViewReference = new WeakReference<TextView>( textView);
}
#Override
protected void onPostExecute() {
TextView textView = textViewReference.get();
//set values to text view
}
I'm using OkHttp to do the same task in my apps
HTTP/2 support allows all requests to the same host to share a socket.
Connection pooling reduces request latency (if HTTP/2 isn’t available).
Transparent GZIP shrinks download sizes.
Response caching avoids the network completely for repeat requests.
Add this dependency
implementation 'com.squareup.okhttp3:okhttp:3.9.1'
Then create/code a new Class named OkHttpHandler
class OkHttpHandler extends AsyncTask<String, String, String> {
OkHttpClient client = new OkHttpClient();
private volatile String data;
public String getResult() {
return data;
}
#Override
protected String doInBackground(String... params) {
try {
Request.Builder builder = new Request.Builder();
builder.url(params[0]);
Request request = builder.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
data = s;
}
}
}
and use it like this way
String str = new OkHttpHandler().execute("http://www.<TEST>.com/json").get();
I also suggest to check whether Wi-fi-Connected/Bluetooth-Connected or PhoneData-Enabled is false if true/else, Proceed to your code

android app urlconnection get request wont work

I am having a problem.
I can't figure out why the following code won't work.
It's a simple app that sends a GET request to some php fragment that supposed to insert a row in a table.
I can't understand why it doesn't work.
Please help.
java:
package com.example.michael.biyum;
import android.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
final AlertDialog alertDialog = alertDialogBuilder.create();
Button startBtn = (Button) findViewById(R.id.btn);
final TextView t = (TextView) findViewById(R.id.hello);
startBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL("http://www.chatty.co.il/biyum.php?q=mkyong");
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();
Toast.makeText(getApplicationContext(),"GET:"+current,Toast.LENGTH_LONG).show();
System.out.print(current);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}
});
}
}
php:
<?php
require('connect.inc.php');
$update_offline="INSERT INTO offline_waiters (user_partner,mail,chat_room) VALUES(0,'gavno','gavno')";
$query_run= mysqli_query($conn,$update_offline);
echo "new";
?>
It's a simple test that should enter a new row in my table.
When I make the request manualy via a browser it works fine.
Once again please help me understand where is the problem.
You need to get the network operation off of the main thread.
I just got this working and tested using an AsyncTask:
class MyAsyncTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
StringBuilder result = new StringBuilder();
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL("http://www.chatty.co.il/biyum.php?q=mkyong");
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();
result.append(current);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return result.toString();
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(getApplicationContext(),"GET:"+result,Toast.LENGTH_LONG).show();
}
}
Just execute the AsyncTask from your click listener:
startBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
new MyAsyncTask().execute();
});
Result in the Toast:

What would be the best way to make this run Async

I have to java classes, one the activity and the other is the class i want to run a void from.
Web.java looks like:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class Web {
public Document requestPage(String urll) throws Exception {
StringBuilder result = new StringBuilder();
URL url = new URL(urll);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
Document doc = Jsoup.parse(result.toString());
return doc;
}
}
And my MainActivity.java looks like this:
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.widget.EditText;
import android.view.View;
import android.widget.Toast;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
public class MainActivity extends AppCompatActivity {
Button Visit;
EditText Urlbox;
Web web = new Web();
#Override
protected void onCreate(Bundle savedInstanceState) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Visit = (Button)findViewById(R.id.Button);
Urlbox = (EditText)findViewById(R.id.EditText);
Visit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Document lol = web.requestPage(Urlbox.getText().toString());
if(lol.text().toString() != null){
Toast.makeText(MainActivity.this, "Visit success!",Toast.LENGTH_SHORT).show();
}
}
});
}
}
And this works fine over the main thread most, but i want to make it go over a different thread so my UI doesnt get jammed if the connection is bad
How would i make this work in async? This is my first time i use async but i just dont understand how i should use it, ive spent a few days trying to figure it out with absolutely no success
So if i could get some examples that do work that would be fantastic so i could compare it to my current code and learn what i did wrong
i handle sitution like with callback Pattern its the best option for Asynchronous networking or you can use AsyncTask but im explain cllback pattern so lets make it happen
first create callback interface
public interface Request {
void onSuccess(Document doc);
}
2 - implements Runnable for running Asynchronous request on another thread
public class Web implements Runnable {
public final Request request;
private final String urll;
Web(String urll, Request request){
this.urll = urll;
this.request = request;
}
#Override public void run() {
try{
StringBuilder result = new StringBuilder();
URL url = new URL(urll);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
Document doc = Jsoup.parse(result.toString());
// fill the cllback with result
this.request.onSuccess(doc);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// return doc;
}
}
3 - now we work with ExecutorService(ThreadPools created for reason .. its off topic here), simple thing in here we use new Thread(Runnable) before that letsimplement the calback
public class MainActivity extends AppCompatActivity implement Request{
Button Visit;
EditText Urlbox;
private Document lol;
//Web web = new Web();
#Override
protected void onCreate(Bundle savedInstanceState) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Visit = (Button)findViewById(R.id.Button);
Urlbox = (EditText)findViewById(R.id.EditText);
Visit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Document lol = web.requestPage(Urlbox.getText().toString());
String url = Urlbox.getText().toString();
Thread thread = new Thread(new Web(url, this));
thread.start();
if(lol.text().toString() != null){
Toast.makeText(MainActivity.this, "Visit success!",Toast.LENGTH_SHORT).show();
}
thread.interrupt();
}
});
}
#Override
public void onSuccess(Document doc) {
lol = doc;
}
}
and every where you need new result or request you have to create thread and if you wanna share result betwwen classes or thread this is another thing
this pattern works perfectly me.

Categories

Resources