I have added a popup activity inside my app which is popping after 15 seconds of my app start. But when I am opening another activity and coming back to my main activity the popup showing again. I want it to appear only the first time when user is opening the app. What changes I should make? Appreciate the help.
Here is the popup code:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (context != null) {
AlertDialog.Builder alert = new AlertDialog.Builder(context, R.style.MyAlertDialogStyle)
.setTitle("Title")
.setMessage("Message")
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
Intent intent = new Intent(MainActivity.this, WebActivity.class);
startActivity(intent);
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int which) {
dialogInterface.dismiss();
// do nothing
}
});
mDialog = alert.create();
mDialog.getWindow().getAttributes().windowAnimations = R.style.MyAlertDialogStyle;
if (!((Activity) context).isFinishing())
mDialog.show();
// .setIcon(R.drawable.inr1)
// .show();
}
}
}, 15000);
You can do this if it needs to pop up only on application start
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
//Set some flag on global constant
}
}
save a tag(counter) in sharedPrefrances for that When the application starts up interpretation is the first time app start
You can use a global variable in the application class like this.
public class global extends Application
// some Boolean variable to hold status
And make sure you put this class inside android manifests application tag
android:name
Add this code in your MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
if(sharedPreferences.getBoolean("IS_FIRST_TIME", true)) {
//show your dialog here
//...
//change the value of your sharedPreferences
sharedPreferences.edit().putBoolean("IS_FIRST_TIME", false).apply();
}
}
please check the activity lifecycle.
Note:Remove Handler.
Note 2:Create method and call the dialog
Note 3:check the below method in lifecycle.
onPause ():
Called as part of the activity lifecycle when an activity is going into the background, but has not (yet) been killed. The counterpart to onResume(). When activity B is launched in front of activity A, this callback will be invoked on A. B will not be created until A's onPause() returns, so be sure to not do anything lengthy here.
save a boolean inside sharedpreferences read its value and determine weather running for the first time or not.
here is the code that will help you.
public void firstimeRun(boolean value) {
SharedPreferences sharedPreferences = getPrefrenceManager();
sharedPreferences.edit().putBoolean("key", value).apply();
}
public boolean isRunningForthefirstTime() {
SharedPreferences sharedPreferences = getPrefrenceManager();
return sharedPreferences.getBoolean("key", false);
}
private SharedPreferences getPrefrenceManager() {
return PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
}
Type finish(); after your startActivity(intent);
Related
The EditButton of my app in Android Studio can be edited but once you have edited the texts it will not save when you exit the window. What to do?
public class BellPepperActivity extends AppCompatActivity {
TextView bpTextView;
AlertDialog dialog;
EditText editText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bell_pepper);
bpTextView = (TextView) findViewById(R.id.bpTextView);
dialog = new AlertDialog.Builder(this).create();
editText = new EditText(this);
dialog.setTitle("BELL PEPPER");
dialog.setView(editText);
dialog.setButton(DialogInterface.BUTTON_POSITIVE, "SAVE", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
bpTextView.setText(editText.getText());
}
});
bpTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
editText.setText(bpTextView.getText());
dialog.show();
}
});
}
}
By window, I assume you Activity (the AppCompatActivity that you have created). To maintain state in Activities you have to learn about the activity lifecycle. Basically when you leave you have to save the instance state:
// invoked when the activity may be temporarily destroyed, save the instance state here
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(TEXT_VIEW_KEY, editText.getText());
// call superclass to save any view hierarchy
super.onSaveInstanceState(outState);
}
and when you restore the state you do the same:
// This callback is called only when there is a saved instance previously saved using
// onSaveInstanceState(). We restore some state in onCreate() while we can optionally restore
// other state here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
editText.setText(savedInstanceState.getString(TEXT_VIEW_KEY));
}
Obviously you have to create a TEXT_VIEW_KEY as private final string at the top of your class:
private static final String TEXT_VIEW_KEY = "TEXT_VIEW_KEY";
Untested, but that should work for you now. For more advanced lifecycle handling learn about the Android Architecture Components, but that should wait until you understand the basic activity lifecycle in android App.
Before referring me to other threads on this forum and marking my question as duplicate kindly read my question. I have to create a global application timeout. No matter which activity is user on, after specific amount of time the user will be displayed AlertDialog that his session has expired and he can exit or renew his session. I have read different solutions and used service as my solution.
public class InActivityTimer extends Service {
MyCounter timer;
#Override
public void onCreate() {
timer = new MyCounter(20 * 1000,1000);
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
timer.start();
return super.onStartCommand(intent, flags, startId);
}
private class MyCounter extends CountDownTimer{
public MyCounter(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
Intent intent = new Intent("timeout_action");
sendBroadcast(intent);
stopSelf();
}
#Override
public void onTick(long millisUntilFinished) {
// Need AlertDialog code here
Toast.makeText(getApplicationContext(), ("Time Remaining: " + millisUntilFinished/1000)+"", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onDestroy() {
timer.cancel();
super.onDestroy();
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
The problem is that I can display the Toast without any problem but the AlertDialog is not displayed when called inside onFinish().
The first problem is to display the AlertDialog for whole application bearing in mind that the AlertDialog is displayed for some context. Also if somehow the AlertDialog is displayed then how to close the Application. On Activity I just close the activity by calling finish() so should I clear the Activities stack in this case?
The second complex part that I am facing is to display a popup when user click "Time remaining" link in the application which will show how much time is remaining for the Session to be timed out. This time should be exactly same as the time remaining in the service.
I can also use BroadcastReceiver and send update to the activity once the time is finished but wouldn't that be Activity specific because I want the timeout to act same regardless of which activity is user on. I want to avoid writing the same code on each activity.
Kindly guide me through with some solution.
If you use a fragment based design for your app, you can keep a root FragmentActivity in which all other elements of the app are displayed. This way you can use the context of the root FragmentActivity every time, to display your Dialog.
Additional: "Could you kindly refer to me some article.."
What you are doing is not common, and I would have to google search just like you to find any existing example similar to your case. I can however fill in a bit more detail on what I have proposed above.
If you are unfamiliar with using Fragments, read the Developer Documentation.
public class MainActivity extends FragmentActivity {
private static final int SPLASH_SCREEN_FRAGMENT = 0;
private static final int HOME_SCREEN_FRAGMENT = 1;
...
#Override
protected void onCreate(Bundle. savedInstanceState) {
super.onCreate(savedInstanceState);
// show your first fragment
Fragment splashFragment = new SplashFragment();
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, splashFragment).commit();
// Start your service using the context of your FragmentActivity
// Your FragmentActivity will always be the current activity, and you will display
// all other elements of your app inside it as fragments
Intent intent = new Intent(this, InActivityTimer.class);
startService(intent);
}
// method for switching the displayed fragment
private void fragmentSwitcher(int fragmentType) {
Fragment currentFragment = new Fragment();
switch (currentFragmentType) {
case SPLASH_SCREEN_FRAGMENT:
currentFragment = new SplashScreenFragment();
break;
case HOME_SCREEN_FRAGMENT:
currentFragment = new HomeScreenFragment();
break;
...
}
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, currentFragment).commit();
}
}
I have solved my issue with rather very simple approach.
#Override
public void onFinish() {
Intent intent = new Intent(getBaseContext(), TimeoutActivity.class);
startActivity(intent);
stopSelf();
}
and below is the onCreate method for my TimeoutActivity.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ContextThemeWrapper ctw = new ContextThemeWrapper(TimeoutDialogActivity.this, R.style.Theme_Base_AppCompat_Dialog_FixedSize);
final AlertDialog alertDialog = new AlertDialog.Builder(ctw).create();
alertDialog.setCancelable(false);
alertDialog.setTitle("Session Timeout !");
alertDialog.setTitle("Your session has expired.");
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Logout", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
finish();
}
});
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Exit", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
finish();
}
});
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Renew Session", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
finish();
});
alertDialog.show();
}
I am trying to release heap size by destroying the current activity, while going to another activity.
I am using finish(); on backPreess()
But this is not releasing the heap.
on setContentView()
The heap size increases 16Mb. I want to release this increase in the heap after going to another activity. Can any one help how to do this?
My code is as following:
package com.stancil.levels;
public class PaintActivity extends ZebraActivity implements
PaintView.LifecycleListener, PaintView1.LifecycleListener1 {
private static final int REQUEST_PICK_COLOR = 1;
....
....
public PaintActivity() {
_state = new State();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Constants.context = getApplicationContext();
setContentView(R.layout.paint);
..................
...................
...............
}
public void onPreparedToLoad() {
// We need to invoke InitPaintView in a callback otherwise
// the visibility changes do not seem to be effective.
new Handler() {
#Override
public void handleMessage(Message m) {
new InitPaintView();
Log.v("PaintActivity", "After InitPaintView Called");
}
}.sendEmptyMessage(0);
}
private class InitPaintView implements Runnable {
private Bitmap _originalOutlineBitmap;
private Handler _handler;
public InitPaintView() {
// Make the progress bar visible and hide the view
_paintView.setVisibility(View.GONE);
_progressBar.setProgress(0);
_progressBar.setVisibility(View.VISIBLE);
_state._savedImageUri = null;
_state._loadInProgress = true;
_originalOutlineBitmap=_imageBitmap;
_handler = new Handler() {
#Override
public void handleMessage(Message m) {
switch (m.what) {
case Progress.MESSAGE_INCREMENT_PROGRESS:
// Update progress bar.
_progressBar.incrementProgressBy(m.arg1);
break;
case Progress.MESSAGE_DONE_OK:
case Progress.MESSAGE_DONE_ERROR:
// We are done, hide the progress bar
// the paint view back on.
_state._loadInProgress = false;
_paintView.setVisibility(View.VISIBLE);
_progressBar.setVisibility(View.GONE);
initiatePopupWindow();
break;
}
}
};
new Thread(this).start();
}
public void run() {
Log.v("Wasimmmmmmmmmmmmmmmm", "qqqqq 22");
_paintView.loadFromBitmap(_originalOutlineBitmap, _handler);
}
}
private static class State {
// Are we just loading a new outline?
public boolean _loadInProgress;
// The resource ID of the outline we are coloring.
//public int _loadedResourceId;
//
// If we have already saved a copy of the image, we store the URI here
// so that we can delete the previous version when saved again.
public Uri _savedImageUri;
}
#Override
public void onBackPressed() {
new AlertDialog.Builder(this)
.setTitle("Exit")
.setMessage("Do you want to go to Main Menu?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Constants.check_new=true;
Intent i=new Intent(PaintActivity.this,MainActivity.class);
// i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Do nothing.
}
}).show();
}
}
}
release yoru objects in onDestroy method, anyways, if there are no references to the detroyed activity, GC will automaticly clean up whenever its needed (it doesnt need to happen right after you closed your activity).
Alternatively theres a method to force running GC, but I wont even write about it cuz its not really a feature a typical application should use
I have a bit of usual problem here. I have a alertdialog that launches as soon as my application has been launched and as soon as the user clicks the ok button that dialog will never display again unless it has been deleted and installed again. It works when I try it on my emulator for the first time and by first time I mean when I launch the application as soon I am done writing the code for the shared preference for the alertdialog. But when I close the emulator and launch my application again, the alertdialog doesn't display and my application doesn't respond to anything. I do not know if this happened to anybody before and I do not know if this was suppose to happen. Can somebody help me understand what is going and why application doesn't respond to anything after the first time the application has been launched. Also my logcat did not display any errors either.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final SharedPreferences settings = getSharedPreferences("pref_name", 0);
boolean installed = settings.getBoolean("installed", false);
if(!installed){
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle("Title");
alertDialog.setIcon(R.drawable.ic_launcher);
alertDialog.setAdapter(new MyAdapter(), null);
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("installed", true);
editor.commit();
}
});
alertDialog.show();
final EditText et = (EditText) findViewById(R.id.editText1);
Button getAnswer = (Button) findViewById(R.id.button1);
getAnswer.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (et.getText().toString().length()==0) {
Toast.makeText(getApplicationContext(),"Can't Be Blank!",Toast.LENGTH_LONG).show();
}else{
EditText et = (EditText) findViewById(R.id.editText1);
String searchTerm = et.getText().toString().trim();
Intent in = new Intent(MainActivity.this, ListView.class);
in.putExtra("TAG_SEARCH", searchTerm);
startActivity(in);
}
}
});
}
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
}}
You need to move this code
final EditText et = (EditText) findViewById(R.id.editText1);
Button getAnswer = (Button) findViewById(R.id.button1);
getAnswer.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (et.getText().toString().length()==0) {
Toast.makeText(getApplicationContext(),"Can't Be Blank!",Toast.LENGTH_LONG).show();
}else{
EditText et = (EditText) findViewById(R.id.editText1);
String searchTerm = et.getText().toString().trim();
Intent in = new Intent(MainActivity.this, ListView.class);
in.putExtra("TAG_SEARCH", searchTerm);
startActivity(in);
}
}
});
}
out of the if part of your code. As Shobhit is saying, this is never getting run the next time you run your app. It only runs if installed is false which is never true after the first run.
Edit-Avoid window leak errors with the Dialog
You can always check if the Dialog is open with dialog.isShowing() and close the Dialog if returns true before the Activity is destroyed or something (another Activity) comes on top. You can do this in onPause().
#Override
public void onPause()
{
if (dialog != null && dialog.isShowing())
{
dialog.dismiss();
super.onPause();
}
}
Move this code into an AsyncTask. It's not good practice to do any work in the onCreate(). The OnCreate() is only for creating the Activity. Start your AsyncTask in the OnResume() Look at this activity-life-cycle Here is the AsyncTask
final SharedPreferences settings = getSharedPreferences("pref_name", 0);
boolean installed = settings.getBoolean("installed", false);
if(!installed){
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle("Title");
alertDialog.setIcon(R.drawable.ic_launcher);
alertDialog.setAdapter(new MyAdapter(), null);
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("installed", true);
editor.commit();
}
});
alertDialog.show();
What you have is as follows:
if(!installed){
// Show dialog
// Else Everything inside it
}
When your app starts first time, it goes inside loop and shows the dialog. Next time when you restart, the value the SharedPreference is true, so it does not go inside the loop and nothing happen. On restarting the phone/emulator ShraredPreference does not delete, so is still true and does not go inside the loop, so nothing happens.
If you do the indentation of your program clearly, then it might be visible in bettr way.
The dialog:
public class ClearDialog extends Dialog {
private MainActivity context;
public ClearDialog(MainActivity context) {
super(context);
this.context = context;
setContentView(R.layout.clear_dialog);
setTitle("something");
setCanceledOnTouchOutside(false);
setCancelable(true);
}
/* not overriding anymore
#Override
public void onBackPressed() {
return;
}
still doesnt work */
#Override
protected void onStart() {
super.onStart();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.clear();
editor.commit();
ResourceHelpers.removeAllResources();
context.onResourcesDeleted();
}
}
The Activity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.itemLogoff:
loginDialog.show(); //this is another dialog
break;
case R.id.itemSync:
Intent syncer = new Intent(MainActivity.this, SyncActivity.class);
MainActivity.this.startActivity(syncer);
break;
case R.id.itemClear:
new AlertDialog.Builder(this)
.setIcon(R.drawable.ic_action_alert)
.setTitle("something")
.setMessage("something")
.setPositiveButton("something", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
showDeleteDialog();
}
})
.setNegativeButton("something", null)
.show();
break;
}
return true;
}
private void showDeleteDialog() {
cd = new ClearDialog(this); //this is the dialog
cd.show();
}
public void onResourcesDeleted() {
cd.dismiss();
loginDialog.show();
}
So.. The user clicks on "Delete all data" from the ActionBar (optionsmenu). I open an AlertDialog asking if he's sure. Then if he's sure, I open a dialog that shows a spinning ProgressBar.
The problem: it won't dismiss!
The loginDialog (all data is lost so I want the user to login again...) comes up in the background. The ClearDialog won't dismiss...
I think that the problem is here (don't override in this way that method):
#Override
public void onBackPressed() {
return;
}
You can already obtain a modal dialog with .setCancelable(false)
Please take a loog at this documentation: http://developer.android.com/guide/topics/ui/dialogs.html#AlertDialog
Give the following property for dialogue
.setCancelable(true);
its just like .setTitle() or .setMessage in your code....
On top of StErMi's answer, which you should follow, also switch the two lines in your onResourcesDeleted() method. The login dialog is called, and takes over before your dismiss is called.
public void onResourcesDeleted() {
cd.dismiss();
loginDialog.show();
}