[MM-15874] Add native code to support RNN v2 on Android (#2855)
* Remove fix for MM-9233 * MM-15774 Add native code to support RNN v2 on iOS * Android changes for RNN v2 upgrade The activity visibility handling of NotificationsLifecycleFacade is no longer needed in RNN v2. I've moved the lifecycle callbacks we use for handling managed config into ManagedActivityLifecycleCallbacks.java and registered them in MainApplication's onCreate. Also, I've moved and updated the loading and getting of the managed config into MainApplication * Update moduleNames and modulePaths * Use TAG in restrictionsReceiver * Set launch screen onCreate * Comment out registerActivityLifecycleCallbacks for now * Remove setSoftInputMode call as it's handled in the manifest * Remove clearHostOnActivityDestroy as that fix is no longer needed * Rename to canLaunchEntry * Remove replacement of super.onBackPressed() * Remove react-navigation from packager files
This commit is contained in:
parent
73792d5526
commit
cbe0c719ac
16 changed files with 294 additions and 334 deletions
12
Makefile
12
Makefile
|
|
@ -160,19 +160,11 @@ run-android: | check-device-android pre-run prepare-android-build ## Runs the ap
|
|||
@if [ $(shell ps -ef | grep -i "cli.js start" | grep -civ grep) -eq 0 ]; then \
|
||||
echo Starting React Native packager server; \
|
||||
npm start & echo Running Android app in development; \
|
||||
if [ ! -z ${VARIANT} ]; then \
|
||||
react-native run-android --no-packager --variant=${VARIANT}; \
|
||||
else \
|
||||
react-native run-android --no-packager; \
|
||||
fi; \
|
||||
npm run android; \
|
||||
wait; \
|
||||
else \
|
||||
echo Running Android app in development; \
|
||||
if [ ! -z ${VARIANT} ]; then \
|
||||
react-native run-android --no-packager --variant=${VARIANT}; \
|
||||
else \
|
||||
react-native run-android --no-packager; \
|
||||
fi; \
|
||||
npm run android; \
|
||||
fi
|
||||
|
||||
build: | stop pre-build check-style i18n-extract-ci ## Builds the app for Android & iOS
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ android {
|
|||
applicationId "com.mattermost.rnbeta"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
missingDimensionStrategy "RNN.reactNativeVersion", "reactNative57_5"
|
||||
versionCode 196
|
||||
versionName "1.20.0"
|
||||
multiDexEnabled = true
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@ package com.mattermost.rnbeta;
|
|||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.reactnativenavigation.controllers.SplashActivity;
|
||||
|
||||
public class MainActivity extends SplashActivity {
|
||||
import com.reactnativenavigation.NavigationActivity;
|
||||
|
||||
public class MainActivity extends NavigationActivity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.launch_screen);
|
||||
|
||||
/**
|
||||
* Reference: https://stackoverflow.com/questions/7944338/resume-last-activity-when-launcher-icon-is-clicked
|
||||
|
|
@ -23,9 +25,4 @@ public class MainActivity extends SplashActivity {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSplashLayout() {
|
||||
return R.layout.launch_screen;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,26 @@ import com.mattermost.share.RealPathUtil;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.RestrictionsManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactMarker;
|
||||
import com.facebook.react.bridge.ReactMarkerConstants;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
|
||||
import com.reactnativedocumentpicker.ReactNativeDocumentPicker;
|
||||
import com.oblador.keychain.KeychainPackage;
|
||||
import com.reactlibrary.RNReactNativeDocViewerPackage;
|
||||
|
|
@ -26,10 +40,6 @@ import com.reactnativecommunity.asyncstorage.AsyncStoragePackage;
|
|||
import com.reactnativecommunity.netinfo.NetInfoPackage;
|
||||
import com.reactnativecommunity.webview.RNCWebViewPackage;
|
||||
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
import com.imagepicker.ImagePickerPackage;
|
||||
import com.gnet.bottomsheet.RNBottomSheetPackage;
|
||||
import com.learnium.RNDeviceInfo.RNDeviceInfo;
|
||||
|
|
@ -37,6 +47,8 @@ import com.psykar.cookiemanager.CookieManagerPackage;
|
|||
import com.oblador.vectoricons.VectorIconsPackage;
|
||||
import com.BV.LinearGradient.LinearGradientPackage;
|
||||
import com.reactnativenavigation.NavigationApplication;
|
||||
import com.reactnativenavigation.react.NavigationReactNativeHost;
|
||||
import com.reactnativenavigation.react.ReactGateway;
|
||||
import com.wix.reactnativenotifications.RNNotificationsPackage;
|
||||
import com.wix.reactnativenotifications.core.notification.INotificationsApplication;
|
||||
import com.wix.reactnativenotifications.core.notification.IPushNotification;
|
||||
|
|
@ -46,19 +58,9 @@ import com.wix.reactnativenotifications.core.AppLaunchHelper;
|
|||
import com.wix.reactnativenotifications.core.AppLifecycleFacade;
|
||||
import com.wix.reactnativenotifications.core.JsIOHelper;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactMarker;
|
||||
import com.facebook.react.bridge.ReactMarkerConstants;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class MainApplication extends NavigationApplication implements INotificationsApplication, INotificationsDrawerApplication {
|
||||
public NotificationsLifecycleFacade notificationsLifecycleFacade;
|
||||
public static MainApplication instance;
|
||||
|
||||
public Boolean sharedExtensionIsOpened = false;
|
||||
public Boolean replyFromPushNotification = false;
|
||||
|
||||
|
|
@ -70,6 +72,19 @@ public class MainApplication extends NavigationApplication implements INotificat
|
|||
public long PROCESS_PACKAGES_START;
|
||||
public long PROCESS_PACKAGES_END;
|
||||
|
||||
private Bundle mManagedConfig = null;
|
||||
|
||||
@Override
|
||||
protected ReactGateway createReactGateway() {
|
||||
ReactNativeHost host = new NavigationReactNativeHost(this, isDebug(), createAdditionalReactPackages()) {
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
};
|
||||
return new ReactGateway(this, isDebug(), host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebug() {
|
||||
return BuildConfig.DEBUG;
|
||||
|
|
@ -109,45 +124,33 @@ public class MainApplication extends NavigationApplication implements INotificat
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
instance = this;
|
||||
|
||||
// TODO: Right now I get a black screen when resuming the app from the
|
||||
// background if these callbacks are registered. I'm commenting this out
|
||||
// to move forward and will come back to this at a later date.
|
||||
//registerActivityLifecycleCallbacks(new ManagedActivityLifecycleCallbacks());
|
||||
|
||||
// Delete any previous temp files created by the app
|
||||
File tempFolder = new File(getApplicationContext().getCacheDir(), "mmShare");
|
||||
RealPathUtil.deleteTempFiles(tempFolder);
|
||||
Log.i("ReactNative", "Cleaning temp cache " + tempFolder.getAbsolutePath());
|
||||
|
||||
// Create an object of the custom facade impl
|
||||
notificationsLifecycleFacade = NotificationsLifecycleFacade.getInstance();
|
||||
// Attach it to react-native-navigation
|
||||
setActivityCallbacks(notificationsLifecycleFacade);
|
||||
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
|
||||
// Uncomment to listen to react markers for build that has telemetry enabled
|
||||
// addReactMarkerListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearHostOnActivityDestroy(Activity activity) {
|
||||
// This solves the issue where the splash screen does not go away
|
||||
// after the app is killed by the OS cause of memory or a long time in the background
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPushNotification getPushNotification(Context context, Bundle bundle, AppLifecycleFacade defaultFacade, AppLaunchHelper defaultAppLaunchHelper) {
|
||||
return new CustomPushNotification(
|
||||
context,
|
||||
bundle,
|
||||
notificationsLifecycleFacade, // Instead of defaultFacade!!!
|
||||
defaultFacade,
|
||||
defaultAppLaunchHelper,
|
||||
new JsIOHelper()
|
||||
);
|
||||
|
|
@ -158,6 +161,51 @@ public class MainApplication extends NavigationApplication implements INotificat
|
|||
return new CustomPushNotificationDrawer(context, defaultAppLaunchHelper);
|
||||
}
|
||||
|
||||
public ReactContext getRunningReactContext() {
|
||||
final ReactGateway reactGateway = getReactGateway();
|
||||
|
||||
if (reactGateway == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return reactGateway
|
||||
.getReactNativeHost()
|
||||
.getReactInstanceManager()
|
||||
.getCurrentReactContext();
|
||||
}
|
||||
|
||||
public synchronized Bundle loadManagedConfig(Context ctx) {
|
||||
if (ctx != null) {
|
||||
RestrictionsManager myRestrictionsMgr =
|
||||
(RestrictionsManager) ctx.getSystemService(Context.RESTRICTIONS_SERVICE);
|
||||
|
||||
mManagedConfig = myRestrictionsMgr.getApplicationRestrictions();
|
||||
myRestrictionsMgr = null;
|
||||
|
||||
if (mManagedConfig!= null && mManagedConfig.size() > 0) {
|
||||
return mManagedConfig;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized Bundle getManagedConfig() {
|
||||
if (mManagedConfig!= null && mManagedConfig.size() > 0) {
|
||||
return mManagedConfig;
|
||||
}
|
||||
|
||||
ReactContext ctx = getRunningReactContext();
|
||||
|
||||
if (ctx != null) {
|
||||
return loadManagedConfig(ctx);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addReactMarkerListener() {
|
||||
ReactMarker.addListener(new ReactMarker.MarkerListener() {
|
||||
@Override
|
||||
|
|
@ -171,7 +219,7 @@ public class MainApplication extends NavigationApplication implements INotificat
|
|||
PROCESS_PACKAGES_END = System.currentTimeMillis();
|
||||
} else if (name.toString() == ReactMarkerConstants.CONTENT_APPEARED.toString()) {
|
||||
CONTENT_APPEARED = System.currentTimeMillis();
|
||||
ReactContext ctx = getReactGateway().getReactContext();
|
||||
ReactContext ctx = getRunningReactContext();
|
||||
|
||||
if (ctx != null) {
|
||||
WritableMap map = Arguments.createMap();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
package com.mattermost.rnbeta;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.app.Activity;
|
||||
import android.app.Application.ActivityLifecycleCallbacks;
|
||||
import android.content.Context;
|
||||
import android.content.RestrictionsManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
|
||||
public class ManagedActivityLifecycleCallbacks implements ActivityLifecycleCallbacks {
|
||||
private static final String TAG = ManagedActivityLifecycleCallbacks.class.getSimpleName();
|
||||
|
||||
private final IntentFilter restrictionsFilter =
|
||||
new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
|
||||
|
||||
private final BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() {
|
||||
@Override public void onReceive(Context ctx, Intent intent) {
|
||||
if (ctx != null) {
|
||||
Bundle managedConfig = MainApplication.instance.loadManagedConfig(ctx);
|
||||
|
||||
// Check current configuration settings, change your app's UI and
|
||||
// functionality as necessary.
|
||||
Log.i(TAG, "Managed Configuration Changed");
|
||||
sendConfigChanged(managedConfig);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
||||
MattermostManagedModule managedModule = MattermostManagedModule.getInstance();
|
||||
if (managedModule != null && managedModule.isBlurAppScreenEnabled() && activity != null) {
|
||||
activity.getWindow().setFlags(LayoutParams.FLAG_SECURE,
|
||||
LayoutParams.FLAG_SECURE);
|
||||
}
|
||||
|
||||
Bundle managedConfig = MainApplication.instance.getManagedConfig();
|
||||
if (managedConfig != null && activity != null) {
|
||||
activity.registerReceiver(restrictionsReceiver, restrictionsFilter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {
|
||||
ReactContext ctx = MainApplication.instance.getRunningReactContext();
|
||||
Bundle managedConfig = MainApplication.instance.getManagedConfig();
|
||||
|
||||
if (ctx != null) {
|
||||
Bundle newConfig = MainApplication.instance.loadManagedConfig(ctx);
|
||||
if (!equalBundles(newConfig, managedConfig)) {
|
||||
Log.i(TAG, "onResumed Managed Configuration Changed");
|
||||
sendConfigChanged(newConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(Activity activity) {
|
||||
Bundle managedConfig = MainApplication.instance.getManagedConfig();
|
||||
|
||||
if (managedConfig != null) {
|
||||
try {
|
||||
activity.unregisterReceiver(restrictionsReceiver);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Just ignore this cause the receiver wasn't registered for this activity
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(Activity activity) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(Activity activity) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {
|
||||
}
|
||||
|
||||
private void sendConfigChanged(Bundle config) {
|
||||
Object result = Arguments.fromBundle(config);
|
||||
ReactContext ctx = MainApplication.instance.getRunningReactContext();
|
||||
|
||||
if (ctx != null) {
|
||||
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
.emit("managedConfigDidChange", result);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean equalBundles(Bundle one, Bundle two) {
|
||||
if (one == null || two == null)
|
||||
return false;
|
||||
|
||||
if(one.size() != two.size())
|
||||
return false;
|
||||
|
||||
Set<String> setOne = new ArraySet<String>();
|
||||
setOne.addAll(one.keySet());
|
||||
setOne.addAll(two.keySet());
|
||||
Object valueOne;
|
||||
Object valueTwo;
|
||||
|
||||
for(String key : setOne) {
|
||||
if (!one.containsKey(key) || !two.containsKey(key))
|
||||
return false;
|
||||
|
||||
valueOne = one.get(key);
|
||||
valueTwo = two.get(key);
|
||||
if(valueOne instanceof Bundle && valueTwo instanceof Bundle &&
|
||||
!equalBundles((Bundle) valueOne, (Bundle) valueTwo)) {
|
||||
return false;
|
||||
}
|
||||
else if(valueOne == null) {
|
||||
if(valueTwo != null)
|
||||
return false;
|
||||
}
|
||||
else if(!valueOne.equals(valueTwo))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ public class MattermostManagedModule extends ReactContextBaseJavaModule {
|
|||
@ReactMethod
|
||||
public void getConfig(final Promise promise) {
|
||||
try {
|
||||
Bundle config = NotificationsLifecycleFacade.getInstance().getManagedConfig();
|
||||
Bundle config = MainApplication.instance.getManagedConfig();
|
||||
|
||||
if (config != null) {
|
||||
Object result = Arguments.fromBundle(config);
|
||||
|
|
|
|||
|
|
@ -1,251 +0,0 @@
|
|||
package com.mattermost.rnbeta;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.RestrictionsManager;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.util.ArraySet;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.content.res.Configuration;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
|
||||
import com.reactnativenavigation.NavigationApplication;
|
||||
import com.reactnativenavigation.controllers.ActivityCallbacks;
|
||||
import com.reactnativenavigation.react.ReactGateway;
|
||||
import com.wix.reactnativenotifications.core.AppLifecycleFacade;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
|
||||
public class NotificationsLifecycleFacade extends ActivityCallbacks implements AppLifecycleFacade {
|
||||
private static final String TAG = NotificationsLifecycleFacade.class.getSimpleName();
|
||||
private static NotificationsLifecycleFacade instance;
|
||||
|
||||
private Bundle managedConfig = null;
|
||||
private Activity mVisibleActivity;
|
||||
private Set<AppVisibilityListener> mListeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
private final IntentFilter restrictionsFilter =
|
||||
new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
|
||||
|
||||
private final BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() {
|
||||
@Override public void onReceive(Context context, Intent intent) {
|
||||
if (context != null) {
|
||||
// Get the current configuration bundle
|
||||
RestrictionsManager myRestrictionsMgr =
|
||||
(RestrictionsManager) context
|
||||
.getSystemService(Context.RESTRICTIONS_SERVICE);
|
||||
managedConfig = myRestrictionsMgr.getApplicationRestrictions();
|
||||
|
||||
// Check current configuration settings, change your app's UI and
|
||||
// functionality as necessary.
|
||||
Log.i("ReactNative", "Managed Configuration Changed");
|
||||
sendConfigChanged(managedConfig);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static NotificationsLifecycleFacade getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new NotificationsLifecycleFacade();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
||||
MattermostManagedModule managedModule = MattermostManagedModule.getInstance();
|
||||
if (managedModule != null && managedModule.isBlurAppScreenEnabled() && activity != null) {
|
||||
activity.getWindow().setFlags(LayoutParams.FLAG_SECURE,
|
||||
LayoutParams.FLAG_SECURE);
|
||||
}
|
||||
if (managedConfig != null && managedConfig.size() > 0 && activity != null) {
|
||||
activity.registerReceiver(restrictionsReceiver, restrictionsFilter);
|
||||
}
|
||||
|
||||
if (activity != null) {
|
||||
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {
|
||||
switchToVisible(activity);
|
||||
|
||||
ReactContext ctx = getRunningReactContext();
|
||||
if (managedConfig != null && managedConfig.size() > 0 && ctx != null) {
|
||||
|
||||
RestrictionsManager myRestrictionsMgr =
|
||||
(RestrictionsManager) ctx
|
||||
.getSystemService(Context.RESTRICTIONS_SERVICE);
|
||||
|
||||
Bundle newConfig = myRestrictionsMgr.getApplicationRestrictions();
|
||||
if (!equalBundles(newConfig ,managedConfig)) {
|
||||
Log.i("ReactNative", "onResumed Managed Configuration Changed");
|
||||
managedConfig = newConfig;
|
||||
sendConfigChanged(managedConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(Activity activity) {
|
||||
switchToInvisible(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(Activity activity) {
|
||||
switchToInvisible(activity);
|
||||
if (managedConfig != null && managedConfig.size() > 0) {
|
||||
try {
|
||||
activity.unregisterReceiver(restrictionsReceiver);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Just ignore this cause the receiver wasn't registered for this activity
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {
|
||||
switchToInvisible(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReactInitialized() {
|
||||
return NavigationApplication.instance.isReactContextInitialized();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReactContext getRunningReactContext() {
|
||||
final ReactGateway reactGateway = NavigationApplication.instance.getReactGateway();
|
||||
if (reactGateway == null || !reactGateway.isInitialized()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return reactGateway.getReactContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAppVisible() {
|
||||
return mVisibleActivity != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void addVisibilityListener(AppVisibilityListener listener) {
|
||||
mListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeVisibilityListener(AppVisibilityListener listener) {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
if (mVisibleActivity != null) {
|
||||
Intent intent = new Intent("onConfigurationChanged");
|
||||
intent.putExtra("newConfig", newConfig);
|
||||
mVisibleActivity.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void switchToVisible(Activity activity) {
|
||||
if (mVisibleActivity == null) {
|
||||
mVisibleActivity = activity;
|
||||
Log.v(TAG, "Activity is now visible ("+activity+")");
|
||||
for (AppVisibilityListener listener : mListeners) {
|
||||
listener.onAppVisible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void switchToInvisible(Activity activity) {
|
||||
if (mVisibleActivity == activity) {
|
||||
mVisibleActivity = null;
|
||||
Log.v(TAG, "Activity is now NOT visible ("+activity+")");
|
||||
for (AppVisibilityListener listener : mListeners) {
|
||||
listener.onAppNotVisible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void LoadManagedConfig(ReactContext ctx) {
|
||||
if (ctx != null) {
|
||||
RestrictionsManager myRestrictionsMgr =
|
||||
(RestrictionsManager) ctx
|
||||
.getSystemService(Context.RESTRICTIONS_SERVICE);
|
||||
|
||||
managedConfig = myRestrictionsMgr.getApplicationRestrictions();
|
||||
myRestrictionsMgr = null;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized Bundle getManagedConfig() {
|
||||
if (managedConfig!= null && managedConfig.size() > 0) {
|
||||
return managedConfig;
|
||||
}
|
||||
|
||||
ReactContext ctx = getRunningReactContext();
|
||||
|
||||
if (ctx != null) {
|
||||
LoadManagedConfig(ctx);
|
||||
return managedConfig;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void sendConfigChanged(Bundle config) {
|
||||
Object result = Arguments.fromBundle(config);
|
||||
ReactContext ctx = getRunningReactContext();
|
||||
if (ctx != null) {
|
||||
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).
|
||||
emit("managedConfigDidChange", result);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean equalBundles(Bundle one, Bundle two) {
|
||||
if (one == null || two == null)
|
||||
return false;
|
||||
|
||||
if(one.size() != two.size())
|
||||
return false;
|
||||
|
||||
Set<String> setOne = new ArraySet<String>();
|
||||
setOne.addAll(one.keySet());
|
||||
setOne.addAll(two.keySet());
|
||||
Object valueOne;
|
||||
Object valueTwo;
|
||||
|
||||
for(String key : setOne) {
|
||||
if (!one.containsKey(key) || !two.containsKey(key))
|
||||
return false;
|
||||
|
||||
valueOne = one.get(key);
|
||||
valueTwo = two.get(key);
|
||||
if(valueOne instanceof Bundle && valueTwo instanceof Bundle &&
|
||||
!equalBundles((Bundle) valueOne, (Bundle) valueTwo)) {
|
||||
return false;
|
||||
}
|
||||
else if(valueOne == null) {
|
||||
if(valueTwo != null)
|
||||
return false;
|
||||
}
|
||||
else if(!valueOne.equals(valueTwo))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@ buildscript {
|
|||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.3.1'
|
||||
|
|
@ -37,6 +39,7 @@ subprojects {
|
|||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven {
|
||||
|
|
@ -47,5 +50,8 @@ allprojects {
|
|||
// Local Maven repo containing AARs with JSC library built for Android
|
||||
url "$rootDir/../node_modules/jsc-android/dist"
|
||||
}
|
||||
maven {
|
||||
url "https://jitpack.io"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ project(':jail-monkey').projectDir = new File(rootProject.projectDir, '../node_m
|
|||
include ':react-native-local-auth'
|
||||
project(':react-native-local-auth').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-local-auth/android')
|
||||
include ':react-native-navigation'
|
||||
project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-navigation/android/app/')
|
||||
project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-navigation/lib/android/app/')
|
||||
include ':react-native-image-picker'
|
||||
project(':react-native-image-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-picker/android')
|
||||
include ':react-native-bottom-sheet'
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export default class App {
|
|||
this.startAppFromPushNotification = false;
|
||||
this.isNotificationsConfigured = false;
|
||||
this.allowOtherServers = true;
|
||||
this.appStarted = false;
|
||||
this.canLaunchEntry = true;
|
||||
this.emmEnabled = false;
|
||||
this.performingEMMAuthentication = false;
|
||||
this.translations = null;
|
||||
|
|
@ -276,7 +276,7 @@ export default class App {
|
|||
};
|
||||
|
||||
startApp = () => {
|
||||
if (this.appStarted || this.waitForRehydration) {
|
||||
if (this.waitForRehydration) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -481,15 +481,15 @@ const fromPushNotification = Platform.OS === 'android' && Initialization.replyFr
|
|||
|
||||
if (startedSharedExtension || fromPushNotification) {
|
||||
// Hold on launching Entry screen
|
||||
app.setAppStarted(true);
|
||||
app.canLaunchEntry(false);
|
||||
|
||||
// Listen for when the user opens the app
|
||||
new NativeEventsReceiver().appLaunched(() => {
|
||||
app.setAppStarted(false);
|
||||
app.canLaunchEntry(true);
|
||||
launchEntry();
|
||||
});
|
||||
}
|
||||
|
||||
if (!app.appStarted) {
|
||||
if (app.canLaunchEntry) {
|
||||
launchEntry();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ lane :build do |options|
|
|||
build
|
||||
end
|
||||
|
||||
desc 'Buid the app for Android and iOS unsigned'
|
||||
desc 'Build the app for Android and iOS unsigned'
|
||||
lane :unsigned do
|
||||
configure
|
||||
|
||||
|
|
@ -507,7 +507,7 @@ platform :android do
|
|||
config_mode = ENV['BUILD_FOR_RELEASE'] == 'true' ? 'Release' : 'Debug'
|
||||
|
||||
gradle(
|
||||
task: 'assemble',
|
||||
task: 'app:assemble',
|
||||
build_type: config_mode,
|
||||
project_dir: 'android/'
|
||||
)
|
||||
|
|
|
|||
|
|
@ -115,7 +115,8 @@
|
|||
"test:watch": "jest --watch",
|
||||
"test:coverage": "jest --coverage",
|
||||
"updatesnapshot": "jest --updateSnapshot",
|
||||
"mmjstool": "mmjstool"
|
||||
"mmjstool": "mmjstool",
|
||||
"android": "cd ./android && ./gradlew app:assembleDebug && ./gradlew installDebug"
|
||||
},
|
||||
"rnpm": {
|
||||
"assets": [
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
- remotedev-utils
|
||||
- socketcluster-client
|
||||
- stacktrace-parser
|
||||
- react-navigation
|
||||
8. Change development versions of certain files to production ones:
|
||||
- configureStore.dev.js -> configureStore.prod.js
|
||||
- react/cjs/react.development.js -> react/cjs/react.production.min.js
|
||||
|
|
|
|||
|
|
@ -524,16 +524,28 @@ module.exports = [
|
|||
'node_modules/react-native-linear-gradient/index.android.js',
|
||||
'node_modules/react-native-local-auth/LocalAuth.android.js',
|
||||
'node_modules/react-native-local-auth/index.js',
|
||||
'node_modules/react-native-navigation/src/NativeEventsReceiver.js',
|
||||
'node_modules/react-native-navigation/src/Navigation.js',
|
||||
'node_modules/react-native-navigation/src/PropRegistry.js',
|
||||
'node_modules/react-native-navigation/src/Screen.js',
|
||||
'node_modules/react-native-navigation/src/ScreenVisibilityListener.js',
|
||||
'node_modules/react-native-navigation/src/deprecated/indexDeprecated.android.js',
|
||||
'node_modules/react-native-navigation/src/deprecated/platformSpecificDeprecated.android.js',
|
||||
'node_modules/react-native-navigation/src/index.js',
|
||||
'node_modules/react-native-navigation/src/platformSpecific.android.js',
|
||||
'node_modules/react-native-navigation/src/views/sharedElementTransition.android.js',
|
||||
'node_modules/react-native-navigation/lib/dist/Navigation.js',
|
||||
'node_modules/react-native-navigation/lib/dist/adapters/AppRegistryService.js',
|
||||
'node_modules/react-native-navigation/lib/dist/adapters/AssetResolver.js',
|
||||
'node_modules/react-native-navigation/lib/dist/adapters/ColorService.js',
|
||||
'node_modules/react-native-navigation/lib/dist/adapters/Constants.js',
|
||||
'node_modules/react-native-navigation/lib/dist/adapters/NativeCommandsSender.js',
|
||||
'node_modules/react-native-navigation/lib/dist/adapters/NativeEventsReceiver.js',
|
||||
'node_modules/react-native-navigation/lib/dist/adapters/SharedElement.js',
|
||||
'node_modules/react-native-navigation/lib/dist/adapters/TouchablePreview.js',
|
||||
'node_modules/react-native-navigation/lib/dist/adapters/UniqueIdProvider.js',
|
||||
'node_modules/react-native-navigation/lib/dist/commands/Commands.js',
|
||||
'node_modules/react-native-navigation/lib/dist/commands/LayoutTreeCrawler.js',
|
||||
'node_modules/react-native-navigation/lib/dist/commands/LayoutTreeParser.js',
|
||||
'node_modules/react-native-navigation/lib/dist/commands/OptionsProcessor.js',
|
||||
'node_modules/react-native-navigation/lib/dist/components/ComponentRegistry.js',
|
||||
'node_modules/react-native-navigation/lib/dist/components/ComponentWrapper.js',
|
||||
'node_modules/react-native-navigation/lib/dist/components/Store.js',
|
||||
'node_modules/react-native-navigation/lib/dist/events/CommandsObserver.js',
|
||||
'node_modules/react-native-navigation/lib/dist/events/ComponentEventsObserver.js',
|
||||
'node_modules/react-native-navigation/lib/dist/events/EventsRegistry.js',
|
||||
'node_modules/react-native-navigation/lib/dist/index.js',
|
||||
'node_modules/react-native-navigation/lib/dist/interfaces/Options.js',
|
||||
'node_modules/react-native-notifications/index.android.js',
|
||||
'node_modules/react-native-notifications/notification.android.js',
|
||||
'node_modules/react-native/Libraries/Animated/src/Animated.js',
|
||||
|
|
@ -742,4 +754,4 @@ module.exports = [
|
|||
'node_modules/symbol-observable/lib/ponyfill.js',
|
||||
'node_modules/tinycolor2/tinycolor.js',
|
||||
'node_modules/url-parse/index.js',
|
||||
];
|
||||
];
|
||||
|
|
@ -500,16 +500,28 @@ module.exports = ['./node_modules/app/app.js',
|
|||
'./node_modules/node_modules/react-native-linear-gradient/index.android.js',
|
||||
'./node_modules/node_modules/react-native-local-auth/LocalAuth.android.js',
|
||||
'./node_modules/node_modules/react-native-local-auth/index.js',
|
||||
'./node_modules/node_modules/react-native-navigation/src/NativeEventsReceiver.js',
|
||||
'./node_modules/node_modules/react-native-navigation/src/Navigation.js',
|
||||
'./node_modules/node_modules/react-native-navigation/src/PropRegistry.js',
|
||||
'./node_modules/node_modules/react-native-navigation/src/Screen.js',
|
||||
'./node_modules/node_modules/react-native-navigation/src/ScreenVisibilityListener.js',
|
||||
'./node_modules/node_modules/react-native-navigation/src/deprecated/indexDeprecated.android.js',
|
||||
'./node_modules/node_modules/react-native-navigation/src/deprecated/platformSpecificDeprecated.android.js',
|
||||
'./node_modules/node_modules/react-native-navigation/src/index.js',
|
||||
'./node_modules/node_modules/react-native-navigation/src/platformSpecific.android.js',
|
||||
'./node_modules/node_modules/react-native-navigation/src/views/sharedElementTransition.android.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/Navigation.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/adapters/AppRegistryService.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/adapters/AssetResolver.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/adapters/ColorService.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/adapters/Constants.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/adapters/NativeCommandsSender.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/adapters/NativeEventsReceiver.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/adapters/SharedElement.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/adapters/TouchablePreview.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/adapters/UniqueIdProvider.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/commands/Commands.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/commands/LayoutTreeCrawler.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/commands/LayoutTreeParser.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/commands/OptionsProcessor.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/components/ComponentRegistry.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/components/ComponentWrapper.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/components/Store.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/events/CommandsObserver.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/events/ComponentEventsObserver.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/events/EventsRegistry.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/index.js',
|
||||
'./node_modules/node_modules/react-native-navigation/lib/dist/interfaces/Options.js',
|
||||
'./node_modules/node_modules/react-native-notifications/index.android.js',
|
||||
'./node_modules/node_modules/react-native-notifications/notification.android.js',
|
||||
'./node_modules/node_modules/react-native/Libraries/Animated/src/Animated.js',
|
||||
|
|
|
|||
Loading…
Reference in a new issue