Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react native AppState has no 'inactive' state on Android

I am trying to change the UI just before the user leaves the app (user is in multi-tasking view or switches to some other app). To be more specific when user leaves the app I want to add a fullscreen view with the app logo.

I am using AppState for that.

On iOS it works as expected: in multitasking view app gets inactive state and once switched to other app state goes to background. When state is inactive I can still change UI.

However, on Android the state is either active or background. Problem is that in background state I cannot change the UI anymore.

Is this a bug on Android? If not, what are my options to get it working on Android.

Thanks.

like image 529
algizmo Avatar asked Nov 03 '16 15:11

algizmo


People also ask

How do I get rid of addEventListener AppState?

Use the remove() method on the EventSubscription returned by addEventListener() .

How do I check my application status in React Native?

Step 2: Create a react native project using expo. Step 3: Now go to the created project using the below command. Project Structure: It will look like the following: Checking App State: AppState module can be used to determine an app's current state, whether it is in the foreground or background.

How do you know app is closed in React Native?

With @react-native-community/hooks you can use the useAppState hook to check the app state. When you close the app, it gets a state of unknown once you open it back. When is in background, it says background' or 'inactive'.


1 Answers

If you need to, you can simulate the same states as iOS by adding some code to MainActivity.java to listen to its lifecycle events

//onResume = 'active'  
//onPause = 'inactive'  
//onStop = 'background' 

@Override
public void onResume() {
    super.onResume();
    ReactContext reactContext = getReactInstanceManager().getCurrentReactContext();
    WritableMap params = Arguments.createMap();
    params.putString("event", "active");

    // when app starts reactContext will be null initially until bridge between Native and React Native is established
    if(reactContext != null) {
        getReactInstanceManager().getCurrentReactContext()
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
            .emit("ActivityStateChange", params);
    }
}

@Override
public void onPause() {
    super.onPause();
    ReactContext reactContext = getReactInstanceManager().getCurrentReactContext();
    WritableMap params = Arguments.createMap();
    params.putString("event", "inactive");

    if(reactContext != null) {
        getReactInstanceManager().getCurrentReactContext()
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("ActivityStateChange", params);
    }
}

@Override
public void onStop() {
    super.onStop();
    ReactContext reactContext = getReactInstanceManager().getCurrentReactContext();
    WritableMap params = Arguments.createMap();
    params.putString("event", "background");

    if(reactContext != null) {
        getReactInstanceManager().getCurrentReactContext()
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("ActivityStateChange", params);
    }
}

Then in your JS listen to these lifecycle changes using DeviceEventEmitter

const nativeEventListener = DeviceEventEmitter.addListener('ActivityStateChange',
  (e)=>{
      console.log(e.event);
})
like image 117
Brien Crean Avatar answered Oct 05 '22 18:10

Brien Crean