I have my code below on the onCreate of my Activity.
SharedPreferences globalPreferences = getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
boolean hasFinishedIntroduction = globalPreferences.getBoolean(PREF_FINISHED_INTRO), false);
Log.d(TAG, "Has finished introduction: " + hasFinishedIntroduction);
if(!hasFinishedIntroduction){
startActivity(new Intent(this, IntroductionActivity.class));
finish();
}
boolean hasLoggedInUsingFacebook = globalPreferences.getBoolean(PREF_LOGGED_IN_FACEBOOK), false);
boolean hasLoggedInUsingGoogle = globalPreferences.getBoolean(PREF_LOGGED_IN_GOOGLE), false);
Log.d(TAG, "Has logged in using Facebook: " + hasLoggedInUsingFacebook);
Log.d(TAG, "Has logged in using Google: " + hasLoggedInUsingGoogle);
if(!hasLoggedInUsingFacebook && !hasLoggedInUsingGoogle){
startActivity(new Intent(this, SocialLoginActivity.class));
finish();
}
My problem is that, every time I run my app (clean install), my app starts my SocialLoginActivity that is supposed to be checked second. My first check was ignored (hasFinishedIntroduction).
Of course I tried debugging it with Log messages but all works fine (the values at least).
10-06 03:15:09.907 12969-12969/com.sample.foo D/Bar: Has finished introduction: false
10-06 03:15:09.937 12969-12969/com.sample.foo D/Bar: Has logged in using Facebook: false
10-06 03:15:09.937 12969-12969/com.sample.foo D/Bar: Has logged in using Google: false
Clearly, the app can read the false in the hasFinishedIntroduction but it ignores it and refuses to execute what's inside my first if statement.
What's surprising is that after I log in on my app, the user will be brought back to this Activity and then now, my check of hasFinishedIntroduction's value will be executed and will start the Activity I instructed it to start.
Thank you for your help.
EDIT
I forgot to note here that I have also put some Log.d()s in the onCreate of my IntroductionActivity and SocialLoginActivity but it really shows that it doesn't really call IntroductionActivity at all.
I think u need to return from the method in the hasFinishedIntroduction block because the code after the block is getting executed and SociaLoginActivity is being launched on top of the IntroductionActivity.
try this:
if(!hasFinishedIntroduction){
startActivity(new Intent(this, IntroductionActivity.class));
finish();
return;
}
Related
I have a small app that i have been working on. I wanted a fresh install to run from on my Galaxy Nexus rooted running 4.2.1. I uninstalled the app, then tried to reinstall it via eclipse. It installs fine, no errors in logcat, console ect... but when you click to run the app, it just closes right on opening. I have tried this on 2 different phones, same thing.
On the Galaxy Nexus, if I restore my ROM back before I uninstalled, I can run it from eclipse all I want. It's only after uninstall and reinstall that I get the force close. It is installed on the ROM backup.
Any ideas?! How can I find out what is going on here?
EDIT:::
Activity is only declared once in manifest...
Tried changing the version number... no effect
added some Log.e() to the MainActivity:
protected void onCreate(Bundle savedInstanceState) {
Log.e(TAG,"STARTING APP");
super.onCreate(savedInstanceState);
// show no back arrow
Log.e(TAG,"AFTER ONCREATE");
setContentView(R.layout.activity_firstload);
Log.e(TAG,"AFTER SETCONTENTVIEW");
getPrefs();
Log.e(TAG,"GET PREFS");
finish();
Log.e(TAG,"AFTER FINISH");
}
The only tag that shows in the LogCat is "AFTER FINISH"
If I get rid of finish, the MainActivity stays open. All that main activity does is check for Preferences. Here is my GetPrefs()
private void getPrefs() {
// Get the xml/preferences.xml preferences
Log.e(TAG,"GET PREFS 1");
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
lp = prefs.getString("defaultreport", "");
Log.v(TAG, lp);
if (lp.equals("esac")) {
// Toast.makeText(MainActivity.this, "ESAC", Toast.LENGTH_SHORT)
// .show();
Intent i = new Intent(MainActivity.this, ESACActivity.class);
startActivity(i);
} else if (lp.equals("sac")) {
// Toast.makeText(MainActivity.this, "SAC", Toast.LENGTH_SHORT)
// .show();
Intent i = new Intent(MainActivity.this, SACActivity.class);
startActivity(i);
} else if (lp.equals("msar")) {
// Toast.makeText(MainActivity.this, "MSAR", Toast.LENGTH_SHORT)
// .show();
Intent i = new Intent(MainActivity.this, MSARActivity.class);
startActivity(i);
}
}
AH>>> May have found something. The preferences initially are set to "" (null) so what would it load?! So I need a screen asking which they'd like to set on FIRST RUN I guess...
EDIT EDIT::: Needed to check for first run in Prefs...
if (prefs.getString("defaultreport", null) == null)
{
startActivity(new Intent(this, Preferences.class));
return;
}
Your string that decides what to run is set to nothing if there is no preference.
lp = prefs.getString("defaultreport", "");
And since you have no option for that case nothing will run and the initial activity will close without starting any other.
I have inAppBilling working but i'm trying to refine it a little bit. I noticed that when I try in app billing in Angry Birds it opens directly on top of the application but my application pulls in app billing to the foreground/desktop. I read the docs and it states that singleTop must be off and reflection must be used as well with an activity context given and NOT an application context. I have verified that I have all of those things done but its still pulling to the foreground. Any ideas?
My verification:
I have an activity called MyActivity
Log.d("TEST", mContext.getClass().getName());
responds back with MyActivity
and in Android Manifest for MyActivity
android:launchMode="standard"
EDIT:
The code that starts the checkout activity
void startBuyPageActivity(PendingIntent pendingIntent, Intent intent) {
if (mStartIntentSender != null) {
// This is on Android 2.0 and beyond. The in-app buy page activity
// must be on the activity stack of the application.
try {
// This implements the method call:
// mActivity.startIntentSender(pendingIntent.getIntentSender(),
// intent, 0, 0, 0);
mStartIntentSenderArgs[0] = pendingIntent.getIntentSender();
mStartIntentSenderArgs[1] = intent;
mStartIntentSenderArgs[2] = Integer.valueOf(0);
mStartIntentSenderArgs[3] = Integer.valueOf(0);
mStartIntentSenderArgs[4] = Integer.valueOf(0);
mStartIntentSender.invoke(mActivity, mStartIntentSenderArgs);
Log.d("TAG", mActivity.getClass().getName());
} catch (Exception e) {
Log.e(TAG, "error starting activity", e);
}
} else {
// This is on Android version 1.6. The in-app buy page activity must be on its
// own separate activity stack instead of on the activity stack of
// the application.
try {
pendingIntent.send(mActivity, 0 /* code */, intent);
} catch (CanceledException e) {
Log.e(TAG, "error starting activity", e);
}
}
}
What I am trying to accomplish is for the in app billing prompt whether it finishes the transaction or cancels to resume back to my game instead of simply closing and finishing. A current fix I have is to start the games Activity again which would result in reloading everything and putting the player back at the main menu page.
In my application I have used some code from the iosched 2012 app. In specific the starting workflow is the following:
1.The user presses the launcher icon of the app
2.HomeActivity checks if the user is authenticated. If he/she is not, it starts the Authentication activity, passing it intent to it and finishes itself
3.When the login process is successful, the authenction activity starts an activity in order to start the HomeActivity and finishes itself
4.HomeActivity checks again if the user is authenticated and displays the home screen of the application.
The following code works like a charm in API Level > 11. Today, I tried the app in a Gingerbread and it fails. Step 3 works, but although the HomeActivity starts it's not brought to front. You have to use the recent list and choose the application in order to see the homeactivity and its now displayed content.
Here's the code and check from the HomeActivity in the oncCreate method
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!AccountUtils.isSystemAuthenticated(this)) {
AccountUtils.startSystemAuthentication(this, getIntent());
finish();
} else if(!AccountUtils.isAppAuthenticated(this)) {
AccountUtils.startAppAuthentication(this, getIntent());
finish();
}
if(isFinishing()) {
return;
}
setContentView(R.layout.activity_main);
...
}
}
The method invoked in the Authentication activity after the login process is completed
protected void handleLoginSuccess(LoginServiceResponse response, String username, String password) {
if(....) {
if(mFinishIntent != null) {
mFinishIntent.addCategory(Intent.CATEGORY_LAUNCHER);
mFinishIntent.setAction(Intent.ACTION_MAIN);
mFinishIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mFinishIntent);
}
finish();
} else {
super.handleLoginSuccess(response, username, password);
}
}
Where the mFinishIntent member variable is the intent passed from the HomeActivity (using getIntent())
As I mentioned, in API Level > 11, this works well, and the breakpoint in HomeActivity's onCreted method is hit twice, while in a Gingerbread phone, is hit only once (only when the application starts).
Do I have to use another flag or do you have any other idea of what's going on?
Thanks
What is probably happening is that the activity is only created when the app is started and then when you go back to it from the Authentication activity, it is simply resumed. Try putting the authentication checking code in HomeActivity in the onResume() method.
Here is some more info: http://developer.android.com/reference/android/app/Activity.html#ProcessLifecycle
I have a strange scenario here.
I have this code:
// For checking if the person is logged in.
first_time_check();
setContentView(R.layout.main);
// ...next lines of code
and the first_time_check() function checks if the user is logged in for the first time. If their user_id is not in the SharedPreferences, I redirect them to log in:
public void first_time_check()
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( ProblemioActivity.this);
String user_id = prefs.getString( "user_id", null ); // First arg is name and second is if not found.
String first_time_cookie = prefs.getString( "first_time_cookie" , null );
// About setting cookie. Check for first time cookie
if ( first_time_cookie == null )
{
// This user is a first-time visitor, 1) Create a cookie for them
first_time_cookie = "1";
// 2) Set it in the application session.
prefs.edit().putString("first_time_cookie", first_time_cookie ).commit();
// Make a remote call to the database to increment downloads number
// AND send me an email that it was a new user.
}
else
{
// If not first time, get their id.
// If user_id is empty, make them an account.
// If id not empty, call the update login date and be done.
if ( user_id == null )
{
// User id is null so they must have logged out.
Intent myIntent = new Intent(ProblemioActivity.this, LoginActivity.class);
ProblemioActivity.this.startActivity(myIntent);
}
else
{
// Make a remote call to the database to increment downloads number
}
}
return;
}
So after the code executes the
Intent myIntent = new Intent(ProblemioActivity.this, LoginActivity.class);
ProblemioActivity.this.startActivity(myIntent);
it still executes below the original code that calls this functions.
Any idea how that can happen?
Thanks!!
This is excerpted from the Dev Guide
Shutting Down an Activity
You can shut down an activity by calling its finish() method.
You can also shut down a separate activity that you previously
started by calling finishActivity().
Note: In most cases, you should not explicitly finish an activity
using these methods. As discussed in the following section about the
activity lifecycle, the Android system manages the life of an
activity for you, so you do not need to finish your own activities.
Calling these methods could adversely affect the expected user
experience and should only be used when you absolutely do not want
the user to return to this instance of the activity.
Calling finish() on the activity seems appropriate here as you do not want the user to return to this activity.
Okay, check this source code:
public void checkSession() {
SharedPreferences session = getSharedPreferences(PREFS_NAME, 1);
String getSession = session.getString("SESSION", null);
Toast.makeText(this, getSession, Toast.LENGTH_SHORT).show();
if(getSession.length() > 30) {
Intent menu = new Intent(this, menu.class);
startActivity(menu);
finish();
}
else
{
}
}
The problem is that "first time users" get crush.
When I disable the function, run the app and login the code creates session. After that when I logout, and restart the app - there's no problem. Any ideas?
First time the app runs and you don't have a value stored in the SharedPreference "SESSION" you return null as your default value. The getSession().length will then result in a NullPointerException.
You should do like this instead:
String getSession = session.getString("SESSION", "");
If getSession is null, I think Toast.makeText will fall over.* You might want to change the default return to "" from null. getSession.length() won't work if getSession is null either.
*Apparently that isn't true -- see TofferJ's comment.