I'm trying to get an app to show all the users online... I'm using the following way to achieve it
#Override
public void onStart(){
super.onStart();
mDatabaseReference.child("Online").setValue(true);
}
#Override
public void onStop(){
super.onStop();
mDatabaseReference.child("Online").setValue(false);
}
I'm not using ondisconnect because it shows offline only if the app is completely closed(not running in the background). SO i used this method on each activity... But the problem is that whenever i open an activity it shows online and the next second turns offline... I'm guessing that its because the prev activity closes after opening the new activity so the presents activity's on start is executed before the next activity's on stop. So since the activity's onstop is executed last it shows offline. How do i solve this problem
Your guess is completely correct.
Starting a new Activity will cause the onPause() and onStop() methods to be called for the first Activity.
Based on your description, I'm assuming that you want the Online status to remain true for as long as the app remains in the foreground and you are putting it in every Activity because your app doesn't only open from a single main Activity.
Your current code will work without a problem if you switched to using a Single-Activity Architecture, which is simply to use a single Activity and have it display different Fragments instead of new Activities. This solution will work with your existing code because onStop() and onStart() will only be called when your app enters the background.
If you look at the Navigation section in the official Android Developers Blog, you'll see that Google wants to encourage developers to switch to using the Single-Activity Architecture.
However, if you still wish to use multiple Activities, then you might want to consider an alternative way to keep track of Online status to take into account of multiple Activities.
For example, rather than using a simple boolean value, you can use an int value.
#Override
public void onStart(){
super.onStart();
mDatabaseReference.child("Online").addValue();
}
#Override
public void onStop(){
super.onStop();
mDatabaseReference.child("Online").removeValue();
}
With the addValue() and removeValue() being:
private void addValue(){
activityCount++;
onlineStatus = true;
}
private void removeValue(){
activityCount--;
if(activityCount <= 0)
onlineStatus = false;
}
Please keep in mind that this is only an example and doesn't take into account of how your app is designed. Bottom line is, you'll have to think of a solution that takes into account of multiple Activities that are displayed.
I do heavily suggest the Single-Activity approach.
Related
As the title says.
Specifically, I am writing an app that prints data to files over the course of runtime. I want to know when I can tell my PrintWriters to save the files. I understand that I can probably do autosave every X minutes, but I am wondering if Android Studio will let me save on close instead. I tried using onDestroy but the code block never executed. (To be precise, I started the app, did a few things, closed the app, clicked Recents, and swiped the app away. The debugger showed that the app never got to that code.)
My current solution attempts to catch the surrounding circumstances by checking for key presses but this only works for the back and volume buttons and not the home, recent, or power buttons.
#Override public boolean onKeyDown(int key, KeyEvent event) {
close();
return false;
}
There's a built in hook to the Activity lifecycle to save your state- onSaveInstanceState. There's even a bundle passed into you to save your state into for it to be restored (the matching function is onResumeInstanceState). And as a free bonus, if you call super.onSaveInstanceState and super.onRestoreInstanceState, it will automatically save the UI state of your app for all views with an id.
Please check the activity lifecycle:
https://developer.android.com/guide/components/activities/activity-lifecycle
Or if you're using a fragment:
https://developer.android.com/guide/fragments/lifecycle
Consider using one of these two:
#Override public void onStart() {
super.onStart();
close();
}
#Override public void onPause() {
super.onPause();
close();
}
I am new to java and android studio and after reading documentation I am still a little confused with the activity lifecycle and how to use it effectively.
I am building an application which has several activities. There is key data loaded in when the app is first opened in the main activity. However when I move to another activity and then back to the main, the onCreate is invoked again which I do not want. I am aware there is a way to save the instance of your onCreate but I am still unsure of how to do this. Here is what I have done:
#Override
protected void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if (outState != null) {
// Restore value of members from saved state
outState.putString("step_count", String.valueOf(stepCount));
outState.putString("cal_count", String.valueOf(calCount));
outState.putString("dis_count", String.valueOf(disCount));
android.util.Log.d(TAG, "onSaveInstanceState");
} else {
// Probably initialize members with default values for a new instance
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getString("step_count", String.valueOf(stepCount));
savedInstanceState.getString("cal_count", String.valueOf(calCount));
savedInstanceState.getString("dis_count", String.valueOf(disCount));
stepCount.setText(String.valueOf(stepCount));
calCount.setText(String.valueOf(calCount));
disCount.setText(String.valueOf(disCount));
android.util.Log.d(TAG, "onRestoreInstanceState");
}
Would appreciate any sort of support and guidance. Thank you.
Again - not a simple question.
First of all: Yes, you can save data "from last session" by overriding: onSaveInstanceState() and restore it overriding onRestoreInstanceState(savedInstanceState: Bundle?). Look here: https://developer.android.com/guide/components/activities/activity-lifecycle#saras
Second of all: According to your description it seems that you need SharedPreferences more than this. If you need a key to anything and it should be used from opening of the app until it is killed or user is logged out, SharedPreferences are the most common solution.
onSaveinstanceState() was created to make possibility to remember what was on the screen "in the last session" without "calculating" it again. For example EditText.text or ImageView.url or similar.
I need to hide the content of my application when it goes to the background so sensitive information are not showing up on the android multitasking view.
It's been suggested to use the following line to hide the screen
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
It works fine.
However, this prevents the user from taking screenshot as well which is not an expected behavior for me. I want to let the user take screenshot of the app if they need to. What I don't want is Android to display the latest screen on the multitasking view.
Would it be possible to set the FLAG_SECURE only when the app goes in the background?
We've ended up with this solution which worked the best for us:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!hasFocus) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
}
You can use Activity Lifecycle Callbacks. Just call setVisiblity(View.INVISIBLE) on the views that you want to hide in the onPause() Callback and setVisiblity(View.VISIBLE) in onResume() Callback.
First of all: There is no exception thrown when this problem occurs.
My app is currently running in Google Plays closed alpha program. When I test the app using an emulator provided by Android Studio or using my own Galaxy A5, everything works fine and as expected.
Now I'm getting reports of my alpha testers, that their app is closing after they close the VideoAd. After investigating a while, I realized all devices used by google while performing Pre-Launch-Tests, had the same problem (visible by the video provided by Google).
Since there is no exception thrown, I have absolutely no idea how to debug this behaviour.
Following is the code of the onRewarded method (the other methods of the listener don't contain any code):
#Override
public void onRewarded(RewardItem rewardItem) {
int amount = calculateAdReward(rewardItem.getAmount());
updateCoins(amount);
rewardedAmount = amount;
rewarded = true;
}
rewardedAmount and rewarded are private fields used to instantiate a fragment in the activitys onResume-method:
#Override
protected void onResume() {
super.onResume();
mAdVideo.resume(this);
if(rewarded){
loadFragment(RewardFragment.newInstance(rewardedAmount);
rewardedAmount = 0;
rewarded = false;
}
}
My goal is to display a fragment after the user has been rewarded which holds the rewarded amount. My first attempt was as followed:
#Override
public void onRewarded(RewardItem rewardItem) {
int amount = calculateAdReward(rewardItem.getAmount());
updateCoins(amount);
loadFragment(RewardFragment.newInstance(amount));
}
which failed, since I tried to instantiate a fragment after saveInstanceState was called.
So after a bit of research, I solved my problem.
What I learned:
Never perform transactions inside the activity's lifecycle methods (onResume,...) since there is a possibility that the activity hasn't fully resumed when you reach your transaction code.
Instead, perform transactions in the onPostResume method. When this method is called, it is guaranteed your activity and all it's fragments have been fully resumed and it is "save" to perform a transaction.
On a side note: Don't perform transactions in those methods if you don't absolutely have to.
When turn the switch on it stays on.. however when i leave the activity and come back to it.. it goes back to off. I want it to stay ON OR OFF depending on whats last pressed. I have tried the code below but does not resolve my issue
SwitchButton.setChecked(true);
SwitchButton.setChecked(false);
What you need to do is override these methods in your activity:
#Override
protected void onSaveInstanceState (Bundle outState){
super.onSaveInstanceState(outState);
outState.putBoolean("CHECKED", SwitchButton.isChecked());
}
then in onCreate:
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstaceState);
if(savedInstanceState != null){
boolean isChecked = savedInstanceState.getBoolean("CHECKED");
SwitchButton.setChecked(isChecked);
}
}
If you are minimizing the activity and then returning back to it, and you want all controls to retain their states, then look into implementing saved instance state. This will persist the control values while you minimize / maximize the activity or rotate it. No data is permanently saved to the device. Sample code here:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
If you are closing the app completely and want the app to remember the settings, then consider SharedPreferences, which can be used to save data locally on the device. The data persists until your app explicitly deletes it or you uninstall the app. Sample code here:
http://developer.android.com/training/basics/data-storage/shared-preferences.html