How to show dialog box from asyntask nonUI activity in android? - android

i have implemented code form the below link to check the idle time of the application
How to intent to another page on android/pop up a message from idle time?
Instead using thread i used asyntask...Now my problem once it reaches the idle time..i want to show dialog to the user application is end relogin from the login activity..
How can i call dialog from the asynctask onpostExcute
public class session extends AsyncTask<Void,Void,Void> {
private static final String TAG=session.class.getName();
private long lastUsed;
private long period;
private boolean stop;
Context context;
final Dialog dialog = new Dialog(context);
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
//here i do the process.......
}
#Override
protected void onPostExecute(Void x){
//stuff to be done after task executes(done on UI thread)
// For Dialog Button**********************************
dialog.setContentView(R.layout.dialog);
dialog.setTitle("Result");
final TextView dialogtxt = (TextView) dialog
.findViewById(R.id.textView1);
final Button closeButton = (Button) dialog
.findViewById(R.id.button1);
closeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
dialog.dismiss();
}
});
dialogtxt.setText("session time out");
dialog.show();
// ****************************************************
}
#Override
protected void onPreExecute(){
//stuff to be done after task executes(done on UI thread)
}
}

You can do it by calling the dialog from either one of the methods except the doInBackground method.
You may call it in the onPreExecute and show the dialog there and after your background task is done you can cancel it from the onPostExecite method. If you want even more control you can also do it using onProgressUpdate. Just dispatch the progress from your background task by calling publishProgress and overwrite the onProgressUpdate method and do whatever you want there.
This is an example taken right out of the docs.
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}

The Asynctask need to get the Context.
If your Asynctask is embeded into the activity, just call the java Activity.this as a context.
You can also put a context as a field in the Asynctask and then give it as an arg to Asynctask.
You can call the Dialog.show in the onPostExecute, it's on UI Thread.
This sample AsyncTask is embeded into an activity
public class AsyncDialogBuilder extends AsyncTask {
private Context context = DriverOnTripActivity.this;
private final AlertDialog.Builder dialog = new AlertDialog.Builder(context);
private Integer remoteAllWaitinOnCount;
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
}
#Override
protected Integer doInBackground(Integer... integers) {
remoteAllWaitinOnCount = User.getRemoteAllWaitinOnCount(latestClosestKojo.getRemoteId());
if (remoteAllWaitinOnCount > 0) {
try {
makeDialog();
} catch (Exception e) {
e.printStackTrace();
}
return 100;
} else {
return 99;
}
}
private void makeDialog() {
dialog.setTitle(latestClosestKojo.getName()
+ " - "
+ remoteAllWaitinOnCount
+ " Kojoalas");
dialog.setPositiveButton("S'arreter", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
isDialogPrompted = false;
dialogInterface.dismiss();
goToOnBoardingActivity();
}
});
dialog.setNegativeButton("Ignorer", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
isDialogPrompted = false;
dialogInterface.dismiss();
}
});
}
#Override
protected void onPostExecute(Integer integers) {
if (integers >= 100 && dialog != null) {
dialog.show();
isDialogPrompted = true;
}
}
}

Related

Stopping AsyncTask in Android

I am trying to stop an AsyncTask in Android. In doInBackground it runs through an IP - Address list and tries to ping all of them.
Furthermore, when executing the AsyncTask a ProgressDialog opens which you can cancel. Calling this cancel - text calls the onCancelled method in AsyncTask. So, this method is being called, but it seems as if it is never stopped because when I hit the button Find again, I always get the following error message:
java.lang.IllegalStateException: Cannot execute task: the task has already been executed (a task can be executed only once)
Here is my code:
private Settings.HostWorker hostWorker;
private void initComponents() {
hostWorker = new Settings.HostWorker();
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if(!hostWorker.isCancelled()) {
hostWorker.cancel(true);
}
}
});
}
findServerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
if(findServerButton.isClickable()) {
progressDialog.show();
hostWorker.execute();
findServerButton.setClickable(false);
}
}
});
private class HostWorker extends AsyncTask<Integer, String, Void> {
#Override
protected Void doInBackground(Integer... params) {
try {
for (int i = 0; i <= 255; i++) {
String ip = createHostsList(i);
if (ip != null) {
publishProgress(ip);
}
if(isCancelled())
{
break;
}
}
} catch (Exception e) {
MyAlertDialog myAlertDialog = new MyAlertDialog(getBaseContext(), "Error in Settings - doInBackground: " + e.getMessage());
myAlertDialog.showAlertDialog();
}
return null;
}
protected void onProgressUpdate(String... values) {
hostsOnline.add(values[0]);
settingsCustomArrayAdapter.notifyDataSetChanged();
}
protected void onCancelled(){
findServerButton.setClickable(true);
}
#Override
protected void onPostExecute(Void aVoid)
{
super.onPostExecute(aVoid);
}
}
The error
Cannot execute task: the task has already been executed (a task can be executed only once)
suggests that you need to create a new HostWorker instance each time you want to run the task. You could achieve this by removing the line
hostWorker = new Settings.HostWorker();
from initComponents and instead adding it into your findServerButton OnClickListener like so:
findServerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
if(findServerButton.isClickable()) {
progressDialog.show();
hostworker = new Settings.HostWorker(); // Line added here.
hostWorker.execute();
findServerButton.setClickable(false);
}
}
});

My app crashes with AsyncTask

I'm new to android and have a problem with my simple application.
I using a very simple counter using AsyncTask.
When I run the app and start the counter, it counts to 10, and then instead of printing "DONE!" the app just crushes, I have no idea why. Here's my code.
(The activity has 3 buttons to create, start and cancel the task).
public class AsyncTaskActivity extends AppCompatActivity {
AsyncTask myAsyncTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async_task);
}
public static void startActivity(Context context){
Intent intent = new Intent(context, AsyncTaskActivity.class);
context.startActivity(intent);
}
public void createNewTask(View view) {
TextView textView = findViewById(R.id.text_view_id);
myAsyncTask = new MyAsyncTask(textView);
}
public void startTask(View view) {
myAsyncTask.execute();
}
public void cancelTask(View view) {
myAsyncTask.cancel(true);
}
private static class MyAsyncTask extends AsyncTask{
private TextView textView;
public MyAsyncTask(TextView textView){
this.textView = textView;
}
#Override
protected Object doInBackground(Object[] objects) {
for(int counter = 0; counter <= 10; counter ++){
if(!isCancelled()) {
textView.setText(String.valueOf(counter));
SystemClock.sleep(500);
}
else
break;
}
textView.setText("DONE!");
return null;
}
}
You cannot update UI from background thread mean the code inside doInBackGround runs on background thread
#Override
protected Object doInBackground(Object[] objects) {
for(int counter = 0; counter <= 10; counter ++){
if(!isCancelled()) {
textView.setText(String.valueOf(counter));
SystemClock.sleep(500);
}
else
break;
}
textView.setText("DONE!");
// ^^^^^ crash , cannot update UI from background thread
return null;
}
so instead use onPostExecuted
protected void onPostExecute(Long result) {
textView.setText("DONE!");
}
Note: if you cancel the task then you will find the same crash with textView.setText(String.valueOf(counter));.
Always use generic types and pass the resultant counter value and update UI accordingly.
private static class MyAsyncTask extends AsyncTask<Void,Void,Integer>{
private TextView textView;
public MyAsyncTask(TextView textView){
this.textView = textView;
}
protected Long doInBackground(Void... obj) {
for(int counter = 0; counter <= 10; counter ++){
if(!isCancelled()) {
SystemClock.sleep(500);
return counter;
}
else
break;
}
return null;
}
protected void onPostExecute(Integer result) {
if(result != null)
textView.setText(String.valueOf(result));
else
textView.setText(String.valueOf("Done"));
// your current code will set done no matter the task is cancelled or not
}
}
You can't edit View from AsyncTask doInBackground (only main thread). So move setText to onPostExecute
#Override
protected void onPostExecute(Void result)
textView.setText("DONE!");
}

Set Progress Dialog properly in asynctask

I currently trying to show a progress dialog on OnclickListener of a Dialogbox since my items are taking too long to fetch from Server.
I use Async task as suggested here (Android progress dialog) and this post (android problem with progress dialog) to show progress dialog The progress dialog is shown , however the code returns exception when it goes to do background that " Looper is not set". And when I set looper nothing happens.
I am not sure at this stage what is it that I am doing wrong.
public void firstMethod()
{
final CustomObj obj = getCustomObj();//not imp
Messages.getInstance().showAlert(MainActivity.this, "message", false, new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
}, new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
gotoAnotherPge(obj);
}
});
}
public void gotoAnotherPge(final CustomObject obj)
{
final ProgressDialog pd = new ProgressDialog(MainActivity.this);
new AsyncTask<Object, Object, Boolean>()
{
protected void onPreExecute()
{
pd.setMessage(String.format(Statics.getText(MainActivity.this, R.raw.dictionary, "subscriptions_loading_unsubscribing")));
pd.show();
}
protected Boolean doInBackground(Object... params)
{
try{
Looper.prepare();
final LocalPopulator lp = new LocalPopulator(MainActivity.this, 0)
{
#Override
public void populate()
{
List<Serializable> items = Arrays.asList(getItemHere(obj));
List<Serializable> listItems = new ArrayList<Serializable>();
listItems.addAll(items);
Serializable[] sItems = listItems.toArray(new Serializable[menuItems.size()]);
result = sItems;
}
};
showNextPage(true, 1, 0, lp);
Looper.loop();
}catch (Exception e){
Log.e("tag", e.getMessage());
/*
* The task failed
*/
return false;
}
return true;
}
protected void onPostExecute(Boolean result)
{
pd.dismiss();
}
};
MainActivity.this.runOnUiThread (new Runnable()
{
#Override
public void run()
{
// dismiss the progressdialog
pd.dismiss();
}
});
}

Update ProgressDialog from Thread inside Service

i want to increment a progress dialog from a thread inside a service, i have really hard time doing that, this is my code please help me.
I tried many different ways including asyncTask (I had problem with context)
and tried with static functions but its not working properly,
I pretty new with android please explain me the problem here.
the activity
public class MainActivity extends Activity {
ProgressDialog progressBar;
private void showProgrssBar() {
progressBar.show();
}
private void dismissProgressBar() {
progressBar.dismiss();
}
private void increaseProgressBar(int total) {
progressBar.incrementProgressBy(total);
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createProgressBarDialog();
Intent n = new Intent(this, myService.class);
startService(n);
}
private void createProgressBarDialog()
{
progressBar = new ProgressDialog(this);
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressBar.setMax(200);
progressBar.setMessage("Recieving bluetooth data");
progressBar.setCanceledOnTouchOutside(false);
}
the service:
public class myService extends Service
{
private myThread myThread;
Handler handler = new Handler()
{
#Override
public void handleMessage(android.os.Message msg)
{
int total = msg.getData().getInt("total");
if (total == -1)
{
dismissProgressBar();
}
else if (total == 0)
{
showProgrssBar();
}
else
{
increaseProgressBar(total);
}
}
};
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
myThread = new myThread(handler);
myThread.start();
return START_STICKY;
}
the thread
class myThread extends Thread
{
Handler h;
int numOfLinesToRead = 220;
int line = 0;
public myThread(Handler h)
{
this.h = h;
}
private void increaseProgressBarOnActivity(int i_MsgType)
{
Message msg = h.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", i_MsgType);
msg.setData(b);
h.sendMessage(msg);
}
#Override
public void run() {
super.run();
int increase;
try
{
Thread.sleep(1);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
for (; line < 220; line++)
{
increase = (line*100/numOfLinesToRead);
if (increase != 0)
{
increaseProgressBarOnActivity(increase);
try
{
Thread.sleep(90);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
Despite you having already tried AsyncTask, I still would strongly recommend to use it.
Just take a look at the onProgressUpdate() method. It is made to update the UI from AsyncTask.
Here is an example of how it could look like:
private class DownloadFilesTask extends AsyncTask<String, Integer, Long> {
private ProgressDialog progressBar;
#Override
protected void onPreExecute(){
super.onPreExecute();
progressBar= new ProgressDialog(getApplicationContext());
progressBar.setMessage("Loading...");
progressBar.show();
}
protected Long doInBackground(String... params) {
long someLong;
// do something here with params
// the Integer variable is used for progress
publishProgress(i);
// call it for example while downloading a file
return someLong;
}
// this is called whenever you call puhlishProgress(Integer)
protected void onProgressUpdate(Integer... progress) {
progressBar.incrementProgressBy(progress[0]);
}
// the onPostexecute method receives the return type of doInBackGround()
protected void onPostExecute(Long result) {
// do something with the result
progressBar.dismiss();
}
}
You said your problem was getting the Context. Well: Service is a Context
So you could simply make the AsyncTask an inner class of your Service and then use its Context.

Alert Dialog and ASync Task

i am trying to use Alert Dialog Box and Async Task in the activity and am getting the following error
Caused by: java.lang.RuntimeException: Can't create handler inside
thread that has not called Looper.prepare()
Code:
public class loginTask extends AsyncTask<Void, Void, Void> {
public ProgressDialog loginDialog = new ProgressDialog(
LoginActivity.this);
#Override
protected void onPreExecute() {
loginDialog.setMessage("Please wait Logging in");
loginDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
if(loginUser()) {
loginDialog.dismiss();
alertbox("title", "winnn", "Okay");
} else {
loginDialog.dismiss();
alertbox("title", "message", "Okay");
}
return null;
}
#Override
protected void onPostExecute(Void unused) {
loginDialog.dismiss();
Intent intentHome = new Intent(LoginActivity.this,
HomeActivity.class);
startActivity(intentHome);
}
}
You can't update UI inside the doInBackground() method directly. (Yes if you still want to execute then write the same inside the runOnUiThread() method inside the doInBackground())
Otherwise, do it inside the onPostExecute() method.
public class loginTask extends AsyncTask<Void, Void, Void>
{
public ProgressDialog loginDialog = new ProgressDialog( LoginActivity.this );
public Boolean flag;
#Override
protected void onPreExecute() {
loginDialog.setMessage("Please wait Logging in");
loginDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
if(loginUser())
flag = true;
else
flag=false;
return null;
}
#Override
protected void onPostExecute(Void unused) {
loginDialog.dismiss();
if(flag)
alertbox("title", "winnn", "Okay");
else
alertbox("title", "message", "Okay");
}
}
the onPreexecute and onPostExecute are part of the UI parts in the Async Task.. the doInBackground is a seperate thread so any thing done inside the doInBackground needs to be handled in the form of progressUpdate
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
Example Reference: Link
reflects any changes you need to make to the UI inbetween the doInBackground process.

Categories

Resources