I am using ProgressDialog in AsyncTask. And If user Press Back Button, then AsyncTask will be cancelled, current fragment will replace by any other Fragment.
There is no issue if user is still on Application. Bu if he goes back and back speedly and at last stop application, It gives error IllegalStateException: Fragment not attached to Activity.
How to solve this ?
My Code:
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(getActivity(), "", "Loading...", true,
true, new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
CancelDialog();
}
});
}
public void CancelDialog() {
new FetchData().cancel(true);
for (int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
((FrameLayout) flMain).removeAllViews();
fm.beginTransaction().add(R.id.frame, new Home()).commit();
}
Home.java:
#Override
public void onResume() {
super.onResume();
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (event.getAction() == KeyEvent.ACTION_UP
&& keyCode == KeyEvent.KEYCODE_BACK) {
getView().clearFocus();
getActivity().finish();
return true;
}
return false;
}
});
}
After so many tried, lastly I have found Simple Answer: isAdded()
It will Return true if the Fragment is currently added to its Activity.
I used below code and it solved my problem.
#Override
protected void onPostExecute(Void result){
if(isAdded()){
// Code to display Data...
}
}
You should be careful when to call e.g getActivity() - your fragment might not (yet/already) be attached to an activity when you call such methods. Check out this.
Alternatively you can save the Activity instance when onAttach is called, but then you'll have to be careful what you do with that Activity instance, so that you do not make conflicting updates with another Fragment that is actually still attached.
isAdded and isDetached can be useful to check the state and avoid calling invalid methods.
Related
First thing I want to say, this was done by seeing a tutorial. Here is the Custom Alert Dialog activity part I am calling from a broadcast receiver. The only problem is the back button click. Once the Alert dialog activity got started, when I press the back button it is getting closed.
public class AlertDialogActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setFinishOnTouchOutside(false);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
setContentView(R.layout.activity_inmsgdialog);
}
#Override
public void onBackPressed()
{
super.onBackPressed();
Toast.makeText(getApplicationContext(), "Back Pressed", Toast.LENGTH_SHORT).show();
}
}
I have tried onBackPressed and I'm able to see the toast message but the activity is getting closed.
See here:
#Override
public void onBackPressed()
{
super.onBackPressed(); //Remove this line
Toast.makeText(getApplicationContext(), "Back Pressed", Toast.LENGTH_SHORT).show();
}
Do not call super.onBackPressed(); code if you want to disable back button for activity. So remove this line. Hope it helps.
You can use the below option to handle back button press
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//your code
return true;
} else {
}
}
Don't propagate the event and you should be good.
#Override
public void onBackPressed()
{
//don't call super
}
I saw many posts on this subject but couldnt find the right answer for me.
I have an activity that dims when i pop the popup window.
the back button working but only the second time i press it, the first press dismiss the popup but its not un-dim the activity because i cant catch the event from the popupwindows, the second press is catched by the activity and only then i can un-dim it.
here are my tries to accomplish this:
m_PopupWindow.setBackgroundDrawable(new BitmapDrawable());
m_PopupWindow.setOutsideTouchable(true);
View popUpWindowLaout = m_PopupWindow.getContentView();
popUpWindowLaout.setFocusableInTouchMode(true);
//first press doesnt get caught here
popUpWindowLaout.setOnKeyListener(new View.OnKeyListener()
{
#Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
m_ActionBar.show();
unShadeTheActivity();
m_PopupWindow.dismiss();
return true;
}
}
});
//this func will catch the second press and will work, but i want the first press will do it.
#Override
public void onBackPressed() {
if (m_PopupWindow != null)
{
m_ActionBar.show();
unShadeTheActivity();
m_PopupWindow.dismiss();
}
else
{
super.onBackPressed();
}
}
change
public void onBackPressed() {
if (m_PopupWindow != null)
{
m_ActionBar.show();
unShadeTheActivity();
m_PopupWindow.dismiss();
}
else
{
super.onBackPressed();
}
}
to
public void onBackPressed() {
super.onBackPressed();
if (m_PopupWindow != null)
{
m_ActionBar.show();
unShadeTheActivity();
m_PopupWindow.dismiss();
}
else
{
// rest of the code
// you can use finish,dismiss or call startActivity
// finish();
}
}
popupWindow.setOnShowListener(HandlePopupShowLister);
popupWindow.setOnDismissListener(HandlePopUpDismissListerner);
public static OnDismissListener HandlePopUpDismissListerner = new OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
// TODO Auto-generated method stub
Log.i("HandlePopUpDismissListerner", "HandlePopUpDismissListerner");
CommonVariable.IsPopupOpen = false;
}
};
public static OnShowListener HandlePopupShowLister = new OnShowListener() {
// onShowListener interface.
#Override
public void onShow(DialogInterface dialog) {
Log.i("HandlePopupShowLister", "HandlePopupShowLister");
// TODO Auto-generated method stub
CommonVariable.IsPopupOpen = true;
}
};
I am having problem on back button of hardware. In my main Activity, I have one List view(say 1). When I click on item of this List view(1), one Alert Dialog appears, in this alert dialog, there is one List view(say 2). Data of this List view(2) are being repeated when I press back button of hardware. I have also put cancel image on this alert dialog to dismiss, when I press this cancel image, data are not being repeated. I tried different methods onResume(), onPause(), onDestroy(), onRestart() to clear the array for List view(2), but nothing works. Here is my code...
case LIST_DIALOG :
LayoutInflater inflater2 = LayoutInflater.from(this);
View dialogview1 = inflater2.inflate(R.layout.listdialog, null);
AlertDialog.Builder dialogbuilder2 = new AlertDialog.Builder(this);
dialogbuilder2.setView(dialogview1);
dialogDetails = dialogbuilder2.create();
case LIST_DIALOG:
AlertDialog alertDialog1 = (AlertDialog) dialog;
// Cancel Alert Dialog
ImageView ivCancel = (ImageView) alertDialog1.findViewById(R.id.imgCancel);
ivCancel.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
dismissDialog(LIST_DIALOG);
arr2.clear();
}
});
// Friend List
showFriendList();
break;
// List view data are inserted with this function call
private void showFriendList() {
// TODO Auto-generated method stub
Request.executeMyFriendsRequestAsync(friendSession, new GraphUserListCallback() {
#Override
public void onCompleted(List<GraphUser> users, Response response) {
// TODO Auto-generated method stub
// arr2 = new ArrayList<String>();
for(GraphUser user : users)
{
arr2.add(user.getName());
}
adapter2 = new ArrayAdapter<String>(getBaseContext(), R.layout.single_row, R.id.txt,arr2);
lvDialog.setAdapter(adapter2);
lvDialog.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
adapter2.notifyDataSetChanged();
itemCount = lvDialog.getCount();
Toast.makeText(getBaseContext(), "" + itemCount, 1000).show();
}
});
}
// I tried these methods, but nothing works...
#Override
public void onResume()
{
super.onResume();
ShowSavedFiles();
arr2.clear();
}
#Override
public void onPause()
{
super.onPause();
arr1.clear();
arr2.clear();
}
#Override
public void onBackPressed() {
//super.onBackPressed();
// finish your Activity
arr2.clear();
return;
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
arr2.clear();
dismissDialog(LIST_DIALOG);
}
return false;
}
I'm not sure but might be adding the following code to your onKeyDown method might help out :
return super.onKeyDown(keyCode, event);
I want to have the possibility of cancel the load of current Android MediaPlayer URL when pressing back button (onBackPressed) and quit to the previous activity as if there was nothing.
This all happens while Activity loads.
onCreate has a ProgressDialog call. I want to cancel this dialog, cancel the creating/starting MediaPlayer and go back.
How to make it correctly?
#Override
public void onBackPressed() {
if (pd!=null) {if (mp3Service!=null) mp3Service.reset(getApplicationContext()); pd.onBackPressed();};
super.onBackPressed();
}
This doesn't work, moreover, in some time the screen begins to darken and hang the APP.
What's wrong, maybe I must call another thread? (playSong launches in separate thread).
If your progress dialog is visible then you need to override its onBackPressed method to handle the event:
pd = new ProgressDialog(this) {
public void onBackPressed() {
dismiss();
mediaPlayer.stop();
}
};
pd.setTitle("Loading");
pd.setMessage("Please Wait..");
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.show();
You could either try to check for OnCancelListenerin your dialog to the detect if your dialog has been canceled. Or you can try something like this
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
//Do your code here for canceling your service
return true;
}
return super.onKeyDown(keyCode, event);
}
When you create your dialog, you can add a cancel listener:
pd.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
// TODO cancel your music service
}
})
How can I specifically override just the back button while within a dialog to finish the entire activity and not just the dialog.
Using setOnCancelListener and setOnDismissListener do not work because there are other times that I simply close the dialog without closing the whole activity behind it.
Edit
Thanks Shubayu that may work!
I was also able to access just the back button in a dialog through this function.
dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
#Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK){
finish();
}
return false;
}
});
Override
public void onBackPressed ()
of the activity and put in the way you want the behavior in it. Also set a boolean from your dialog which you use inside onBackPressed() of the Activity. if the boolean is true, run the disabling part of the onBackPressed() code else don't.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK){
// your logic goes here
return true;
}
return super.onKeyDown(keyCode, event);
}
use the above code::
You can use : dialog.setOnCancelListener(.....)
first set dialog.setCancelable(true);
than you can place below code :
dialog.setOnCancelListener(new DialogInterface.OnCancelListener()
{
#Override
public void onCancel(DialogInterface dialog)
{
// add code backpress
}
});