I'm having a very weird situation in my app. I have an activity, on which I have log in button. On button click I'm checking whether user is logged in or not, and simultaneously showing proper message. My code looks like this:
#Override
public void onClick(View v) {
if (loginUserId == null || loginAccessToken == null) {
Intent intent = new Intent();
intent.setClassName("com.example.poc",
"com.example.poc.LoginPromptDialog");
startActivity(intent);
} else {
System.out.println("Else condition here!");
}
}
On else condition I'm printing on the log.
In my case take a scenario that user is not logged in, then Login Prompt Activity will be shown. I have a skip button on my Second Activity, on that button I'm just calling finish() method. And I'm coming back from Second Activity to First Activity. This is confirmed that my onResume() method is called when coming back from Second Activtiy.
Still user is not logged in and when I click again button on the First Activity my else condition is called. Why again my if condition is not called?
I can't figure out why this is happening.
Any kind of help will be appreciated.
I was getting "" values from the other activity. Thanks to the comments I got. Solved.
Related
I would like to start an activity only if the string I pass with putExtra from another activity equals 'search' like so:
action = intent.getStringExtra("cause");
Button btnBack = findViewById(R.id.btnBack);
btnBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(action == "search") {
Intent intent2 = new Intent(profiloutente.this, ricerca.class);
startActivity(intent2);
}
}
});
But, the condition always seems to be false (so the activity doesn't start) even if the variable containing the get Extra equals "search". I don't understand why this happens. Could someone help me?
The obvious probklem is that you are using == on a String. How do I compare strings in Java?
Another problem is that action is read outside of listener. That may be the intent, but I can't tell in isolation - if it is the surrounding the entire listener in the if statement would make more sense. action will take the value from getStringExtra at the time you run the surrounding code, not when the listener is fired.
There may be other issues.
if(action.equals("search"))
instead
if(action == "search")
MainActivity has an attribute android:launchMode="singleInstance" in AndroidManifest.xml
Here's the onCreate method from MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG, "onCreate() from MainActivity");
session = new TempSession(this);
// check if logged in. If not, take the user back to login activity.
session.checkLogin(); // <---- HERE
Toast.makeText(this, "logged in as " + session.getUsername(), Toast.LENGTH_SHORT).show();
// Prevents screen from turning off when in this Activity.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
....
and the TempSession, it checks if user is logged in, and if not, it will take the user to the LoginActivity.
This is the checkLogin() method
public void checkLogin(){
// Check login status
if(!this.isLoggedIn() || getUsername() == null) {
// user is not logged in redirect him to Login Activity
Intent i = new Intent(context, LoginActivity.class);
// Closing all the Activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
// Add new Flag to start new Activity
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
// Staring Login Activity
context.startActivity(i);
}
}
From my understanding, where I marked <---- HERE from MainActivity, when it calls checkLogin(), shouldn't it finish all task before it proceeds?
Currently, my app would open up LoginActivity, but still proceeds to the next instructions (e.g. makes a Toast saying "logged in as null", and keeps going on in background) and calls onPause() -> onStop() .
Is there any way to stop the MainActivity from keep going at that point?
This situation causes pressing back from LoginActivity bypasses to MainActivity.
Let me know if you need more information.
Thank you in advance.
Is there any way to stop the MainActivity from keep going at that point?
Yes. Have checkLogin() return some value that indicates MainActivity#onCreate(...) should return instead of proceeding.
Calling startActivity(...) does not start an activity. Think of it as asking the Android framework to start an activity. It places this job at the end of the UI thread's work queue. That means that before it starts the new activity, it will finish any other jobs that are already in the work queue, including the rest of the current method and possibly other lifecycle methods of the current activity.
The reason that your toast still shows up is because merely starting a new activity does not destroy your old activity. It's merely pushed to the backstack. Of course you can change this using the android:launchMode attribute in your manifest. A simple strategy in your cause might be to simply return true from your checkLogin() method when the user is logged in and change your onCreate as follows:
if( session.checkLogin() ) {
Toast.makeText(this, "logged in as " + session.getUsername(), Toast.LENGTH_SHORT).show();
// Prevents screen from turning off when in this Activity.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
....
}
I have a MainPage activity that the user is taken to after logging in. This activity then dynamically draws one button on the screen for each subcategory it finds in my database in a TableLayout. This works, but if the user logs out and logs back in again then the MainPage will display twice the number of buttons (it never deletes the original set).
I have tried removing the buttons just before the user logs out using removeView(). However when the user presses log out the buttons disappear and the login activity is opened. When the user has logged back in the first set of buttons are still on the screen as well as the new set.
I'm an android newbie and I can't find anyone with a similar problem so I'm not sure if I've made quite a silly mistake here. It seems to me that I must be opening MainPage incorrectly, but I'm not sure.
Below is the code I think is relevant to this question.
LoginActivity, the lines I am using to open MainPageActivity if login successful:
Intent mainPage = new Intent(getApplicationContext(), MainPageActivity.class);
mainPage.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mainPage.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
startActivity(mainPage);
// Close Login Screen
finish();
MainPageActivity, method that is called just before closing the activity when the user presses logout.
public void removeSectionButtons(TableLayout tableLayout){
int noOfRows = tableLayout.getChildCount();
System.out.println("rows was "+noOfRows);
for(int i = 0; i<noOfRows; i++){
int id=i+1;
TableRow row = (TableRow) tableLayout.getChildAt(id);
tableLayout.removeView(row);
}
}
MainPageActivity, the case in onOptionsItemSelected() when log out is pressed.
case R.id.action_logout:
tableLayout = (TableLayout)findViewById(R.id.MainPageTableTitle);
removeSectionButtons(tableLayout);
//code here to log out the user
menuHelper.logoutUser(userFunctions, getApplicationContext());
return true;
And finally the logoutUser() method in the MenuHelper class:
public void logoutUser(UserFunctions userFunctions, Context context){
userFunctions.logoutUser(context);
Intent login = new Intent(context, LoginActivity.class);
login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
login.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
context.startActivity(login);
finish();
}
This was my bad, removeView() was working. The problem instead was with my database handling. Everytime the user logged out I was not wiping the SQLite database on the phone...but every time they logged in I was copying data off the server into the lite databse again.
This meant that when the user logged out and logged back in all the fields in the database had been duplicated so my code was displaying what was in the database as it should.
I have an activity which is repeated "x" times with this piece of code :
//create intent to start itself again with different parameters
Intent intent = getIntent();
intent.putExtra(CATEGORY_ID, temp.getCat_ID());
intent.putExtra(CATEGORY_SHOPID, temp.getShopID());
intent.putExtra(CATEGORY_SITEID, temp.getSiteID());
intent.putExtra(CATEGORY_NAME, temp.getCat_Name());
finish();
startActivity(intent);
My goal is that when the user presses the back button that the same activity gets started as there was before with the same parameters as before and such. I tried saving them in an Activity ArrayList but that doesn't seem to work.
When you call finish, your activity will end.
When you don't call finish, your activity just go to the background. In that case, when you press the backbutton in your new activity, your previous activity comes up.
I think when you just delete finish(), it will work.
It's okay if you save the parameters you've already set earlier, but you need to retrieve all that information from the Intent itself and repopulate your activity with the proper data.
This must be done like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String categoryId = getIntent().getStringExtra(CATEGORY_ID);
// retrieve the others and populate your activity
}
in your activity, get event back
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK ) {
// and you have to make a intent to call this activity again with parameter other
finish(); // and call finish() here to close the old activity
}
return super.onKeyDown(keyCode, event);
}
hope this help!
Have you tried overriding the onBackPressed method?
OK, I was adviced to make a new thread for my question. I am using imported SQLite database. Anyway, I have made two themed dialogs for right and wrong answers, and I want to show them when right or wrong answer is clicked. Here's the code in my activity, cut out parts:
private class Answer {
public Answer(String opt, boolean correct) {
option = opt;
isCorrect = correct;
}
String option;
boolean isCorrect;
}
final OnClickListener clickListener = new OnClickListener() {
public void onClick(View v) {
Answer ans = (Answer) v.getTag();
if (ans.isCorrect) {
Toast toastT = Toast.makeText(Kviz.this, "Correct!", Toast.LENGTH_SHORT);
toastT.show();
finish();
}else{
Toast toastP = Toast.makeText(Kviz.this, "Wrong!", Toast.LENGTH_SHORT);
toastP.show();
}
startActivity(getIntent());
}
};
When I use Toast like above it works fine, but when I try to use my themed activity like this, it doesn't, instead it goes right to next question, and when I press back button on my phone I get that themed popup activity:
final OnClickListener clickListener = new OnClickListener() {
public void onClick(View v) {
Answer ans = (Answer) v.getTag();
if (ans.isCorrect) {
Intent t = new Intent("rs.androidaplikacijekvizopstekulture.TACANODGOVOR");
startActivity(t);
finish();
}else{
Intent p = new Intent("rs.androidaplikacijekvizopstekulture.POGRESANODGOVOR");
startActivity(p);
}
startActivity(getIntent());
}
};
To repeat, I get the themed activity when I press the back button, I get the wrong ones and the correct ones, as I go backwards. I just want to show that dialog and then to load the next question, like it does with the Toast. Just to mention that this activity loading works fine in my other acitivity, only it goes after simple button click, no question and answers.
The reason is after calling any of (right/wrong) startActivity, it moves on to call startActivity(getIntent()); method. One way is to make your TACANODGOVOR & POGRESANODGOVOR Dialog activity by adding following tag/value for these activities in manifest file android:theme="#android:style/Theme.Dialog" e.g.
<activity ... android:theme="#android:style/Theme.Dialog" />
It will display TACANODGOVOR & POGRESANODGOVOR as dialog and unless user presses back button (or any exit button activities may have), it wont proceed to next line.