How to finish Activity from AsyncTask class in android? - android

I have an activity with a hamburger menu. When I click on the hamburger menu logout enty, it will call an AsyncTask. After the API was called, if the statuscode indicates success then I need to call loginactivity. Up to here it works fine, but my problem is when I press the back button in login then it goes back to the previous screen. How to fix this? How do I finish activity in AsyncTask?
public class LandingActivityNew extends AppCompatActivity {
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
drawerLayout.closeDrawers();
int id = menuItem.getItemId();
switch (id){
case R.id.navItemSettings:
Intent iSettings = new Intent(LandingActivityNew.this,SettingsActivity.class);
startActivity(iSettings);
finish();
break;
case R.id.navItemTC:
// Toast.makeText(LandingActivityNew.this, "Settings", Toast.LENGTH_LONG).show();
Intent iTerms = new Intent(LandingActivityNew.this,TermsConditions.class);
startActivity(iTerms);
break;
case R.id.navItemPrivacy:
//Toast.makeText(LandingActivityNew.this, "Privacy", Toast.LENGTH_LONG).show();
Intent iPrivacy = new Intent(LandingActivityNew.this,ConsentActivity.class);
startActivity(iPrivacy);
break;
case R.id.navItemReportProblem:
Toast.makeText(LandingActivityNew.this, "Report a Problem", Toast.LENGTH_LONG).show();
break;
case R.id.navItemFAQ:
Toast.makeText(LandingActivityNew.this, "FAQ", Toast.LENGTH_LONG).show();
break;
case R.id.navItemShare:
Toast.makeText(LandingActivityNew.this, "Share", Toast.LENGTH_LONG).show();
break;
case R.id.navItemLogout:
new LogoutAsyncTask(LandingActivityNew.this).execute();
break;
}
return false;
}
});
}
AsyncTask class like this...
public class LogoutAsyncTask extends AsyncTask<String,String,String> {
Context context;
public LogoutAsyncTask(Context context){
this.context = context;
}
#Override
protected void onPreExecute() {}
#Override
protected String doInBackground(String... params) {}
#Override
protected void onPostExecute(String file_url) {
if (pDialog.isShowing()) {
pDialog.dismiss();
}
int appStatusCode = getLogoutResponse.getAppStatusCode();
if (appStatusCode == Constants.APP_STATUS_CODE_SUCCESS) {
***Intent logout=new Intent(context,LoginActivity.class);
context.startActivity(logout);
((Activity)context).finish();***
} else {
ExceptionMessages.showAlertDialog(context, "Unable to Logout", getLogoutResponse.getMessages().get(0), true);
}
}
}
in onPost() I need to finish the activity call, how to do that?

Try this way,
Intent iobj = new Intent(Activity_First.this, Activity_Second.class);
iobj.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(iobj);

How to finish Activity from AsyncTask class in android?
Because passing LandingActivityNew.this in LogoutAsyncTask class. Do it as:
((LandingActivityNew)context).finish();
in onPostExecute method

Intent logout=new Intent(yourActivity.this,LoginActivity.class);
yourActivity.this.startActivity(logout);
yourActivity.this.finish();
Hope it works. Thanx. If this not work tell me i give u better answer

Change the LogoutAsyncTask with below code:
public class LogoutAsyncTask extends AsyncTask<String, String, String> {
Activity activity;
LandingActivityNew obj;
public LogoutAsyncTask(Activity activity) {
this.activity = activity;
obj = activity.getApplicationContext();
}
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... params) {
}
#Override
protected void onPostExecute(String file_url) {
if (pDialog.isShowing()) {
pDialog.dismiss();
}
int appStatusCode = getLogoutResponse.getAppStatusCode();
if (appStatusCode == Constants.APP_STATUS_CODE_SUCCESS) {
***Intent logout=new Intent(activity,LoginActivity.class);
activity.startActivity(logout);
obj.finish();
} else {
ExceptionMessages.showAlertDialog(activity, "Unable to Logout", getLogoutResponse.getMessages().get(0), true);
}
}
}

Related

android - doInBackground return always false

I'm trying to shows a ProgressDialog while a list is loading data in an AsyncTask, but 'exito' in onPostExecute is never true, and the dialog never dismiss.
I tried to delete the if (exito) but the progressDialog dismiss and the list is charged a few seconds later, and it isn't I want.
I want that progressDialog shows while is loading, and when is loaded, dismiss the progressDialog and change fragment.
Where is my mistake? Thanks
private class ATCargarProductos extends AsyncTask<Void, Integer, Boolean>{
boolean terminado = false;
Bundle bdl;
FragmentTransaction transaction;
ProgressDialog progressDialog;
ArrayList<ItemDetails> results = new ArrayList<ItemDetails>();
public ATCargarProductos(FragmentTransaction transaction){
this.transaction = transaction;
}
#Override
protected Boolean doInBackground(Void... params) {
if (compruebaConexion()) {
rellenaLista(new CallBack() {
#Override
public void onSuccess(final ArrayList<Comida> listaComidas) {
for (int i = 0; i < listaComidas.size(); i++) {
ItemDetails item_details = new ItemDetails(listaComidas.get(i));
if (item_details.getTipo().equals("B")) {
results.add(item_details);
}
}
Fragment fragmentProductos = new FragmentProductos();
bdl = new Bundle(2);
bdl.putInt("tipoProducto", 1);
bdl.putParcelableArrayList("resultados", results);
fragmentProductos.setArguments(bdl);
completado = true;
}
#Override
public void onFail(String msg) {
}
});
return completado;
} else {
return false;
}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(getActivity(), R.style.AppTheme_Dark_Dialog);
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Cargando lista...");
progressDialog.show();
}
#Override
protected void onPostExecute(Boolean exito) {
super.onPostExecute(exito);
if (exito) {
progressDialog.dismiss();
transaction.commit();
}
}
}
rellenaLista() is asynchronous.
Since it's running on a different thread, return completado; is executed before you reach onSuccess(), and therefore completado is still false.
You don't really need an AsyncTask.
You can do the following:
if (compruebaConexion()) {
// show progress dialog here
rellenaLista(new CallBack() {
#Override
public void onSuccess(final ArrayList<Comida> listaComidas) {
// dismiss dialog
// handle success
}
#Override
public void onFail(String msg) {
// dismiss dialog
// handle failure
}
});
}
I think that the method compruebaConexion()is always false, if you can add to the question the code of this method. I could admit this idea.
Create a class like that. And check your internet connection with it.
public class EZInternetConnection {
public static boolean isNetworkConnected(Context context)
{
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
boolean flag = cm.getActiveNetworkInfo() != null &&
cm.getActiveNetworkInfo().isConnectedOrConnecting();
return flag;
}
}
Usage:
if(EZInternetConnection.isNetworkConnected( context ))
{
//internet connection is ok.
//other codes.
}
else
{
//no internet.
}

How to implement onBackPressed() & intents in fragment?

I know that onBackPressed() is a method in activity but, I want to use the functionality in fragments such that when back button is pressed, it gets redirected to another activity via Intent. Is there any solution to this ?
public class News_Events_fragment extends Fragment {
ProgressDialog pd;
ListView lv1;
SharedPreferences sharedPreferences = null;
int NotiCount;
TextView txt_title, txt_msg, textView;
Context context;
Intent intent ;
ArrayList<SliderMsgTitleModel> CurrentOfficersPastList;
NewsActivityAdapter pastAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
context = (Context) getActivity();
View rootView = inflater.inflate(R.layout.activity_news, container, false);
new AsyncTask<Void, Void, ArrayList<SliderMsgTitleModel>>() {
protected void onPreExecute() {
pd = new ProgressDialog(getActivity());
pd.setCancelable(true);
pd.setTitle("UPOA");
pd.setMessage("Please wait,loading the data...");
pd.show();
}
#Override
protected ArrayList<SliderMsgTitleModel> doInBackground(
Void... params) {
System.out.println("In Background");
CurrentOfficersPastList = new ArrayList<SliderMsgTitleModel>();
// display view for selected nav drawer item
ParseQuery<ParseObject> query = ParseQuery.getQuery("message");
query.whereEqualTo("featured_status", true);
// query.whereEqualTo("push_status", true);
query.orderByDescending("updatedAt");
query.selectKeys(Arrays.asList("title"));
query.selectKeys(Arrays.asList("message"));
try {
query.setCachePolicy(ParseQuery.CachePolicy.NETWORK_ELSE_CACHE);
List<ParseObject> results = query.find();
for (int i = 0; i < results.size(); i++) {
ParseObject object = results.get(i);
CurrentOfficersPastList.add(new SliderMsgTitleModel(
object.getString("title"), object
.getString("message")));
System.out.println("title is=="
+ object.getString("title") + "&& message is"
+ object.getString("message") + "size is"
+ CurrentOfficersPastList.size());
}
} catch (Exception e) {
e.getMessage();
}
pd.dismiss();
return CurrentOfficersPastList;
}
#SuppressWarnings("unchecked")
#Override
protected void onPostExecute(ArrayList<SliderMsgTitleModel> value) {
pd.dismiss();
/*Intent ent = new Intent(getActivity(), NewsActivity.class);
ent.putExtra("NEWSLIST", (ArrayList<SliderMsgTitleModel>) value);
startActivity(ent);
System.out.println("Value is" + value.size());*/
CurrentOfficersPastList = new ArrayList<SliderMsgTitleModel>();
CurrentOfficersPastList = value;
lv1 = (ListView) getActivity().findViewById(R.id.list_title);
pastAdapter = new NewsActivityAdapter(getActivity(), R.layout.activity_news_txt, CurrentOfficersPastList);
lv1.setAdapter(pastAdapter);
}
}.execute();
return rootView;
}
public void onBackPressed() {
// TODO Auto-generated method stub
//super.onBackPressed();
//Toast.makeText(getApplicationContext(), "click",2000).show();
String cameback="CameBack";
intent = new Intent(getActivity(),HomeActivity.class);
intent.putExtra("Comingback", cameback);
startActivity(intent);
}
}
You can interact with the fragment using a callback interface. In your activity add the following:
public class MyActivity extends Activity {
protected OnBackPressedListener onBackPressedListener;
public interface OnBackPressedListener {
void doBack();
}
public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
this.onBackPressedListener = onBackPressedListener;
}
#Override
public void onBackPressed() {
if (onBackPressedListener != null)
onBackPressedListener.doBack();
else
super.onBackPressed();
}
#Override
protected void onDestroy() {
onBackPressedListener = null;
super.onDestroy();
}
}
In your fragment add the following:
public class MyFragment extends Fragment implements MyActivity.OnBackPressedListener {
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((MyActivity) getActivity()).setOnBackPressedListener(this);
}
#Override
public void doBack() {
//BackPressed in activity will call this;
}
}
Yes, There is. You should implement like this.
#Override
public void onBackPressed() {
if (fragment != null)
//user defined onBackPressed method. Not of Fragment.
fragment.onBackPressed();
} else {
//this will pass BackPress event to activity. If not called, it will
//prevent activity to get BackPress event.
super.onBackPressed();
}
}
Explanation
Check whether your fragment is initialized or not. If it is, then pass on back press event to your fragment.
If above condition not passed, just pass back press to your activity so that it will handle it.
Note
Here condition can be anything. I just take fragment initialization as an example. May be that can't be helped you. You need to define your own condition to pass it to fragment.
Edit
I created a sample application on GitHub to implement Back Stack of fragment .
Download Fragment Back Stack application.
Override onKeyDown instead of onBackPressed. Not necessarily . But this works for me
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
String cameback="CameBack";
intent = new Intent(getActivity(),HomeActivity.class);
intent.putExtra("Comingback", cameback);
startActivity(intent);
return true
}
return false;
}
You can implement onKeyListener for your fragment and call next activity within that.
I've never tried this. But i hope it may help
For Example
fragmentObject.getView().setOnKeyListener( new OnKeyListener()
{
#Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
//your code here
}
return false;
}
} );
You need to override onBackPressed method in fragment.

How to do method onPostExecute initiate new Activity

I have one task that execute the method doInBackground and return a boolean value. What I want is to initiate a new Intent but the method startActivity is not available. How can I do that?
My task:
public class LoginTask extends AsyncTask<String, Integer, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
boolean sucess;
//do some stuff
return sucess;
}
#Override
protected void onPostExecute(Boolean result) {
if (result) {
//startActivity(new Intent(this, MainViewActivity.class));
//it doesn't find startActivity
}
}
}
Pass the Activity that starts the AsyncTak in the constructor
public class LoginTask {
private Context mCtx;
public LoginTask(Context ctx){
mCtx = ctx;
}
....
#Override
protected void onPostExecute(Boolean result) {
if (result) {
mCtx.startActivity(new Intent(mCtx, MainViewActivity.class));
}
}
}
A remark about previous replies:
Please remember to do not leak your activity. Use WeakReference class:
public static class LoginTask extends AsyncTask<String, Integer, Boolean> {
WeakReference<Activity> mActivityReference;
public LoginTask(Activity activity){
this.mActivityReference = new WeakReference<Activity>(activity);
}
#Override
protected Boolean doInBackground(String... params) {
boolean sucess;
//do some stuff
return sucess;
}
#Override
protected void onPostExecute(Boolean result) {
if (result && mActivityReference.get() != null) {
Activity activity = mActivityReference.get();
activity.startActivity(new Intent(activity, MainViewActivity.class));
}
}
}
You need to create the task with a reference to the activity or context that spawned it.
public class LoginTask extends AsyncTask<String, Integer, Boolean> {
Activity mActivity;
public LoginTask(Activity activity){
this.mActivity = mActivity;
}
#Override
protected Boolean doInBackground(String... params) {
boolean sucess;
//do some stuff
return sucess;
}
#Override
protected void onPostExecute(Boolean result) {
if (result) {
mActivity.startActivity(new Intent(mContext, MainViewActivity.class));
}
}
}
Are you sure that startActivity is not available? I just tested it and it works fine for me.
I think you should replace the this in your line, because the this doesn't refer to the Activity, it refers to the ASyncTask.
startActivity(new Intent(getApplicationContext(), MainViewActivity.class));
That should work.
this inside onPostExecute() refers to AsyncTask class instance.
Use YourActivityName.this instead:
startActivity(new Intent(ParentActivity.this, MainViewActivity.class));

Disable Buttons during AsyncTask

I programmed an quiz-app and if I touch one of the answers in an AsyncTask if the answer is correct I set the color to green or if it is false to red.
But now during the time the AsyncTask runs I can press other buttons like the "change question" button or on another one of the answers. This is then done after the AsyncTask has finished it's work. So the next question is loaded and it automatically answers the next question or uses one of the jokers what ever.
I tried to setEnabled(false) the Buttons but they are still bugging.
How do I prevent this?
private void disableOrDisableButtons(boolean boo) {
buttonAnswer1.setEnabled(boo);
buttonAnswer2.setEnabled(boo);
buttonAnswer3.setEnabled(boo);
buttonAnswer4.setEnabled(boo);
}
and here I start the AsyncTask
disableOrDisableButtons(false);
new PrepareAdapter().execute(null, null, null);
in my AsyncTask
#Override
protected void onPreExecute() {
disableOrDisableButtons(false);
if (correctAnswerAtButton != buttonClicked) {
switch (buttonClicked) {
case 1:
buttonAnswer1.setTextColor(Color.RED);
break;
case 2:
buttonAnswer2.setTextColor(Color.RED);
break;
case 3:
buttonAnswer3.setTextColor(Color.RED);
break;
case 4:
buttonAnswer4.setTextColor(Color.RED);
break;
}
if (buttonClicked != 0) { // 0.. if second chance joker used
wrongAnswer = true;
}
}
switch (correctAnswerAtButton) {
case 1:
buttonAnswer1.setTextColor(Color.GREEN);
return;
case 2:
buttonAnswer2.setTextColor(Color.GREEN);
return;
case 3:
buttonAnswer3.setTextColor(Color.GREEN);
return;
case 4:
buttonAnswer4.setTextColor(Color.GREEN);
return;
}
}
I you want to disable the whole interface while the AsyncTask runs, you can use code such as the following to display a dialog:
public abstract class BaseAsyncTask<Param, Result> extends AsyncTask<Param, Void, Result> implements DialogInterface.OnCancelListener {
private static final String TAG = "BaseAsyncTask";
private ProgressDialog dialog = null;
protected Context ctx = null;
protected Exception exception = null;
public BaseAsyncTask(Context ctx) {
this.ctx = ctx;
}
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(ctx, WLConstants.MSG_TITLE_LOADING_DIALOG, WLConstants.MSG_LOADING_DIALOG, true);
dialog.setCancelable(true);
dialog.setOnCancelListener(this);
if (ctx instanceof WozzonActivity) {
((WozzonActivity) ctx).setCurrentDialog(dialog);
}
}
#Override
protected Result doInBackground(Param... parameters) {
try {
return inBackground(parameters);
} catch (Exception ex) {
exception = ex;
Log.e(TAG, ex.getClass().getName(), ex);
return null;
}
};
#Override
protected void onPostExecute(Result result) {
try {
dialog.dismiss();
} catch (Exception ex) {
}// TODO:
if (result == null) {
onException(exception);
} else {
onResult(result);
}
}
protected void onException(Exception ex) {
if (ex != null && ex instanceof WozzonException) {
Toast.makeText(ctx, ex.getMessage(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ctx, WLConstants._ERROR_MSG, Toast.LENGTH_SHORT).show();
}
}
public abstract void onResult(Result result);
public abstract Result inBackground(Param... parameters) throws Exception;
#Override
public void onCancel(DialogInterface theDialog) {
cancel(true);
}
}
You need to use the onPreExecute() method of the ASyncTask().
Your problem is not related to threads at all. Try setTextColor(#ff0000) and settextColor(#00ff00), instead of settextColor(Color.RED) and setTextColor(Color.GREEN).
This is the way i use it now to lock my screen during the AsyncTask. For me it is perfect now. Hope it can help u.
private class PrepareAdapter extends AsyncTask<Void, Void, Integer>
implements DialogInterface.OnCancelListener {
private Dialog dialog = null;
#Override
protected void onPreExecute() {
// To disable the whole screen --> setCancelable(false);
dialog = new Dialog(WerWeissWasQuizActivity.this, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
dialog.setCancelable(false);
dialog.show();
}
#Override
protected Integer doInBackground(Void... params) {
dialog.dismiss();
return 0;
}
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//do other stuff...
}
#Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
cancel(true);
}
}

Asynk task android

I have a tabgroup having multiple activities. In one of the tabs i have two activities between whom i want to place a progress dialog.For this i am using Asynk Task. Following is my AsynkTask class which i have made an inner class for AboutUs activity:
private class TheTask extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
progDialog = ProgressDialog.show(AboutUs.this.getParent(), "Loading... ",
"please wait....", true);
}
#Override
protected Void doInBackground(Void... params) {
final Intent aboutusIntent = new Intent(getParent(), Departments.class);
final TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("Departments", aboutusIntent);
return null;
}
#Override
protected void onPostExecute(Void result) {
if(progDialog.isShowing())
{
progDialog.dismiss();
}
}
}
I am calling this class in my AboutUs activity :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aboutus);
.
.
.
.
/* Button for going to Departments */
Button ourdepbtn = (Button) findViewById(R.id.departmentsbutton);
ourdepbtn.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
//ourDepartments();
new TheTask().execute();
return false;
}
});
}
However this does'nt start a new activity i.e. Departments. The progress dialog appears and then disappears but activity never loads.
Any suggestions..??
First, you cannot start an activity from a non GUI thread (which Async doInBackground() is). Just start directly inside your Button.onClick() (why you use onTouch?) listener.
If you want to show up a ProgressDialog for the new Activity as soon as possible, you need to create it in the new (child) Activity onCreate(), as your ProgressDialog is connected to the new (child) activity (is it?). Take care about the order of creating layouts (create the ProgressDialog after calling setContentView()).
I am not very sure why you want to show that ProgressDialog. Is there something which delays the display of the childActivity? You loading some data? Then, the Dialog should be related to that loading task (Async I guess).
private class TheTask extends AsyncTask{
Context con;
Intent aboutusIntent;
TabGroupActivity parentActivity;
private TheTask(Context context)
{
this.con=context;
}
#Override
protected void onPreExecute() {
progDialog = ProgressDialog.show(con, "Loading... ",
"please wait....", true);
}
#Override
protected Void doInBackground(Void... params) {
aboutusIntent = new Intent(con, Departments.class);
parentActivity = (TabGroupActivity)getParent();
return null;
}
#Override
protected void onPostExecute(Void result) {
if(progDialog.isShowing())
{
progDialog.dismiss();
}
parentActivity.startChildActivity("Departments", aboutusIntent);
}
}
Thanks for your suggestions Oliver :)

Categories

Resources