Reputation: 6792
I have come across a requirement but I am not able to get the correct way of implementation and hence need your help.
What I want to do? - I want to perform an action depending upon notification I get as follows:
What I have done? I have achieved point #1 and #2. I want to achieve point #3. I have tried the below
public static boolean isApplicationBroughtToBackground(final Activity activity) {
ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);
// Check the top Activity against the list of Activities contained in the Application's package.
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
try {
PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
for (ActivityInfo activityInfo : pi.activities) {
if(topActivity.getClassName().equals(activityInfo.name)) {
return false;
}
}
} catch( PackageManager.NameNotFoundException e) {
return false; // Never happens.
}
}
return true;
}
However this returns true in both the cases, point #2 and #3, so I am not able to distinguish only #3.
Also I tried the below in every Activity I have,
@Override
protected void onPause() {
super.onPause();
saveIsPausedInPref(true);
}
@Override
protected void onResume() {
super.onResume();
saveIsPausedInPref(false);
}
But, it also doesn't give the desired result coz if the app is sent to background by pressing the Home button my Preference will have isPaused = true and if the user removes the app from recent then it will stay true and again I will not be able to differentiate Point #2 and #3 when the notification arrives.
Apologies for the whole story, but I hope I am able to explain my requirement.
Thanks in advance. :)
Edit:
<activity
android:name=".HomeActivity"
android:screenOrientation="portrait" >
</activity>
<activity
android:name=".ChatProfileActivity"
android:screenOrientation="portrait" >
</activity>
Upvotes: 9
Views: 2840
Reputation: 95636
To differentiate between case #2 and case #3, you can do the following:
Launch ActivityB
if it is not case #1. In ActivityB.onCreate()
do this:
super.onCreate(...);
if (isTaskRoot()) {
// ActivityB has been started when the app is not running,
// start the app from the beginning
Intent restartIntent = new Intent(this, MyRootActivity.class);
startActivity(restartIntent);
finish();
return;
}
... rest of onCreate() code here...
Upvotes: 2
Reputation: 6697
Below code works for me
In AndroidManifest.xml
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:name=".MyApplication"
>
MyApplication.java
public class MyApplication extends Application {
private ActivityLifecycleCallbacks myLifecycleHandler;
@Override
public void onCreate() {
super.onCreate();
myLifecycleHandler=new MyLifecycleHandler();
registerActivityLifecycleCallbacks(myLifecycleHandler);
}
}
MyLifecycleHandler.java
public class MyLifecycleHandler implements Application.ActivityLifecycleCallbacks {
private static final String TAG = MyLifecycleHandler.class.getSimpleName();
private static int resumed;
private static int paused;
private static int started;
private static int stopped;
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
++resumed;
}
@Override
public void onActivityPaused(Activity activity) {
++paused;
Log.d(TAG, "application is in foreground: " + (resumed > paused));
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityStarted(Activity activity) {
++started;
}
@Override
public void onActivityStopped(Activity activity) {
++stopped;
Log.d(TAG, "application is visible: " + (started > stopped));
}
public static boolean isApplicationVisible() {
return started > stopped;
}
public static boolean isApplicationInForeground() {
return resumed > paused;
}
}
Now using myLifecycleHandler methods you can get all states you need.
isApplicationInForeground means -> Atleast one activity is in visible state.
isApplicationVisible means -> Atleast one activity is there which got started but not stopped, means application is running state
if isApplicationInForeground is true isApplicationVisible will be always true, but vice versa is not true
Upvotes: 4
Reputation: 5119
If you change to not show any pop up, just to go to the Activity B always (destroyed, background or foreground), you don't need any of this check. Just to work with the flags FLAG_ACTIVITY_X on your notification (it's GCM this notification?).
You can use the onNewIntent method to check the intent if comes from a notification and start Activity B.
Upvotes: 1
Reputation: 4661
I know that u figured out 1 & 2 but ill right my own toughts in case u did something else and u want to take a look.
How to know whether your app is in foreground?
this should be the correct way, if its in foreground then post an event via eventbus, eventbus is my preffered way.
Upvotes: 1