5

I have 3 major class in the application

1) Intent service: where I receive push notification and open activity according to notification message and other two classes behavior. below is the code which does that

 if(Global.isMainScreenRunning){
   Intent intent = new Intent(this, MainScreen.class);
   intent.setFlag(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(intent);
} else if(!Global.NotificationScreenRunning){
   Intent intent = new Intent(this, NotificationScreen.class);
   intent.setFlag(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(intent);
}

2) NotificationScreen : This is the mediator screen so if the application is not running this screen will be shown first and on click of yes button of this screen MainScreen will be opened and this screen will be finished.

3) Main screen: This is the main screen of the application which show map. its core behavior is that ts a launchmode="singletask" mentioned in menifest file, which means if this screen is running its hole data will be sent to onNewIntent() method rather than opening this screen again.

Now what is happening in flow is

Step 1: application is in background and push notification comes. condition run and the second condition gets success and notification screen intent is shot

step 2: In notification screen I click on ye button to move on to the next main screen

step 3: In Main screen I process this info and perform task or just close the application

Step 4: again a new notification is received and as the application is not running is goes to second condition and start the intent for notification screen but this time no notification screen is launched instead of providing its intent and main screen is launched which is wrong.

This is the abnormal behavior which I am facing that instead of providing class of notification screen for intent main screen is launched which is totally different behavior of application according to android.

Any help from any one who come across such problem will be greatly appreciated.

Edit

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="18" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.front" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-feature android:name="android.hardware.microphone" />

    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />

    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <permission android:name="com.example.app.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="com.example.app.permission.C2D_MESSAGE" />

    <supports-screens
        android:largeScreens="true"
        android:normalScreens="true"
        android:smallScreens="true"
        android:xlargeScreens="true" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/android_app_icon"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".SplashScreen"
            android:configChanges="keyboardHidden|orientation"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".MainScreen"
            android:configChanges="keyboardHidden|orientation"
            android:launchMode="singleTask"
            android:excludeFromRecents="true"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".NotificationScreen"
            android:configChanges="keyboardHidden|orientation"
            android:excludeFromRecents="true"
            android:screenOrientation="portrait" >
        </activity>

        <receiver
            android:name=".pushnotification.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="com.selebrety.app" />
            </intent-filter>
        </receiver>

        <service android:name=".pushnotification.GcmIntentService" />

        <meta-data android:name="com.google.android.gms.version"
           android:value="@integer/google_play_services_version" />
    </application>

</manifest>

Second Edit

The mobile in which I am testing is "YU Yureka" here is its specification link. Current it have android 5.0.2 OS

Third Edit

To test this behavior I have debugged the code from eclipse debugger. To check this I have put a break point in NotificationScreen onResume and onCreate but it was never hit instead of onResume of MainScreen is hit.

Also I added a logs in if and else condition but still logs for else condition is printed.

Fourth Edit Global.isMainScreenRunning: is global boolean variable which is done false in onPause of MainScreen and done true in onResume of MainScreen.

Global.NotificationScreenRunning: is global boolean variable which is done false in onPause of NotificationScreen and done true in onResume of NotificationScreen.

Abhinav Singh Maurya
  • 3,313
  • 8
  • 33
  • 51

5 Answers5

0

Global state is evil, and this question demonstrates why. To understand what's happening, you'll have to look at every place where your global flags are set or cleared, and analyze all the possible execution paths that might lead there. That's way beyond the scope of the kind of help you can get on SO. And there's an extra complication on Android, since the entire VM might be destroyed (and all your globals cleared) any time your app is in the background. Just as bad, the VM and the Application instance might be retained after you exit the last activity. When that happens, Application#onCreate(...) will not be called again the next time you start the app, and all your static globals will still be set to whatever they were when you last ran the app.

Save yourself a lot of hair-pulling and stop using global state.

Kevin Krumwiede
  • 9,868
  • 4
  • 34
  • 82
  • I believe you have not read the question correctly. Please read question and let me know the answer. And by the way problem is not with the global variable its with the intent not starting correct activity – Abhinav Singh Maurya Jul 13 '15 at 06:14
  • 1
    @AbhinavSinghMaurya believe you have not read the answer correctly. Your question is *unanswerable* without an analysis of every read or write of `Global.isMainScreenRunning` and `Global.NotificationScreenRunning` in your entire app. – Kevin Krumwiede Jul 13 '15 at 06:15
0

You can try add android:taskAffinity=":main" to your MainScreen activity in manifest.
Maybe because the MainScreen still in a same task with the NotificationScreen so it's was call up all the task when NotificationScreen called again.
You can try this demo for more visual: play app and code
Hope it help.

justHooman
  • 3,044
  • 2
  • 17
  • 15
0

As I got your point you want to resume Notification Screen every time when you get notification in the app.For this I can suggest a solution this will make the application runs and allows you to achieve expected behavior but when you press home button your Main screen will no longer active.It will be killed.As we all know android maintains activity stacks for all acticities.So if you press device back button then activity will be poped out from stack and you will not face this problem.

I think this is a standard behavior of activity stacks for more information you can go with this link:

http://www.slideshare.net/RanNachmany/manipulating-android-tasks-and-back-stack

You can try this code snippet:

Intent i = new Intent(NotificationFullScreen.this,
      MainActivity.class);
    i.putExtra("FROM", "Notification");
    i.putExtra("bookingId", bookingId);
    i.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY
      | Intent.FLAG_FROM_BACKGROUND);
    startActivity(i);
    NotificationFullScreen.this.finish();
Ricky Khatri
  • 952
  • 2
  • 16
  • 42
  • what a presentation done by Ran Nachmany. I was not knowing the behavior mentioned in the presentation and sides from 91-101 explain the exact behavior I am facing with Intent.FLAG_ACTIVITY_NEW_TASK. Thanks for the reply. I resolved the problem with the flags you have mentioned. but yes my MainScreen will be killed after moving away from it but what can be done with the default behavior. Your answer fixed my problem. – Abhinav Singh Maurya Jul 20 '15 at 08:23
-1

Hi @Abhinbav Singh Maurya

I think the problem is that main screen is getting called from your splash screen declared in the manifest as the application launch screen, so when the app is killed and you are calling the intent this will get called.

Instead of that what can you do is broadcast the message to the splash screen and receive it in splash screen and based on condition call the intent from there.

Again here there is a thing that you should take care of, you have to broad cast the intent only after the receiver is registered in the SplahScreen, else it will never be received. so try to user handler.postDelayed method and broadcast after 1000 ms or 700 ms.

 Intent mIntent = new Intent(context, SplashScreen.class);
                mIntent.setAction(Intent.ACTION_MAIN);
                mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
                mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(mIntent);
broadcastMessage(context, message);

I have answered a similar question in the following thread. here

I think this is what you are looking for. Please let me know if this met your requirement or not, if you find the answer useful, if my answer helps you, up vote the answer so that it will be useful to others.

Cheers :)

Edit

I have did a bit research on it.

You can have two launcher activities according to this link.

Try it and let me know. Hope this helps you. :)

Community
  • 1
  • 1
  • please check my question correctly I have not mentioned mainscreen as launch screen I have declared its launch mode as single task. There is lot of difference between them. – Abhinav Singh Maurya Jul 11 '15 at 04:56
  • can you post your manifest here. In your question you mentioned that the MainScreen is the mainscreen of the application.. So what is the reason to downvote the answer? – Programming Pirate Jul 11 '15 at 04:57
  • Now when the application is not running and you try to call intent, your 'SplashScreen' will be loaded as per my knowledge. So Obviously your splash screen will start and load your 'MainScreen'. So you need to broadcast the intent from Intent service and receive it in splashscreen and take next action accordingly. That's what my answer said. I assumed that your MainScreen is your launch screen, so please try it and let me know. – Programming Pirate Jul 11 '15 at 05:11
  • Could you please let me know why splash screen will open if I am providing intent a class of notification scree. Is there any specification that only launcher screen can be open from intent service not and ordinary screen? – Abhinav Singh Maurya Jul 11 '15 at 05:55
  • Yes cannot open any screen other than launcher screen if the app is not running, That's why mIntent.addCategory(Intent.CATEGORY_LAUNCHER); and launch the launcher activity and broadcast message. If you can open any other activity other than launcher activity when the app is killed, you can ask even your friends to down vote my answer :) – Programming Pirate Jul 11 '15 at 06:36
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/83015/discussion-between-abhinav-singh-maurya-and-sravan). – Abhinav Singh Maurya Jul 11 '15 at 07:02
  • please check my question once again before answering. I have an intent service running in background. application is closed as soon as push notification is received I open my application specific activity "notification screen". You can open any activity outside the application using new_task flag, so for me outside is intent service for receiving push notification. – Abhinav Singh Maurya Jul 11 '15 at 07:07
  • I have checked your question. You are starting an activity in the OnMessage of the GCMIntentService... That's what I understood.. Am I correct? – Programming Pirate Jul 11 '15 at 07:47
-2
if(Global.isMainScreenRunning){
   Intent intent = new Intent(this, MainScreen.class);
   intent.setFlag(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(Intent);//here is the problem change Intent to intent 

} else if(!Global.NotificationScreenRunning){
   Intent intent = new Intent(this, NotificationScreen.class);
   intent.setFlag(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(intent);
}
  • That is not my problem. Please read question carefully and follow the steps that I have mentioned there – Abhinav Singh Maurya Jul 16 '15 at 05:51
  • i think you want to say that first time app works normal but when app complete its first cycle it behaves abnormal – Padmakar Pandey Jul 16 '15 at 06:21
  • Exactly. Like when you run an open app in eclipse without any change its says its previous task is bring to front, that sort of behavior I am feeling with the app – Abhinav Singh Maurya Jul 16 '15 at 06:23
  • I think that when you close your app from main screen the system closes the app completely so it can't check such condition but at first when the app launches onCreate() runs and check these conditions – Padmakar Pandey Jul 16 '15 at 06:52
  • I checked the conditions of OnCreate and onResume of NotificationScreen but non of them hit. – Abhinav Singh Maurya Jul 16 '15 at 07:11
  • can you provide the complete code of your app? or you have check these conditions contineously in background of your app that checks the condition at some time intervals – Padmakar Pandey Jul 16 '15 at 07:21
  • I have check these condition as soon as push notification is received in intent service. I have provided the flow and what happening. sorry I cannot provide the full source code – Abhinav Singh Maurya Jul 16 '15 at 12:21