How to get callback when Android app comes foreground from background? - android

How to know app state background to foreground in android?
I had extends my activities from one Baseactivity call and Baseactivity class extends android Activity.
I put code appcomeForeground() into base activity on onRestart() but its call when we navigate activity into our foreground app also.
Please suggest way to get call back only when app comes foreground.
Thanks in advance.

to check whether your application is in background of foreground you can do the following.
Declare a class which will maintain the state
public class ApplicationState {
public static boolean isActivityVisible() {
return activityVisible;
}
public static void activityResumed() {
activityVisible = true;
}
public static void activityPaused() {
activityVisible = false;
}
private volatile static boolean activityVisible;
}
in the onResume method of every activity of your application call
ApplicationState.activityResumed()
and in onPause method of every activity of your application call
ApplicationState.activityPaused()
Now at anytime you can check the foreground/background state of your application by just calling
ApplicationState.isActivityVisible()

Maintain a boolean variable in Baseactivity,
i.e.:
private boolean isForeground;
Inside onResume() of Baseactivity make isForeground = true
and inside onPause() method of Baseactivity make isForeground = false
and whenever you want to know the status,check that boolean variable and apply your further logic accordingly.

There's no framework-provided way to do this. I've described my own solution here: https://stackoverflow.com/a/14734761/1207921

Another way to solve is to call putExtra on the intents which let the user navigate between the app's activities. If onRestart/onResume does not receive this Extra, the app was just coming into foreground.

Related

Check if activity onStop is called while starting a new activity

I am trying to solve a problem. In my application I need to determine if onStop method was called because of starting a new activity or it was called after user had clicked on the home button or had switched to another app.
I have BaseActivity class, and I need to check it here.
I have tried to find a way to do this, but unfortunately still no solution is found.
Maybe there is a workaround for that.
The idea is to differentiate the initiator of onStop method call.
I would be grateful for any help.
A possible solution would be to register an ActivityLifecycleCallbacks and save the reference name of the last activity that called onResume:
public class ActivityChecker implements Application.ActivityLifecycleCallbacks {
private static ActivityChecker mChecker;
private String mCurrentResumedActivity = "";
public static ActivityChecker getInstance() {
return mChecker = mChecker == null ? new ActivityChecker() : mChecker;
}
// If you press the home button or navigate to another app, the onStop callback will be called without touching the mCurrentResumedActivity property.
// When a new activity is open, its onResume method will be called before the onStop from the current activity.
#Override
public void onActivityResumed(Activity activity) {
// I prefer to save the toString() instead of the activity to avoid complications with memory leaks.
mCurrentResumedActivity = activity.toString();
}
public boolean isTheLastResumedActivity(#NonNull Activity activity) {
return activity.toString().equals(mCurrentResumedActivity);
}
// [...] All other lifecycle callbacks were left empty
}
The ActivityLifecycleCallbacks can be registered in your Application class:
public class App extends Application {
public App() {
registerActivityLifecycleCallbacks(ActivityChecker.getInstance());
}
}
Don't forget to register it in your manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.package.name">
<application
...
android:name=".App"
> ...
</application>
</manifest>
Then, you can use it in your base Activity.
public class MyBaseActivity {
#Override protected void onStop() {
if(ActivityChecker.getInstance().isTheLastResumedActivity(this)) {
// Home button touched or other application is being open.
}
}
}
References:
Registering your custom Application class and the ActivityLifecycleCallbacks: https://developer.android.com/reference/android/app/Application.html
After writing this I found this link with some other options to retrieve the current resumed activity: How to get current foreground activity context in android?.
You can use SharedPreferences to check it:
#Override
protected void onStop() {
super.onStop();
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
pref.edit().putBoolean("IfOnStopCalled", true).apply();
}
Check in your BaseActivity:
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
Boolean IfOnStopCalled = pref.getBoolean("IfOnStopCalled",false);
if(IfOnStopCalled){
//Do your action
}
else{
//Do your action
}

Android - How to know when app has been resumed after being in background

I'm trying to determine when my app is being resumed after the user closed it, in any way, pressing home button, back button or switching to another app.
What I need to do is to set a boolean when the app goes in background, so, when it is resumed, I know that it was in background before and I can act accordingly.
I tried to use onResume and onPause methods in activities to know when the app goes in background and it is then resumed, but as only one activity can be alive at at time, I had no success. When an activity is paused, this doesn't mean that the app went to background, because another activity could have been launched, but the onResume event of that activity will trigger only after the previous one has paused.
I've also tried to list all the apps in foreground, but with no success, if I put my app in background resuming another app, my app always results to be in the foreground.
I read that since Android 4 there is a new method to know when the app is in foreground, but I need my app to be compatible with Android 3.0 devices too.
Here is the code I tried putting in every single activity (MyApp is my Application name):
#Override
protected void onResume() {
super.onResume();
MyApp.isPaused = false;
}
#Override
protected void onPause() {
super.onPause();
MyApp.isPaused = true;
}
This is also my attempt to list all the apps in foreground:
ActivityManager activityManager = (ActivityManager)((Activity) currentContext).getSystemService( ACTIVITY_SERVICE );
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
for(RunningAppProcessInfo appProcess : appProcesses){
if(appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
if(appProcess.processName.equals("com.xxx.myapp")) {
Log.i("MyApp", "it's in foreground");
}
Log.i("MyApp", appProcess.processName);
}
}
This class provides a singleton to determine "the activity in background" status. It uses a timer with a threshold(i.e. 0.3s) to determine the activity is went to background or not.
One thing has to point out is that if the user resumes to the activity within the threshold (i.e. 0.3s), this test will be failed.
If you have a better solution, please share with us :)
Ref: https://gist.github.com/steveliles/11116937
You are absolutely correct :) Because only one activity can be alive at a time so you need something which remains alive through out the application life cycle :) like Application instance itself or you can also make use of shared preference for that matter. But seriously using shared prefference for checking lifecycle is wrong choice if you ask me.
If I was in your position I would have gone for Application class :) Here is code if you want to do the same :)
import android.app.Application;
/**
* Created by sandeepbhandari on 3/3/16.
*/
public class AppService extends Application{
private static AppService sInstance;
public static boolean isGoingToBackGround=false;
#Override
public void onCreate() {
super.onCreate();
sInstance = this;
}
public static AppService getInstance() {
return sInstance;
}
}
In all your activities onPause just set
AppService service = AppService.getInstance();
service.isGoingToBackGround =true;
And in onResume check the same variablethats all :) and yeah if you want to use your application class rather than default Application you have to make change to manifest.xml
<application
android:name=".AppService"
Thats all :)
Override onTrimMemory(int level) in your Application. Might not be the prettiest way, but it has worked for me.
You will get
TRIM_MEMORY_BACKGROUND = 40;
when your application went into the Background.
You can make Application class inside your project to save state of your project. When any activity goes to pause call on pause respectively while on resume call on resume method and save state of the inside this class. Even if one activity goes on pause another on resume your class will know exact state of the application. Or another way you can save applicaton state in shared preference in each activity can change its value.
i trust there is no need for u to post a code... that being said...
start by logging every implemented methods onCreate(), onPause(), onDestroy(), and other well reputed Activity methods...
but back button does not just pause it kills, thus onCreate is called most
and check onStart() too.
public class CustomApplication extends Application {
private static boolean activityVisible;
#Override
public void onCreate() {
super.onCreate();
}
public static boolean isActivityVisible() {
return activityVisible;
}
public static void activityResumed() {
activityVisible = true;
}
public static void activityPaused() {
activityVisible = false;
}
}
and in your all activities set
#Override
protected void onResume() {
super.onResume();
CustomApplication.activityResumed();
}
#Override
protected void onPause() {
super.onPause();
CustomApplication.activityPaused();
}
and in your manifest
<application
android:name=".CustomApplication"

Get state of activity (paused / resumed)

I am using a LoaderManager to get some data and when it finishes a child fragment should be shown. In some cases this happens when the activity is already in paused state and can not perform the fragment transaction.
Is there a way to get the current state of the activity (seems to have a mResume flag)? Or do I have to maintain my own boolean?
The new Architecture Components allow you to do it with:
this.getLifecycle().getCurrentState()
A quick look in the Activity source code indicates that the Activity class does keep track on the resume state with the member mResumed. But since mResume is not public and isResumed() is hidden, we can't use them.
You can have a simple solution to provide you with that information for all your classes. Simply create a base Activity class that store the state. For example:
public class ActivityBase extends Activity {
private boolean mIsResumed = false;
#Override
public void onResume() {
super.onResume()
mIsResumed = true;
}
#Override
public void onPaused() {
super.onPaused()
mIsResumed = false;
}
public boolean isResumed() {
return mIsResumed
}
}
Simply extend this class with your class:
public class MyActivity extends ActivityBase {
private void onLoadDone() {
if (isResumed()) {
// Show the fragment
}
}
}
One way it could be achieved is by using breakpoints on your Activity (for instance, putting a breakpoint in your onResume method), and using the Evaluate Expression window that you can open by clicking a right click on your Debug menu window, and selecting it from there (OR SHIFT + F8) for mac. Once opened, you can intercept the current state (depending where your breakpoint is) using this line in your Evaluate Expression Window:
getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)
If it returns true, that means your Activity is currently in the resume state.
If false, it's in another state.
They have plenty of other states you can play with, just check here

About launcher intent

I'm trying to make a certain function to start only when a user,
Opens the app for the first time,
Goes back to an app from home.
But not start if the user switches between activities within the app.
I have looked through this topic,and the best answer is to use singleTask with onNewIntent(). So, if a user is goes back to the app from Home, a onNewIntent call with the launcher intent passed to it can be used.
However, here is my code:
public class AdMobSDK_DFP_Interstitial extends Activity implements AdListener {
private static final String MOBMAX_INTERSTITIAL_AD_UNIT_ID = "/7732/test_portal7/android_app1_test_portal7/splash_banner_android_app1_test_portal7";
private DfpInterstitialAd interstitialAd;
private int num = 0;
public void onNewIntent(Intent intent){
super.onNewIntent(intent);
Log.d("flow", "onNewIntent");
}
If I switch between different activities in the app, onNewIntent() is always called, which is the same as I go back to the app from Home.
First thing you can do is to implement your own "Application" object and have it run the needed function when it is created.
public class MyApplication extends Application {
#Override
public void onCreate() {
// Call your function
}
}
Your application object will be live as long as your app is alive (any activity/service is still running), but note that the Application object is not destroyed immediately when the user presses "Home", and might stay alive for a while and a user can return to it without the function being called.
If you need this function to run as part of your main activity, just save a flag in your Application context :
public boolean alreadyDisplayed = false; and then in your activity's onStart you can just call
if ((MyApplication)getApplication().alreadyDisplayed ) {
// Call your function
(MyApplication)getApplication().alreadyDisplayed = true;
}
** If this solution is not enough for you and you need to call your function every time your main activity is displayed from the home page you'll need to do something not as nice... one suggestion I can give you is to implement the same Application object but this time with an "open activity" counter:
public class MyApplication extends Application {
public int mActivityCounter = 0;
}
Then you can increment this counter on every onStart of activity in your app and decrement on every onStop (of course this can be done by implementing a class MyActivity and make all your relevant activities inherit it. Then you can use this counter to know if there are any other activities opened. Note that you'll have to make sure the access to this counter is synchronized and work your way with it as you need.
I hope this helps...

Convenient way to find out whether onReceive on BroadcastReceiver was called while the application was running?

I have a static registration for BroadcastReceiver for handling SMS in Manifest. Is there a proper way to find out whether onReceive() method on that receiver class was called while the application was running or not ?
This is required so, I can start a activity if SMS was received when application was not running, otherwise, just process information and display some notification.
Track visibility of your application yourself by using Activity.onPause(), Activity.onResume() methods and a static boolean. Store "visibility" status in some other class. Good choices are your own implementation of the Application or a Service (there are also [a few variations][4] of this solution if you'd like to check activity visibility from the service).
Example
This example provides the skeleton code for one activity, but you can add more booleans if you need to track more than one Activity.
Implement custom Application class (note the isActivityVisible() static method):
public class MyApplication extends Application {
public static boolean isActivityVisible() {
return activityVisible;
}
public static void activityResumed() {
activityVisible = true;
}
public static void activityPaused() {
activityVisible = false;
}
private static boolean activityVisible;
}
Register your application class in AndroidManifest.xml:
<application
android:name="your.app.package.MyApplication"
android:icon="#drawable/icon"
android:label="#string/app_name" >
Add onPause and onResume to every Activity in the project (you may create a common ancestor for your Activities if you'd like to, but if your activity is already extended from MapActivity/ListActivity etc. you still need to write the following by hand):
#Override
protected void onResume() {
super.onResume();
MyApplication.activityResumed();
}
#Override
protected void onPause() {
super.onPause();
MyApplication.activityPaused();
}

Categories

Resources