What will happen if I call startActivityForResult() recursively? - android

I intend to show four welcome screens to the user that only appear once for new users. To do so, I save a flag in the Preferences at start up and check its value to determine if the user is new or not. If not, then the welcome screens do not appear:
SharedPreferences mPrefs;
final String welcomePref = "oldUser";
#Override
public void onCreate(Bundle savedInstanceState) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
Boolean welcome = mPrefs.getBoolean(welcomePref, false);
if (!welcome) {
Intent intent = new Intent(this, welcomeScreenOne.class);
startActivity(intent); //start the first welcome screen
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean(welcomePref, true); //not a new user anymore
editor.commit();
}
}
The welcomeScreenOne activity starts the second welcome screen and so on.
As you may have noticed, the error in this code is that if the user views the first welcome screen, the pref is set to true and so if he exits the application before looking at the other welcome screen (2, 3 and 4) then returning to the app will not display the remaining screens.
To solve this I thought of using startActivityForResult(Intent, int) inside each welcome screen activity so that the 4th returns to the 3rd, which returns to the 2nd which returns to the 1st welcome screen, then setting the pref to true. Is this bad coding practice?
My second solution is calling the 1st screen from the main, returning then calling the 2nd, returning then calling the 3rd and so on.
Maybe there is a way I do not know of, please advise?

Is this bad coding practice?
IMHO, yes.
Maybe there is a way I do not know of, please advise?
Have one activity, not four.
Use something else inside this one activity for your sequence of welcome screens, such as:
Four fragments, showing one at a time
Four views, showing one at a time
An existing library for such welcome screens, such as these wizards or these "showcase views"

It's possible for you to add a splashActivity to your app? if so, you can check on that activity if the user is new or not, and if is new, show the welcome screen and if not, send it to your mainActivity (or the activity you need).

It depends on the activity mode you are launching the activity if you will use launch mode Single Instance than the same activity will get reopened again and again ,if the default mode will be there every time a new instance will be created and there will be activities piled up in the stack which can create unknown results

Related

Android - how to display an activity just for 1 time?

I'd like to make a welcome screen just for 1 time. It should not be a splash screen because I'd put a TextEdit and a button to get the user's username. I need to see some examples of the code that would do it, thanks for stopping by! :D
1. First let the user insert his Username in the TextView.
2. When the user press the Button, then do the following...
- Use Intent to move to the next Activity you want to divert him after this Staring Activiy.
Eg:
Intent i = new Intent(StartActivity.this, DesiredActivity.class);
- Now after you use startActivity() method with Intent as the argument, do use finish() method, that will remove this StartActivity from the Back-Stack.
Eg:
Intent i = new Intent(StartActivity.this, DesiredActivity.class);
startActivity(i);
finish();
Now if the user press back button from the DesiredActivity( the one you went from StartActivity), the app will exit.
////////////Edited Part/////////////////
You don't want you app not to go to the First activity again, where you have already given the username.. After the first time..right ??????
- Then to do this... i will recommend you to do the below....
i. First save the username that user inputs the first time into Shared Preference or into a file, or a Database.
ii. Now when you open you app, let there be a thread which checks the existence of the username in the Shared Preference or in a file, or a Database, resp wherever u have saved it.
iii. If found let it move to the desired activity, if not prompt him to input the username, thats what happen the 1st time you open your app.
iv. Now its also about user-friendliness, so i recommend you to use a splash activity in the beginning, and fire your checking thread from here. So the user wont feel awkward looking at the blank screen while the thread checks the username
Start the activity. In OnCreate, check if the Activity already has been shown. If yes, start the next activity, if not, save that you are showing the activity now.
you can create a Activity in onCreate method check if user already enter UserName, if Yes start Another Activity immediately or show user Activity to enter user name.
Hope you are storing user name somewhere to check it if it is present or not
Have a starting activity that will decide if the next activity that should be opened is the once-off welcome screen or the other part of your app.
In the first activity:
To know if the screen has been opened before, you'll have to save a boolean value to the phone's memory:
If the read boolean value is false (screen has not been opened before), show the once-off screen.
Else the screen has been opened before and that's why you'll advance to the other part of the app.
To save boolean value:
public void writePrimitiveInternalMemory(String filename, boolean value) {
SharedPreferences preferences = game.getPreferences(Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean(filename, value);
editor.commit();
}
To read boolean value:
public boolean readPrimitiveInternalMemoryBoolean(String filename) {
SharedPreferences preferences = game.getPreferences(Activity.MODE_PRIVATE);
return preferences.getBoolean(filename, false);
}
I hope this helps.

Android - Disclaimer popping up after every intent

Just a bit about my app first. Its a quiz app. It has a main screen displaying a question, which loads straight away, and arrows going previous and next which go to other quiz questions. I'm using the same layout over and over, just by passing different question data, so when I click the "next" button, it will just launch an intent to the same class, just with different data. At the start of my one single layout, I have a little check to see if the user has clicked to hide the disclaimer or not.
So my disclaimer pops up at the start of the app. It has a dismiss button and a Dont show this again checkbox. I can get the checkbox working perfect, using SharedPreferences but the problem arises when they hit the Dismiss button. Since I'm reusing the same layout, any time the user navigates to a new question, the disclaimer pops up. I only want it to popup on the first screen, e.g. when the app loads.
I have tried setting another SharedPreference to hide the disclaimer when the user hits dismiss but once I hide it, it never comes back, because when the user loads the app back up again, that shared preference is still set. My problem is knowing where to set the preference back! I tried resetting it in onPause() but that didn't work.
So, what I'm asking is, how can I determine if an activity is the first one to be loaded so I can only do the Disclaimer check then, and not in each of the subsequent screens?
Thanks.
EDIT: Here's my OnCreate() method:
final static String disclaimerShownPref = "disclaimerShown";
final static String disclaimerShownOnce = "disclaimerShownThisSession";
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
//Checks to see if the boolean is set
//The second argument is the default to use if the preference can't be found
if(!mPrefs.getBoolean(disclaimerShownPref, false))
{
if(!mPrefs.getBoolean(disclaimerShownOnce, true))
{
new Disclaimer(this);
}
}
topMostLayout=buildHomeScreen();
setContentView(topMostLayout);
}
In your case I would suggest using a static variable in your activity:
private static boolean sFirstTime = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if( sFirstTime )
{
/*
* Place the disclaimer check here
*/
sFirstTime = false;
}
else
{
}
Having said that. I would consider a better approach to switch between questions in the same instance of your activity instead of creating a new one every time.
Good luck!
Instead of restarting the activity each time the user navigates between questions, you should just write a function that will repopulate the views with the new question data when previous or next are clicked. As for the disclaimer, if you want it to show up every time the app is started, then setting the variable using shared preferences is not the best way to go about it. The shared preferences are not deleted when the app closes, they are only deleted if you erase them manually or uninstall the application altogether. Instead create a variable in your activity that tracks whether or not "Dismiss" was clicked. As long as the app is running the dialog will not be displayed, but when the app is restarted all the variables including the one that keeps track of displaying the dialog will be reset and it will show up again.
Instead of using an Intent to launch a new version of your activity, why not just use an onClickListener to call setText() and change the display question? This might make the Activity lifecycle more intuitive and probably simplify your code.

Using Primitive Data Types in another Class and the res/menu/.xml file

I'm a very new to Java. I thought I was doing okay but have now hit a brick wall, so to speak.
The idea is I use the 'home button' '_menu' for the user to choose one of 26 formats. The format they choose has 3 variables. Those 3 variables are then used in the first xml view, along with 2 user inputs to calulate another variable. This variable is then used in a second xml view, along with a third user input here, to calculate the final answer.
I have created the 26 choices and if for example I choose option 5, on the emulator screen I see all the correct values associated with this choice. I don't think those values are getting stored anywhere. I say this because if I come out of that view and return back into it, it's not showing, as in my example, choice 5. It's showing its initial state, as though I was going into it the first time. I assume it's something to do with launching this activity from the start but is there anyway around this. Or really where do I start.
My second question is with the integer variables that I created from this choice. I need to pass them into another java file for the first set of calculations. I've tried to pass the variables/data with the, 'new intent putExtra' but can't get it to work. But I don't think I can use this anyway since the I don't want to launch the second view directly from the res/menu/ .xml view.
Not sure if this is making sense to anyone. Can someone help point me in the right direction?
I don't quite understand your first question, but it sounds like you're launching a new activity and when you quit and come back to it, everything is reset. If you're launching a new activity after selecting the options from your phone's menu button, you should implement a method that saves data to the shared preferences of the main activity. This method should be called on the activities onPause(), onDestroyed(), or onStop() method. You can also add a method on onResume() where the activity checks if there's any data stored in shared preferences and if so, make the desired changes.
As for your second question...I kinda don't understand it either. new intent and putextra is used when you're starting a new activity and want to pass data to it. Views are not "launched" they are only inflated and brought on display whenever you want. I did an app once where I had everything in one activity and just using setContentView() method all the time. In the long run, it just complicated everything. It is easier to keep things simple and launch activities. Here is an example of some variables being passed to a new activity:
On my main activity (FirstActivity) I have:
(when newActivityButton is clicked)
case R.id.newActivityButton:
Intent mIntent = new Intent(FirstActivity.this,SecondActivity.class);
String[] luckyNumbers = {
luckyNumber[0].getText().toString(),
luckyNumber[1].getText().toString(),
luckyNumber[2].getText().toString(),
luckyNumber[3].getText().toString(),
luckyNumber[4].getText().toString(),
luckyNumber[5].getText().toString()};
mIntent.putExtra("luckyNumbers", luckyNumbers);
mIntent.putExtra("message", messageField.getText().toString());
FirstActivity.this.startActivity(mIntent);
break;
luckyNumbers[] is an array of textviews.
Then on my NewActivity onCreate(), I have:
message = getIntent().getExtras().getString("message");
Log.i("TAG", message);
luckyNumbers = getIntent().getExtras().getStringArray("luckyNumbers");
cv.setLuckyNumbers(this.luckyNumbers);
cv.setMessage(this.message);
where cv is just a custom view I created with its own methods

How can my Android app open with one of two views, based on a condition?

This is my very first post on StackOverflow.
Basically, my app starts by checking to see if a user record exists in my Sqlite Database. If yes, I would like it to display my main application screen. If not, I would like another screen to be displayed, prompting the user for a password.
This password screen is a new addition to my app. It originally just displayed the main screen like so:
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Then I would run the check for a user. If no user is found I display the password screen like so:
Intent myIntent = new Intent(this, loginScreenActivity.class);
startActivityForResult(myIntent, 0);
The problem is, if I decide to hit the BACK button to exit out of the application from the password screen, it goes back to the main screen.
How can I first run the check, then display one of the two views??
Hope this makes sense.
Thanks in advance.
When you navigate to the login screen, call finish() on the first screen
read the Activity documentation, it will be very helpful.
You need to set the FLAG_ACTIVITY_CLEAR_TOP if you never wan1t go back to this screen.
Or the secont one, override the onbackpressed() method and use finish() method inside in.

Android: Different start activity depending on user preference

My application starts with a welcome screen Activity, but that screen has an option to skip that screen altogether in future launches.
What's the proper Android way to do this? Initially, I just automatically detected the skipWelcome preference and switched to the 2nd activity from Welcome. But this had the effect of allowing the user to hit the back button to the welcome screen we promised never to show again.
Right now, in the Welcome activity, I read the preference and call finish() on the current activity:
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
boolean skipWelcome = preferences.getBoolean("skipWelcome", false);
if (skipWelcome) {
this.finish();
}
And then I implement onDestroy to move on to the next Activity:
#Override
public void onDestroy() {
super.onDestroy();
startActivity(new Intent(Welcome.this, StartFoo.class));
}
But this makes for some weird visual transitions. I'm starting to think that I need a base Activity that pops open Welcome only if proper, and then goes to StartFoo.
I can't comment on Mayra's answer or I would (not enough rep), but that's the correct approach.
Hidden in the Android documentation is this important phrase for Activity.startActivityForResult(),
"As a special case, if you call
startActivityForResult() with a
requestCode >= 0 during the initial
onCreate(Bundle
savedInstanceState)/onResume() of your
activity, then your window will not be
displayed until a result is returned
back from the started activity. This
is to avoid visible flickering when
redirecting to another activity."
Another important note is that this call does not block and execution continues, so you need to stop execution of the onCreate by returning
if (skipWelcome) {
// Create intent
// Launch intent with startActivityForResult()
return;
}
The final piece is to call finish immediately in the welcome activity's onActivityResult as Mayra says.
There are a few solutions to this.
Did you try just launching the activity and finishing? I vauguely remember that working, but I could be wrong.
More correctly, in if(skipWelcome) you can start the new activity for result, then when onActivityResult is called, immidiately finish the welcome activity.
Or, you can have your launcher activity not have a view (don't set content), and launch either the welcome activity or StartFoo.

Categories

Resources