I'm a android newbie.
I need to create some kind of preloader for the Activity. Right now I click the button say "Show company" and afterwards I go to the next activity where the data is loaded from serwer and shown inside. The problem is that (from what I understand) the activity is connecting with internet and until connections is done nothing is show. User must wait and then suddelny (after few seconds - varies) he gets new 100% ready page based on new activity.
The best for me would be sth like: create a loding animation that is shown until the activity is fully loaded. (that would solve problem everywhere)
Alternative would be: loading the new activity before connecting with the internet url. When its loaded it say sth default like "Loading data" until full text is downloaded from url that will replace the first text.
Here is the code I use to load text from URL.
try {
// Create a URL for the desired page
URL url = new URL(serwer_url);
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
// str is one line of text; readLine() strips the newline character(s)
Plain_str = Plain_str + str;
}
Log.i("Plain read str", Plain_str);
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {}
//end of reading file
//here is the anchor to the text in activity
TextView MainText = (TextView)findViewById(R.id.TextMain);
MainText.setText(Html.fromHtml(Plain_str.toString()));
You can use an AsyncTask like this:
protected class Mytask extends AsyncTask<Void, Void, String>{
#Override
protected String doInBackground(Void... params) {
String Plain_str= null;
try {
// Create a URL for the desired page
URL url = new URL(serwer_url);
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
// str is one line of text; readLine() strips the newline character(s)
Plain_str = Plain_str + str;
}
Log.i("Plain read str", Plain_str);
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {}
return Plain_str;
}
protected void onPostExecute(String str){
TextView MainText = (TextView)findViewById(R.id.TextMain);
MainText.setText(Html.fromHtml(str.toString()));
}
}
And then to execute the Task
new MyTask().execute();
Related
I'm writing a android trivia app that uses the Open Trivia DB to generate its questions. The problem I'm incurring is that I'm simply unable to connect to the generated API url and I'm not sure why.
I'm simply trying to pull the raw text from the URL and then sort it later, here is the relevant code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button start = (Button)findViewById(R.id.button);
try {
getJSON();
}
catch (IOException e){
Log.d("CREATION","Something wrong");
}
}
private String getJSON()throws IOException{
URL trivia = new URL("https://opentdb.com/api.php?amount=10");
URLConnection yc = trivia.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
Log.d("CREATION",inputLine);
in.close();
return "";
}
}
The Stack trace from the errors I get comes back with this:
at edu.niu.students.z1802067.triviaapp.MainActivity.getJSON(MainActivity.java:59)
which is this line of code:
yc.getInputStream()));
How could I write this to simply get all the raw text from the JSON?
First of all you try make request with UI thread. It's blocking UI for a long time (time of request)
Try use thread like this:
new Thread(){
#Override
public void run() {
try {
getJSON();
}
catch (IOException e){
Log.d("CREATION","Something wrong: " + e, e);
}
}
}.start();
Better solution for reading data form API is use library like https://square.github.io/retrofit/
It simplifies the task and data processing
My english isn't perfect, but I hope it helps some people that are trying to solve this problem ;-)
My Question
I'm learning Android programming yet and I hope you guys can help me.
I'm trying to get a string from a txt file, from a ftp server. My string is called "contents" and I'm trying to show it with my "texto" TextView.
I'm using FTPClient to acess the ftp server.
This is my method inside my MainActivity class:
public void get_txt() throws MalformedURLException {
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect("my.ftp.url", 21);
ftpClient.enterLocalPassiveMode();
ftpClient.login("my_user", "my_password");
InputStream inStream = ftpClient.retrieveFileStream("teste.txt");
InputStreamReader isr = new InputStreamReader(inStream, "UTF8");
String contents = isr.toString();
texto.setText(contents);
barra.setEnabled(false);
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Thanks, and I hope you can help me :)
EDIT 1: I forgot to mention. My app is running ok, the problem is that the TextView never changes.
The Final and Working Code (I hope it helps you)
Finally, after hours, I managed to get it right! For those who need the answer, here it is:
public class Principal extends AppCompatActivity {
public static TextView texto;
String contents;
ProgressBar barra;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_principal);
texto = (TextView) findViewById(R.id.texto);
TarefaDownload download = new TarefaDownload();
download.execute();
}
The code above is my MainActivity (I call it "Principal" here). I created only a TextView there, then I instaciated my AsyncTask class called "TarefaDownload". This class is a private class where all the logic to acess ftp is placed. Let's see this class code now.
private class TarefaDownload extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... params) {
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect("my_ftp_link_here", 21);
ftpClient.enterLocalPassiveMode();
ftpClient.login("my_user_login_here", "my_password_here");
ftpClient.changeWorkingDirectory("/");
InputStream inStream = ftpClient.retrieveFileStream("teste.txt");
InputStreamReader isr = new InputStreamReader(inStream, "UTF8");
int data = isr.read();
contents = "";
while(data != -1){
char theChar = (char) data;
contents = contents + theChar;
data = isr.read();
}
isr.close();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
texto.setText(contents);
}
}
So, basically I was trying to read a single line string from a txt file called "teste". The method "doInBackground" runs everything in background (don't you say?), so all the code to access ftp must come there.
Then I created a String called "contents", started to read the chars (one per time) from the InputStreamReader and storing in the string. You must notice that the String contents is being used in this method, but it belongs to my MainActivity, so I can access it outside the AsyncTask class. Finally, when de doInBackground method finishes, the "onPostExecute" methos is called and set the text of my TextView to value of my String value.
That's all! You may notice that you must add a INTERNET permission on your Manifest file (or then you'll not be able to access the ftp server):
<uses-permission android:name="android.permission.INTERNET" />
And that's it, your app should be reading data from the ftp server!
I want to get an HTML from a web page, remove some tags from the code and display it using a TextView... But those HTMLs are too big to be temporaly stored into a String...
When I try this way:
String html = "myBigHTML";
myTextView.setText(fromHtml(html));
compiler says error: constant string too long
If I put the html into a .txt and try this way:
InputStream is = getAssets().open("html.txt");
tvTeste.setText(fromHtml(convertStreamToString(is)));
public static String convertStreamToString(InputStream is) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
return sb.toString();
}
It works but the app gets soooo slow, almost freezes... And also, if I store it in a .txt I couldn't work with the tags...
.:: EDIT ::.
My onCreate() method as asked...
private TextView tvTeste;
private InputStream is;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_frequencia);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
tvTeste = (TextView)findViewById(R.id.tvTeste);
try {
is = getAssets().open("html.txt");
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String strLine;
List<String> stringList = new ArrayList<>();
try {
while ((strLine = br.readLine()) != null) {
stringList.add(strLine);
}
} catch (Exception e) {
e.printStackTrace();
}
tvTeste.setText(fromHtml(TextUtils.join("",stringList)));
}
Let's try this: each line of HTML text is a String. Each String is inside a List of String.
So, some pseudocode:
List<String> stringList = new ArrayList<>();
while (htmlHandler.next()) {
stringList.add(fromHtml(htmlHandler.readLine()));
}
myTextView.setText(joinStringArray(stringList));
Where joinStringArray uses a StringBuilder to produce a single big String object.
Basically you shouldn't read the entire web page, but you should read it sequentially.
Another point to mark. You should avoid any time consuming process that blocks the activity. try the same using, for example an AsyncTask.
Please check https://developer.android.com/reference/android/os/AsyncTask.html
Basically, i have an app that uses JSON. I get the JSON in new HentData.execute(); and pass it to a string variable. But when I try to acutally do something with it my program crashes.
HentData extends AsyncTask, I know it gives me a JSON string that works
INSIDE oncreate()
new HentData().execute();
jsonToArray();
arrayToText();
This crashes
But when I run them like this it works, do I have to close the HentData class somehow?
protected void onPostExecute(String resultat){
json_string = resultat;
jsonToArray();
arrayToText();
}
This is my doInBackground()
protected String doInBackground(Void... voids){
try {
URL url = new URL(json_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream IS = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(IS));
StringBuilder sb = new StringBuilder();
while((json_string = bufferedReader.readLine())!=null){
sb.append(json_string+"\n");
}
bufferedReader.close();
IS.close();
httpURLConnection.disconnect();
return sb.toString().trim();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
But when I run them like this it works, do I have to close the HentData class somehow?
protected void onPostExecute(String resultat){
json_string = resultat;
jsonToArray();
arrayToText();
}
You don't have to close anything. This works because "async" in AsyncTask makes the code run in the background.
In other words,
new HentData().execute(); // Not waiting for result
jsonToArray(); // Continue on, even though there is no result yet --> error
arrayToText();
If you want a more flexible way to get results, see How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
If you hate writing AsyncTasks (for HTTP methods), see Comparison of Android networking libraries: OkHTTP, Retrofit, and Volley
I'm creating an app where I need a function to get plain text from a website. I am able to get the text and print it out on my PC just fine, but when I try running it on an Android device, the app won't start.
I believe it has something to do with throwing an IOException. I've been reading that I am not supposed to do that because I don't define the interface. Is there a way to get around this? Android Studio won't compile my code if I don't throw the exception.
The function:
public String getText(String site) throws IOException {
// Make a URL to the web page
URL url = new URL(site);
// Get the input stream through URL Connection
URLConnection con = url.openConnection();
InputStream is =con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// read each line and return the final text
String res = "";
String line = null;
while ((line = br.readLine()) != null) {
//System.out.println(line);
res += line;
}
return res;
}
And this is how Android Studio makes me run it in the onCreate method:
String text = null;
try {
text = getText("http://myWebsite.com");
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show();
First, read your logcat - you should see your exception there with full stacktrace. Second, there is nothing wrong with catching IOException, but you must do something with it once cached - like inform user of problem in functionality - like no more space, etc.
And this is how Android Studio makes me run it in the onCreate method:
this is a problem, because your are getting data from your site on UI thread, you must do it from worker thread, ie. AsyncTask.
You can not do it in the main thread
try this
class MyTask extends AsyncTask<Void, Void, String>{
private String site;
MyTask(String site) {
this.site = site;
}
#Override
protected String doInBackground(Void... params) {
try {
URL url = new URL(site);
URLConnection con = url.openConnection();
InputStream is =con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// read each line and return the final text
String res = "";
String line = null;
while ((line = br.readLine()) != null) {
//System.out.println(line);
res += line;
}
return res;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if(s != null){
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
}
}
}
where to get a string is used as
new MyTask("http://myWebsite.com").execute()