2

I have an Application class like so:

public class MyApplication extends Application {
    private static boolean FOCUSED;

    public static boolean isAppFocused() {
        Log.v("@@@@@@  isAppFocused", "called");
        return FOCUSED;
    }  

    public static void appResumed() {
        Log.v("@@@@@@  appResumed", "called");
        FOCUSED = true;
    }

    public static void appPaused() {
        Log.v("@@@@@@  appPaused", "called");
        FOCUSED = false;
    }  
}

And inside my MainActivity I'm calling its methods like so:

@Override
protected void onResume() {
    super.onResume();
    MyApplication.appResumed();
}

@Override
protected void onPause() {
    super.onPause();
    MyApplication.appResumed();
}

As you see, I have never called the MyApplication.appPaused(); method. And FOCUSED variable's default value inside MyApplication is null.

Strangely when I call isAppFocused() inside service, it returns false!!!!!

I want to know if the app is focused so that it doesn't show notifications inside service. I even used SharedPreferences before this, and that had the same problem, no matter what, their value is not gonna be the one I expect. :|

I don't know why it doesn't want me to know if app has focus. :| I'm pissed off.

EDIT: I changed the Application class to this:

public class MyApplication extends Application {
    private static String FOCUSED;

    public static String isAppFocused() {
        Log.v("@@@@@@  isAppFocused", "called");
        return FOCUSED;
    }  

    public static void appResumed() {
        Log.v("@@@@@@  appResumed", "called");
        FOCUSED = "true";
    }

    public static void appPaused() {
        Log.v("@@@@@@  appPaused", "called");
        FOCUSED = "false";
    }  
}

Now inside the Service I'm using it like so:

if(MyApplication.isAppFocused().equals("false")){
  //show notifications
}

Now it throws NullPointerException, but I see in logcat that appResumed() method is called twice before calling isAppFocused().

inside AndroidManifest.xml:

<application
    android:allowBackup="false"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:uiOptions="splitActionBarWhenNarrow" android:supportsRtl="true">



    <!-- Splash screen -->
    <activity
        android:name="com.example.SplashScreen"
        android:screenOrientation="portrait"
        android:theme="@android:style/Theme.Black.NoTitleBar" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

    <!-- Main activity -->
    <activity
        android:name="com.example.MainActivity"
        android:configChanges="orientation|screenSize|keyboardHidden"
        android:launchMode="singleTask"
        android:label="@string/app_name" >
    </activity>

    <!-- Login activity -->
    <activity 
        android:name="com.example.Login"
        android:screenOrientation="portrait">
    </activity>

    <!-- Push Service -->
    <receiver android:name="com.example.service.MyBroadcast" 
              android:enabled="true" 
              android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
    </receiver>
    <service android:name="com.example.service.MyService"
             android:process=":My_Service_Process"
        />

</application>
<application
    android:name="com.example.MyApplication" >

</application>

EDIT 2: I changed inside MainActivity:

@Override
protected void onResume() {
    super.onResume();
    MyApplication.appResumed();
    Log.v("**** isAppFocused", MyApplication.isAppFocused());  
}

@Override
protected void onPause() {
    super.onPause();
    MyApplication.appPaused();
    Log.v("**** isAppFocused", MyApplication.isAppFocused());  
}

the result is correct, and onResume it returns "true" and onPause it returns "false". but inside the service it always returns the default value which is "true"; I don't know why it changes inside MainActivity but it doesn't change inside service.

Angry version of the Application class:

public class MyApplication extends Application {
    private static String FOCUSED = "true";

    public static String isAppFocused() {
        Log.v("@@@@@@  isAppFocused", "called");
        return FOCUSED;
    }  

    public static void appResumed() {
        Log.v("@@@@@@  appResumed", "called");
        FOCUSED = "true";
    }

    public static void appPaused() {
        Log.v("@@@@@@  appPaused", "called");
        FOCUSED = "false";
    }  
} 
M D P
  • 4,525
  • 2
  • 23
  • 35
  • please someone try to do this, and if it worked please post your code here. I'm using background service for push notifications, it should return true while the app is focused and return false if it's not focused. I want to have access to such information inside my Service which is running on a different thread. see if you can accomplish such thing. thanks. – M D P Jul 24 '14 at 01:45
  • What is the purpose of the FOCUSED flag? Can you elaborate on this more? – Code-Apprentice Jul 24 '14 at 01:51
  • it holds the state of the app. if the app is resumed it should be true; – M D P Jul 24 '14 at 01:54
  • The problem is that this seems like a solution to another problem. What is the original problem that you are trying to solve by using this flag? – Code-Apprentice Jul 24 '14 at 03:08
  • that's not a problem, I want my service to show notifications only if the main app has focus. – M D P Jul 24 '14 at 03:59

1 Answers1

1

According to Within an application, will the activity and service run in the same process?, your Service and Activity run in different processes. This means that any changes your activity makes to any variables are not visible to the service. You need to find another way to communicate between the service and activity. See Communication between Service and Activity on Android for suggestions.

Community
  • 1
  • 1
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • there are many ways, one way is broadcastreceiver one way is using sharedpreferences which I tried and had the same problem and one way is using Application class. well how can I solve this problem? moving to another way is not the solution. – M D P Jul 24 '14 at 04:35
  • I just want to check if the app has focus, how hard could this be? – M D P Jul 24 '14 at 10:41
  • @MDP You cannot use the Application class because you have two separate instances of it in each process. SharedPreferences might have the same problem. I'm not entirely sure since I am unfamiliar with them. – Code-Apprentice Jul 24 '14 at 19:00
  • @MDP Another option is to start the service in your Activity's onResume() and stop it in onPause(). – Code-Apprentice Jul 24 '14 at 19:01
  • the whole point of the service is to be running even if the app is not running, that's why I made it android.intent.action.BOOT_COMPLETED. I can't stop it. SharedPreferences write info on a file, so everyone can access it, and it was working perfectly for some time, but I don't know why it's not changing the same key value, the same problem I have with Application class. I want to check if the app has focus, not show the notification, I don't want to stop the whole service. how can I do that? – M D P Jul 24 '14 at 21:04
  • @MDP Then you will need to look at BroadcastRecievers. – Code-Apprentice Jul 24 '14 at 22:46
  • but what's the use of Application class then? shouldn't it be worked in services? because in activities we can pass variables through Extras on Intent, I think the main use of Application class is to be used inside services. what's wrong with my app? – M D P Jul 24 '14 at 23:28
  • @MDP As I said in my answer, you have two processes with two instances of `MyApplication`. Changing variables in one process doesn't affect the variables in the other. You will need to find another solution in order to communicate between your Service and your Activity. – Code-Apprentice Jul 25 '14 at 00:11
  • thanks, I ended up using BroadcastReceiver, it was so hard because it wasn't working either, but now it's working. – M D P Jul 25 '14 at 23:05