Android Checking Website Updates Periodically (JSOUP) - java

I have a simple Android app. I am getting HTML elements from a website (article count from wikipedia) by use of JSOUP. I am getting article count on button click RefreshBtn() and show in a textview tv1 as shown below:
public class MainActivity extends ActionBarActivity {
String URL = "https://en.wikipedia.org";
Element article;
TextView tv1;
ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView)findViewById(R.id.tv1);
}
private class FetchWebsiteData extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
try {
Document doc = Jsoup.connect(URL).userAgent("Mozilla").get();
article = doc.select("div#articlecount > a").first();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
if(article == null) tv1.setText("null!");
else tv1.setText(article.text() + " articles found!");
mProgressDialog.dismiss();
}
}
public void RefreshBtn(View v) {
new FetchWebsiteData().execute();
}
...
}
I want to get article count periodically (for example in every 2 hours). Then maybe I can create push-notifications if there is a change. What is the best way to do this? I need some suggestions. Thanks.

The best way is to use the internal Alarm Manager.
Alarm Manager Example
another way is to implement a second Thread:
new Thread(new Runnable()
#Override
public void run()
{
try
{
while(true)
{
Thread.sleep(100000); //milliseconds
// Do Something
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}).start();

Related

Change TextView Between Activities

So i got a project with the following activities : MainActivity/GetJson/ TimerActivity.
GetJson activity :
public class GetJson extends AppCompatActivity {
String JSON_STRING;
String json;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void getJSON(View view){
new BackgroundTask().execute();
}
public class BackgroundTask extends AsyncTask<Void,Void,String> {
String json_url;
#Override
protected void onPreExecute() {
json_url="http://10.10.103.36/projet/php/fichier.php";
}
#Override
protected String doInBackground(Void... params) {
try {
URL url=new URL(json_url);
HttpURLConnection httpURLConnection=(HttpURLConnection)url.openConnection();
InputStream inputStream=httpURLConnection.getInputStream();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder=new StringBuilder();
while ((JSON_STRING= bufferedReader.readLine())!=null){
stringBuilder.append(JSON_STRING+"\n");
}
bufferedReader.close();
inputStream.close();;
httpURLConnection.disconnect();
return stringBuilder.toString().trim();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
json=result;
}
}
}
Timer Activity
public class TimerActivity extends Activity {
private TextView test;
String msg = "Hey";
private Handler mHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
test = (TextView) findViewById(R.id.compteur);
Timer timer = new Timer();
TimerTask tt = new TimerTask()
{
#Override
public void run()
{
test.setText(msg);
}
};
timer.scheduleAtFixedRate(tt,5000,1000); // Delay 5 seconds on the first run
// then run every second
test.setText(msg);
setContentView(R.layout.activity_main);
}
}
In my xml main activity i got 2 textview :
- compteur : to display a text from my timeractivity
- textViewJson : to display my json
I think my methods to get json( from GetJson) and display text(from TimerActivity) are correct. But the problem is that i can't setText from others activities to my main activity.
I don't have any compilation problem bu my textView aren't getting updated.
I tried both in GetJson and TimerActivity to just do :
TextView test;
test = (TextView) findViewById(R.id.compteur);
test.setText(msg);
In order to check if i can change the textview text without even using the returned values and nothing happens.
Any ideas ?
Have a good day !
Once you have the information you want to show in your TVs you should save it somewhere and load it when your Activity is created. You can't change the state of Views in a destroyed Activity. Use Intents (putExtra();) to pass data between your Activies or use SharedPreferences

Showing dialog box in android

I know this is duplicate but trust me i have tried many of the available codes and still not getting this worked.
Below are my code
public class LookIn extends AppCompatActivity implements View.OnClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
//Initializing properties
}
public void onClick(View v) {
// Event for button click
callHelper();
}
private void callHelper()
{
List result=null;
try {
String jsonResponse=new CallmeGetHelperAsyncTask(this).execute(params).get();
result= RestUtil.getUserList(jsonResponse);
}
catch (InterruptedException e) {
Log.e("Callme", Log.getStackTraceString(e));
} catch (ExecutionException e) {
Log.e("Callme", Log.getStackTraceString(e));
}
catch(JSONException x)
{
Log.e("Callme",Log.getStackTraceString(x) );
}
}
}
Below is my AsyncTask class
public class CallmeGetHelperAsyncTask extends AsyncTask<String,Void,String > {
private AppCompatActivity activity=null;
private ProgressDialog dialog=null;
public CallmeGetHelperAsyncTask(){}
public CallmeGetHelperAsyncTask(AppCompatActivity activity){
this.activity=activity;
//this.dialog= dialog;
}
#Override
protected void onPreExecute() {
if(this.dialog!=null)
{
Log.v("Callme", "Starting Dialog");
dialog = ProgressDialog.show(this.activity, "title", "message");
// this.dialog.setMessage("Looking for Helpers");
this.dialog.show();
}
else
{
dialog = ProgressDialog.show(this.activity, "title", "message");
}
}
#Override
protected void onPostExecute(String s) {
if(this.dialog!=null)
{
Log.v("Callme","Closing Dialog");
this.dialog.dismiss();
}
else
{
Log.v("Callme","Dialog is not initiated in CallmeGethelperAsyncTask");
}
}
#Override
protected String doInBackground(String... params) {
//call to webservice
}
}
I am not able to get what is the problem with above code.
One more bizarre i found(bizarre may be for me only because i am new). I tried printing Thread.currentThread.getId() from both my ActivityClass as well as from my AsyncTask and surprisingly both printed "1".
If i am not wrong then that says both codes are running from the same thread.
About this i have read Running multiple AsyncTasks at the same time -- not possible? which says earlier threadpool contained only 1 thread but i am using Android 5.1 which is supposed to contain 5 threads. So again i am confused over it.
Kindly take some time to explain. Thank you
Replace this:
public CallmeGetHelperAsyncTask(AppCompatActivity activity){
this.activity=activity;
//this.dialog= dialog;
}
with:
private Context context;
public CallmeGetHelperAsyncTask(Context context){
this.context=context;
}
and this:
dialog = ProgressDialog.show(this.activity, "title", "message");
with:
dialog = ProgressDialog.show(this.context, "title", "message");
and this:
String jsonResponse=new CallmeGetHelperAsyncTask(this).execute(params).get();
with:
String jsonResponse=new CallmeGetHelperAsyncTask(LookIn.this).execute(params).get();
Although i would rather not use the static method show of the progress dialog and build an Actual Progress Dialog.
Hope it helps!!!!

Asynctask w/ ProgressDialog

I know that have a lot of answers about this, but I can't find exactly what I need:
1) When users click on the button, shows a progress Dialog;
2) Executes a class AsyncTask and wait for the answer (it's a response using HTTPUrlConnection);
3) Dismiss Progress Dialog;
I tried a lot of things, but the progress dialog is not "appearing". My code:
public class MainActivity extends Activity implements OnTaskCompleted{
..
private ProgressDialog progressDialog;
private Button btnLogin;
..
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnLogin = (Button) findViewById(R.id.btnLogin);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
progressDialog = ProgressDialog.show(MainActivity.this,
"", "Scanning Please Wait", true);
try {
String param1 = "testParam1";
String param2 = "testParam2";
String response = new SyncHelper(MainActivity.this).execute("http://server.example.com/api", param1, param2).get(); //this way, my activity waits of the answer
Log.d(TAG, "Finished: " + response);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} else {
// user didn't entered username or password
Toast.makeText(getApplicationContext(),
"Done",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
}
}
});
}
public void onTaskCompleted()
{
progressDialog.dismiss();
}
public class SyncHelper extends AsyncTask<Object, Void, String>
{
..
private OnTaskCompleted listener;
..
protected String doInBackground(Object... url) {
String response = "";
try {
response = getRequest((String) url[0],(String) url[1], (String) url[2]); //Here I make a HttpURLConnection
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
#Override
protected void onPreExecute() {
}
protected void onPostExecute(String result) {
listener.onTaskCompleted();
}
}
public interface OnTaskCompleted{
void onTaskCompleted();
}
public class MainActivity extends Activity{
..
private Button btnLogin;
..
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnLogin = (Button) findViewById(R.id.btnLogin);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
try {
String param1 = "testParam1";
String param2 = "testParam2";
new SyncHelper(MainActivity.this).execute("http://server.example.com/api", param1, param2); //this way, my activity waits of the answer
Log.d(TAG, "Finished: " + response);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} else {
// user didn't entered username or password
Toast.makeText(getApplicationContext(),
"Done",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
}
}
});
}
public class SyncHelper extends AsyncTask<String, Void, String>
{
..
Context context;
private ProgressDialog pd;
..
public SyncHelper (Context c)
{
context = c;
}
#Override
protected void onPreExecute() {
pd = new ProgressDialog(context);
pd.setTitle("Processing...");
pd.setMessage("Please wait.");
pd.setCancelable(false);
pd.setIndeterminate(true);
pd.show();
}
protected String doInBackground(String... url) {
String response = "";
try {
response = getRequest(url[0], url[1], url[2]); //Here I make a HttpURLConnection
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
protected void onPostExecute(String result) {
// here you will be getting the response in String result.
if (pd.isShowing())
pd.dismiss();
}
}
When you are using get, using AsyncTask doesn't make any sense. Because get() will block the UI Thread, maybe thats why are not able to see the progress dialog. If you want to send the response back to the MainActivity then use the callback interface as you were using beofre.

Unable to close Progress Dialog in Android

I want to create a progress dialog in android, keep it open for 2 seconds then close it.
Below is the code I have written:
package com.example.proressdialogtest;
import android.app.activity;
import android.app.ProgressDialog;
import android.os.bundle;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
ProgressDialog pg = new ProgressDialog(MainActivity.this, 4);
pg.show(MainActivity.this, null, "Searching...", false);
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
pg.dismiss();
}
When I run the code on my device, the ProgressDialog is opened and then it stays open, it does not close after 2 seconds. What am I doing wrong?
As per the answers below. I have added the onPreExecute() and onPostExecute() methods before and after the doInBackground method respectively.
Here is the code for the two methods.
ProgressDialog pd;
public void onPreExceute() {
pd = new ProgressDialog(MainActivity.this);
pd.show(MainActivity.this, "", "Searching...", false);
}
public void onPostExecute() {
pd.dismiss();
}
The problem still persists. The progress bar will not close.
You are calling sleep() on the UI Thread. Don't do this. Use runOnUiThread or an AsyncTask
Painless Threading
AsyncTask
I would use an AsyncTask. You will start the ProgressDialog in onPreExecute() then close it in onPostExecute(). It is a UI element so using it in doInBackground() will give you the error
This SO answer has a good example of using it
Edit:
Use this code
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
final ProgressDialog pg ;
pg = ProgressDialog.show(MainActivity.this, null, "Searching...", false);
Thread timer=new Thread(){
public void run()
{
try {
sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
finally{
pg.dismiss();
}
}
};
timer.start();
}
}
You are pausing the UI thread by calling
Thread.sleep(2000);
Because Thread.sleep(x) will make the current thread sleep for x milli seconds
which is bad thing.
place
I don't know why
pg.dismiss() in finally block to make sure that progress dialog will be closed.
And also your Code won't run because you have missed
super.onCreate(savedInstanceState);
following code will work for you,
new AsyncTask<Integer, Integer, Boolean>()
{
ProgressDialog progressDialog = null;
#Override
protected void onPreExecute()
{
progressDialog = ProgressDialog.show(MainActivity.this, "",
"Loading...");
}
#Override
protected Boolean doInBackground(Integer... params)
{
if (params == null)
{
return false;
}
try
{
Thread.sleep(2000);
}
catch (Exception e)
{
return false;
}
return true;
}
#Override
protected void onPostExecute(Boolean result)
{
progressDialog.dismiss();
}
}.execute();

Point to object in UI from other class - Android SDK

I've just started development with Android and I have little experience in Java. I've got a button listener in my main Activity but I want to do a background task that updates an TextView in my UI. See the following code.
btnJSON.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
new BGTask().execute();
}
class BGTask extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... params) {
Thread.sleep(2000);
String x = "test";
return (String) x;
}
protected void onPostExecute(String result) {
tvData.setText(result);
}
}
});
This code works, however, when I move the code for the BGTask code to a seperate class file, its no longer possible to update the UI component tvData. How do a pass a reference to that object to the BGTask class?
Thanks!
What you need to do, if you want to move your task class to another file, is this:
Add a TextView field to BGTask and a constructor that takes a TextView.
Pass in the TextView you want to update.
Here is the code:
public class BGTask extends AsyncTask<Void, Void, String> {
private TextView tvData = null;
public BGTask(TextView tv) {
this.tvData = tv;
}
protected String doInBackground(Void... params) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String x = "test";
return (String) x;
}
protected void onPostExecute(String result) {
if (tvData != null)
tvData.setText(result);
}
}
And your activity will look like:
Button button = (Button) findViewById(R.id.button);
TextView tv = (TextView) findViewById(R.id.textview);
final BGTask task = new BGTask(tv);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
task.execute();
}
});

Categories

Resources