Java - Web Scraping In Android Studio [duplicate] - java

This question already has answers here:
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Closed 2 years ago.
I'm trying to web scrape from a website https://www.worldometers.info/coronavirus/ and turns that data to form an app but the data is not actually printing I don't the reason but whenever I click the button in an android emulator it just crashes instantly !!
I have 3 textView in the app and a button so whenever I click the button it should show up the data in the textView !!
textView have ids of TotalCases / TotalDeaths / TotalRecovered
button has an id of the button
Here is what I have I have done
package com.example.coronaupdate;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import android.widget.Button;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
Button btn;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
compare();
}
});
}
public void compare()
{
final TextView totalCases;
final TextView totalDeaths;
final TextView totalRecovered;
totalCases = (TextView) findViewById(R.id.TotalCases);
totalDeaths = (TextView) findViewById(R.id.TotalDeaths);
totalRecovered = (TextView) findViewById(R.id.TotalRecovered);
try {
Document doc = Jsoup.connect("https://www.worldometers.info/coronavirus/").userAgent("mozilla/17.0").get();
Elements temp = doc.select("div.maincounter-number");
Element totalcase = temp.get(0);
String cases = totalcase.select("div.maincounter-number span").text();
totalCases.setText(cases);
Element totaldeaths = temp.get(1);
String deaths = totaldeaths.select("div.maincounter-number span").text();
totalDeaths.setText(deaths);
Element totalrecovered = temp.get(2);
String recovered = totalrecovered.select("div.maincounter-number span").text();
totalRecovered.setText(recovered);
/* for(Element totalCase:temp)
{
String cases = totalCase.select("div.maincounter-number span").text();
System.out.println("" + cases);
*//*i++;
System.out.println(i + "" + totalCase.getElementsByTag("span"));*//*
}*/
}
catch (IOException e){
e.printStackTrace();
}
}
}
image of the app view
Image of the app view

If you could post the Error you're getting it would be easier to see what's going on, but I have two assumptions of what's wrong.
First you should check if yout Manifest is asking for INTERNET access permission. If it isn't, you should include it.
Second: Always when making requests to the internet in Android you should use either AsyncTasks or at least open a separate thread manually. That's because internet calls are asynchronous by definition, and if you block the main execution of your App to wait for a response the UI is gonna freeze or crash. So perhaps you should extract the logic of your compare() function to a separate class that inherits from AsyncTask and place it into the doInBackground() method.

Related

Android app crashing when trying to setText() from an arraylist<String> [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 12 months ago.
Improve this question
I am a bit new to Android Studio and Java. I am trying to update a text by replacing it from an element of an ArrayList. However, when using setText(userList.get(0)), the app crashes. My guess is that the arraylist is empty or cannot be accessed. But I use the same code on a button with a setOnClickListener, the text is updated by the string found in the arrayList.
I want to make the app automatically update the Text onloading the activity.
Here is my MainActivity.java -- I commented the setText that is crashing the app.
package com.example.sampletest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ArrayList<String> userList = new ArrayList<String>();
TextView text;
Button swapText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new getUsers().execute();
text = (TextView) findViewById(R.id.text);
swapText = (Button) findViewById(R.id.button);
//text.setText(userList.get(0));
swapText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
text.setText(userList.get(0));
}
});
}
class getUsers extends AsyncTask<Void, Void, Void> {
String error = "";
#Override
protected Void doInBackground(Void... voids) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://192.168.100.5:3306/cardetailingdb", "lau", "lau");
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM users");
while (resultSet.next()) {
userList.add(resultSet.getString(1));
}
} catch (Exception e) {
error = e.toString();
}
return null;
}
}
}
My guess is that the arraylist is empty or cannot be accessed.
The list is empty. You can see the stacktrace in the logcat for crash details.
But I use the same code on a button with a setOnClickListener, the text is updated by the string found in the arrayList.
That's because it's is not executed syncronously in onCreate() but later on clicking the button.
I want to make the app automatically update the Text onloading the activity.
You can add an onPostExecute() to your async task that gets run on the main thread once the background call completes. You should also check that the async call actually succeeded and not blindly trust that userList has elements in it.
In type of async task you should ensured first your all data is populated. Soo make sure background is completed and List is not empty. Hope will be work fine. For crashing issues you can add a check point like:
if(userList.size()>0){ text.setText(userList.get(0)); }

TextView not updating after creating new Activity

I'm new to Android and I stuck. I have a Textview on Activity which should show result, but for some reason it is updating TextView only if you click on Button which is not doing anything or if you close app and reopen it again from menu of running apps. I suppose it's somehow connected with updating activity. Thank you in advance!
package com.example.visacheck;
import android.content.Intent;
import android.os.Bundle;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class FourthActivity extends AppCompatActivity {
String aplicationNumber;
String type;
String year;
#Override
protected void onCreate(Bundle savedInstanceState) {
this.getSupportActionBar().hide();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fourth);
Intent intent = getIntent();
final Button button = findViewById(R.id.resultButton); //Result appearing only after clicking button
aplicationNumber = intent.getStringExtra("aplicationNumber");
type = intent.getStringExtra("type");
year = intent.getStringExtra("year");
class MyJavaScriptInterface {
#JavascriptInterface
#SuppressWarnings("unused")
public void processHTML(String html) {
TextView text = findViewById(R.id.textView);
text.setText(html);
}
}
final WebView myWebview = findViewById(R.id.webview);
myWebview.getSettings().setJavaScriptEnabled(true);
myWebview.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
myWebview.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
myWebview.loadUrl(("javascript:document.getElementById('edit-ioff-application-number').value = '" + aplicationNumber + "';void(0);"));
myWebview.loadUrl(("javascript:" + "document.getElementById('edit-ioff-application-code').value = '" + type + "';void(0);"));
myWebview.loadUrl(("javascript:document.getElementById('edit-ioff-application-year').value = '" + year + "';void(0);"));
myWebview.loadUrl(("javascript:document.getElementById('edit-submit-button').click();"));
myWebview.loadUrl("javascript:window.HTMLOUT.processHTML(document.getElementsByClassName('alert alert-warning')[0].innerText);");
myWebview.loadUrl("javascript:window.HTMLOUT.processHTML(document.getElementsByClassName('alert alert-success')[1].innerText);");
myWebview.loadUrl("javascript:window.HTMLOUT.processHTML(document.getElementsByClassName('alert alert-danger')[0].innerText);");
}
});
myWebview.loadUrl("https://frs.gov.cz/ioff/application-status");
}
}
I'm not going to do a very good job at this, as I can hardly touch on the subject myself. Maybe someone with more knowledge can go into further detail, but the general idea here is that this code is being called by the JS thread as opposed to your UI thread (Which is the only thread that is allowed to handle UI updates), and I'm surprised this code doesn't crash when doing so, honestly. The post() method adds this to the view's message queue, which means that the text will be updated AFTER the view has been rendered, and has no other tasks to perform. I know I did a bad job at explaining this, but for more information, please refer to these:
What exactly does the post method do?
Alternately, you can user runOnUIThread(), example:
How do we use runOnUiThread in Android?
I'm sure that a lot of people out there have already explained this better than I have. But the most important thing to understand here is that you must not update UI from anything other than the UI thread
Please note that I chose myWebView arbitrarily, and this should work if posted to the fragment's main view aswell.
class MyJavaScriptInterface {
#JavascriptInterface
#SuppressWarnings("unused")
public void processHTML(final String html) {
myWebview.post(new Runnable() {
#Override public void run() {
TextView text = findViewById(R.id.textView); text.setText(html);
}
});
}
}

Creating Random Corresponding Arrays in Android

I made a question earlier on the same project but now I have a different problem. My goal is to have a password field that is stored locally and when a password is put in that is equal to the variable a screen will display. I have accomplished this but know I want to spice it up a little. I want to make it so that when the background color is red the password is red and so on for yellow and blue. I need to create two arrays that both randomly pick the same variable. I know this is possible because I have done it within Phaser but I am struggling on doing it in Android Studio. Anyways here is my code so far and my attempt at making an array.
Thanks for all the help,
Murdoc
package com.example.murdocbgould.passwordpt4;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.example.murdocbgould.passwordpt4.R;
import com.example.murdocbgould.passwordpt4.Welcome;
import java.security.AccessController;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String apassword[] = {"rootr", "rootb", "rooty"};
final String acolors[] = {"red", "blue", "yellow"};
Random rn = new Random();
int answer = rn.nextInt(3) + 1;
final EditText editText = (EditText) findViewById(R.id.editText);
Button button = (Button) findViewById(R.id.button);
final TextView textView2 = (TextView) findViewById(R.id.textView2);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
textView2.setText(editText.getText().toString().trim());
if(editText.getText().toString().trim().equals(apassword)){
Intent myIntentR1 = new Intent(view.getContext(), Welcome.class);
startActivity(myIntentR1);
} else {
Intent a = new Intent(view.getContext(), FTry.class);
startActivity(a);
}
}
});
}
}
Just write a bunch of if statements or use a switch statement. If you are going to write a serious app you would not store passwords in an array! I understand your in High School but consider using sqlite database it will open up a new world to develop apps. Storage of data is a wonderful learning experience. Back to your question here is a small snippet of IF code. In your case grab the password from the array and hard code the color to look for a match.
A better solution would be a HashMap key-value search the Map with the random password as the key and this will give a value that is a color. If you want both password and color to be random then use the IF statement concept
if(!etPW.getText().toString().equals(etCPW.getText().toString())){
Toast.makeText(MainActivity.this,"Password Does NOT\n"+"Match Confirm Password",Toast.LENGTH_LONG).show();
etPW.setText("");
etCPW.setText("");
etPW.requestFocus();
return;
}

My app won't load when I bring in a MediaPlayer

I'm working on a simple number guessing game. At the moment I have it set that when you guess the correct number it takes you to WinActivity.java. All I want it to do on that screen is say "You won" and to play a little trumpet victory sound (and also display a button that'll bring them to the GameActivity if they want to play again).
The trouble is, when I try bringing in a MediaPlayer the app doesn't even start.
Here is my code for my WinActivity that contains the MediaPlayer.
package com.example.jeremy.numberguessinggame;
import android.content.Intent;
import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class WinActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_win);
MediaPlayer trumpetsound = MediaPlayer.create(this,R.raw.trumpet);
trumpetsound.start();
Button btnPlayAgain = (Button) findViewById(R.id.button2);
TextView youWon = (TextView) findViewById(R.id.textViewYouWon);
btnPlayAgain.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent playAgainIntent = new Intent(WinActivity.this,GameActivity.class);
startActivity(playAgainIntent);
}
});
}
}
When I run the app the Messages Gradle Build window will pop up and says "error: cannot find symbol variable raw".
I added the raw folder to the res location, and was able to drag the sounds into the folder no problem.
I just don't see why I can't make this MediaPlayer work.
I would love some help. If you need more information I'll be glad to give it to you.

Android: On Click gradual visibility change

I have got a little problem which is for me impossible to solve. I've got lots of TableRows called Radek_X and they are set to be android:visibility="gone".
And I need that if you for the first time, click on button(there is only one button for that process) it will change Radek_1 to android:visibility="visible" if you click on the button for the second time it will change Radek_2 from gone to visible, while Radek_1 is still visible. And so on for all others TableRows. I'm really desperate. I will be very grateful for any help! Have a nice day!
Here is my java file
package jansoldat.formular100;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TableRow;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
Button buttonPridejStaniceni;
TableRow Radek_2, Radek_3, Radek_4,Radek_5,Radek_6;
#Override
private ArrayList<String> arrayList;
private ArrayAdapter<String> adapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonPridejStaniceni = (Button) findViewById(R.id.buttonPridejStaniceni);
Radek_2 = (TableRow) findViewById(R.id.Radek_2);
Radek_3 = (TableRow) findViewById(R.id.Radek_3);
Radek_4 = (TableRow) findViewById(R.id.Radek_4);
Radek_5 = (TableRow) findViewById(R.id.Radek_5);
Radek_6 = (TableRow) findViewById(R.id.Radek_6);
}
public void PridejDalsiStaniceniClicked(View v)
{
Radek_2.setVisibility(View.VISIBLE);
Radek_3.setVisibility(View.VISIBLE);
Radek_3.setVisibility(View.VISIBLE);
Radek_4.setVisibility(View.VISIBLE);
Radek_5.setVisibility(View.VISIBLE);
Radek_6.setVisibility(View.VISIBLE);
}
}
`
It's actually easier than you think, change your onClick method, which I assume you're setting by xml to PridejDalsiStaniceniClicked to this:
int[] views = new int[]{R.id.Radek_2,R.id.Radek_3,R.id.Radek_4};//...
int counter = 0;
public void PridejDalsiStaniceniClicked(View v)
{
findViewById(views[counter]).setVisibility(View.VISIBLE);
if(counter<views.length){
counter++;
}
}
What happens inside is that we will fetch the view that matches the counter of times pressed while there are still views in the array. Some people don't realize that view ids are integers and can be stored in an array like in the example.

Categories