expo-dev-launcher 55.0.28 → 55.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/debug/java/com/facebook/react/devsupport/DevLauncherDevServerHelper.kt +6 -8
  4. package/android/src/debug/java/expo/modules/devlauncher/DevLauncherController.kt +2 -2
  5. package/android/src/debug/java/expo/modules/devlauncher/compose/routes/Profile.kt +1 -1
  6. package/android/src/debug/java/expo/modules/devlauncher/compose/screens/BranchesScreen.kt +6 -6
  7. package/android/src/debug/java/expo/modules/devlauncher/compose/screens/ErrorScreen.kt +2 -2
  8. package/android/src/debug/java/expo/modules/devlauncher/compose/screens/SettingsScreen.kt +1 -1
  9. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/AccountSelector.kt +1 -1
  10. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/SignUp.kt +2 -2
  11. package/android/src/debug/java/expo/modules/devlauncher/services/HttpClientService.kt +2 -2
  12. package/ios/EXDevLauncherController.m +5 -0
  13. package/ios/SwiftUI/AccountSheet.swift +3 -3
  14. package/ios/SwiftUI/ErrorView.swift +1 -1
  15. package/ios/SwiftUI/HomeTabView.swift +0 -4
  16. package/ios/SwiftUI/SettingsTabView.swift +1 -6
  17. package/ios/SwiftUI/UpdatesTab/NotSignedInView.swift +3 -7
  18. package/ios/SwiftUI/UpdatesTab/NotUsingUpdatesView.swift +0 -4
  19. package/ios/SwiftUI/UpdatesTab/UpdatesListView.swift +0 -4
  20. package/ios/SwiftUI/UpdatesTab/UpdatesTabView.swift +0 -4
  21. package/package.json +4 -4
  22. package/plugin/build/pluginConfig.d.ts +6 -0
  23. package/plugin/build/pluginConfig.js +12 -0
  24. package/plugin/build/withDevLauncher.js +15 -0
  25. package/plugin/src/pluginConfig.ts +18 -0
  26. package/plugin/src/withDevLauncher.ts +22 -0
package/CHANGELOG.md CHANGED
@@ -10,6 +10,23 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 55.0.30 — 2026-05-01
14
+
15
+ ### 🎉 New features
16
+
17
+ - [plugin] Add option to disable tools button by default. ([#44251](https://github.com/expo/expo/pull/44251) by [@alanjhughes](https://github.com/alanjhughes))
18
+
19
+ ## 55.0.29 — 2026-04-21
20
+
21
+ ### 🐛 Bug fixes
22
+
23
+ - [Android] Use `OkHttpClientProvider` instead of bare `OkHttpClient` so custom interceptors are applied. ([#44798](https://github.com/expo/expo/pull/44798) by [@fabriziocucci](https://github.com/fabriziocucci))
24
+ - [iOS] Fix JSI crash (`EXC_BAD_ACCESS` in `jsi::Pointer::~Pointer`) when an embedded `main.jsbundle` and dev-launcher race on startup. ([#44799](https://github.com/expo/expo/pull/44799) by [@fabriziocucci](https://github.com/fabriziocucci))
25
+
26
+ ### 💡 Others
27
+
28
+ - Align dev launcher labels across iOS and Android. ([#44720](https://github.com/expo/expo/pull/44720) by [@vonovak](https://github.com/vonovak))
29
+
13
30
  ## 55.0.28 — 2026-04-11
14
31
 
15
32
  ### 🐛 Bug fixes
@@ -26,13 +26,13 @@ expoModule {
26
26
  }
27
27
 
28
28
  group = "host.exp.exponent"
29
- version = "55.0.28"
29
+ version = "55.0.30"
30
30
 
31
31
  android {
32
32
  namespace "expo.modules.devlauncher"
33
33
  defaultConfig {
34
34
  versionCode 9
35
- versionName "55.0.28"
35
+ versionName "55.0.30"
36
36
  }
37
37
 
38
38
  buildTypes {
@@ -2,13 +2,13 @@ package com.facebook.react.devsupport
2
2
 
3
3
  import android.content.Context
4
4
  import androidx.core.net.toUri
5
+ import com.facebook.react.modules.network.OkHttpClientProvider
5
6
  import com.facebook.react.devsupport.interfaces.PackagerStatusCallback
6
7
  import com.facebook.react.modules.debug.interfaces.DeveloperSettings
7
8
  import com.facebook.react.packagerconnection.PackagerConnectionSettings
8
9
  import expo.modules.devlauncher.launcher.DevLauncherControllerInterface
9
10
  import okhttp3.Call
10
11
  import okhttp3.Callback
11
- import okhttp3.OkHttpClient
12
12
  import okhttp3.Request
13
13
  import okhttp3.Response
14
14
  import java.io.IOException
@@ -25,13 +25,11 @@ class DevLauncherDevServerHelper(
25
25
  packagerConnection: PackagerConnectionSettings
26
26
  ) : DevServerHelper(devSettings, context, packagerConnection) {
27
27
 
28
- private val httpClient: OkHttpClient by lazy {
29
- OkHttpClient.Builder()
30
- .connectTimeout(HTTP_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS)
31
- .readTimeout(0, TimeUnit.MILLISECONDS)
32
- .writeTimeout(0, TimeUnit.MILLISECONDS)
33
- .build()
34
- }
28
+ private val httpClient = OkHttpClientProvider.getOkHttpClient().newBuilder()
29
+ .connectTimeout(HTTP_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS)
30
+ .readTimeout(0, TimeUnit.MILLISECONDS)
31
+ .writeTimeout(0, TimeUnit.MILLISECONDS)
32
+ .build()
35
33
 
36
34
  override fun getDevServerBundleURL(jsModulePath: String): String {
37
35
  return controller?.manifest?.getBundleURL() ?: super.getDevServerBundleURL(jsModulePath)
@@ -16,6 +16,7 @@ import com.facebook.react.ReactApplication
16
16
  import com.facebook.react.ReactHost
17
17
  import com.facebook.react.ReactPackage
18
18
  import com.facebook.react.bridge.ReactContext
19
+ import com.facebook.react.modules.network.OkHttpClientProvider
19
20
  import expo.modules.devlauncher.helpers.DevLauncherInstallationIDHelper
20
21
  import expo.modules.devlauncher.helpers.DevLauncherMetadataHelper
21
22
  import expo.modules.devlauncher.helpers.DevLauncherUrl
@@ -46,7 +47,6 @@ import expo.modules.updatesinterface.UpdatesDevLauncherInterface
46
47
  import kotlinx.coroutines.CoroutineScope
47
48
  import kotlinx.coroutines.Dispatchers
48
49
  import kotlinx.coroutines.launch
49
- import okhttp3.OkHttpClient
50
50
 
51
51
  private const val NEW_ACTIVITY_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK or
52
52
  Intent.FLAG_ACTIVITY_CLEAR_TASK or
@@ -64,7 +64,7 @@ class DevLauncherController private constructor(
64
64
  val nullableContext: Context?
65
65
  get() = contextHolder.get()
66
66
 
67
- val httpClient by lazy { OkHttpClient() }
67
+ val httpClient by lazy { OkHttpClientProvider.getOkHttpClient() }
68
68
  val lifecycle by lazy { DevLauncherLifecycle() }
69
69
  private val pendingIntentRegistry by lazy { DevLauncherIntentRegistry() }
70
70
  private val installationIDHelper by lazy { DevLauncherInstallationIDHelper() }
@@ -121,7 +121,7 @@ private fun LoggedOut(authLauncher: ManagedActivityResultLauncher<AuthRequestTyp
121
121
  }
122
122
 
123
123
  NewText(
124
- "Login or create an account to view local\ndevelopment servers and more",
124
+ "Log in or create an account to view local\ndevelopment servers and more",
125
125
  style = NewAppTheme.font.sm.merge(
126
126
  lineHeight = 19.sp,
127
127
  textAlign = TextAlign.Center
@@ -79,7 +79,7 @@ private fun BranchBadge(
79
79
  }
80
80
 
81
81
  @Composable
82
- private fun NeedToSingInComponent(
82
+ private fun NeedToSignInComponent(
83
83
  onProfileClick: () -> Unit = {}
84
84
  ) {
85
85
  Box(
@@ -93,7 +93,7 @@ private fun NeedToSingInComponent(
93
93
  ) {
94
94
  Icon(
95
95
  painter = painterResource(R.drawable.log_in),
96
- contentDescription = "Sign In Icon",
96
+ contentDescription = "Log in icon",
97
97
  tint = NewAppTheme.colors.icon.info
98
98
  )
99
99
 
@@ -103,7 +103,7 @@ private fun NeedToSingInComponent(
103
103
  modifier = Modifier.fillMaxWidth()
104
104
  ) {
105
105
  NewText(
106
- "Sign in to view updates",
106
+ "Log in to view updates",
107
107
  style = NewAppTheme.font.lg.merge(
108
108
  fontWeight = FontWeight.SemiBold,
109
109
  lineHeight = 20.sp,
@@ -112,7 +112,7 @@ private fun NeedToSingInComponent(
112
112
  )
113
113
 
114
114
  NewText(
115
- "Sign in to your Expo account to see available\nEAS updates for this project.",
115
+ "Log in to your Expo account to see available\nupdates for this project.",
116
116
  style = NewAppTheme.font.sm.merge(
117
117
  lineHeight = 19.6.sp,
118
118
  textAlign = TextAlign.Center
@@ -122,7 +122,7 @@ private fun NeedToSingInComponent(
122
122
  }
123
123
 
124
124
  ActionButton(
125
- "Sign In",
125
+ "Log in",
126
126
  foreground = Color.White,
127
127
  background = Color.Black,
128
128
  fill = false,
@@ -154,7 +154,7 @@ fun BranchesScreen(
154
154
  }
155
155
 
156
156
  if (needToSignIn) {
157
- NeedToSingInComponent(onProfileClick)
157
+ NeedToSignInComponent(onProfileClick)
158
158
  return@Column
159
159
  }
160
160
 
@@ -43,7 +43,7 @@ fun ErrorScreen(
43
43
  )
44
44
  )
45
45
 
46
- NewText("This development build encountered the following error.")
46
+ NewText("This development build encountered the following error:")
47
47
  }
48
48
 
49
49
  StackTrace(
@@ -70,7 +70,7 @@ fun ErrorScreen(
70
70
  )
71
71
 
72
72
  ActionButton(
73
- "Go To Home",
73
+ "Go home",
74
74
  foreground = NewAppTheme.colors.buttons.secondary.foreground,
75
75
  background = NewAppTheme.colors.buttons.secondary.background,
76
76
  modifier = Modifier.padding(vertical = NewAppTheme.spacing.`2`),
@@ -152,7 +152,7 @@ private fun MenuGesturesSection(state: SettingsState, onAction: (SettingsAction)
152
152
  },
153
153
  content = {
154
154
  NewText(
155
- text = "3 fingers long press"
155
+ text = "Three-finger long-press"
156
156
  )
157
157
  },
158
158
  rightComponent = {
@@ -72,7 +72,7 @@ fun AccountSelector(
72
72
  }
73
73
 
74
74
  ActionButton(
75
- "Log Out",
75
+ "Log out",
76
76
  foreground = Color.White,
77
77
  background = Color.Black,
78
78
  modifier = Modifier.padding(NewAppTheme.spacing.`3`),
@@ -18,7 +18,7 @@ fun SignUp(
18
18
  verticalArrangement = Arrangement.spacedBy(NewAppTheme.spacing.`2`)
19
19
  ) {
20
20
  ActionButton(
21
- "Login",
21
+ "Log in",
22
22
  foreground = Color.White,
23
23
  background = Color.Black,
24
24
  modifier = Modifier.padding(NewAppTheme.spacing.`3`),
@@ -26,7 +26,7 @@ fun SignUp(
26
26
  )
27
27
 
28
28
  ActionButton(
29
- "Sign Up",
29
+ "Sign up",
30
30
  foreground = NewAppTheme.colors.text.secondary,
31
31
  background = NewAppTheme.colors.background.element,
32
32
  modifier = Modifier.padding(NewAppTheme.spacing.`3`),
@@ -1,8 +1,8 @@
1
1
  package expo.modules.devlauncher.services
2
2
 
3
3
  import androidx.core.net.toUri
4
+ import com.facebook.react.modules.network.OkHttpClientProvider
4
5
  import expo.modules.devlauncher.helpers.await
5
- import okhttp3.OkHttpClient
6
6
  import okhttp3.Request
7
7
  import org.json.JSONObject
8
8
 
@@ -32,7 +32,7 @@ data class DevelopmentSession(
32
32
  class HttpClientService() {
33
33
  private var currentSession: String? = null
34
34
 
35
- val httpClient = OkHttpClient.Builder()
35
+ val httpClient = OkHttpClientProvider.getOkHttpClient().newBuilder()
36
36
  .addInterceptor { chain ->
37
37
  val originalRequest = chain.request()
38
38
  val session = currentSession
@@ -196,6 +196,11 @@ static const NSTimeInterval EXDevLauncherDefaultRequestTimeout = 10.0;
196
196
  });
197
197
  };
198
198
 
199
+ if ([[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"] != nil) {
200
+ [self navigateToLauncher];
201
+ return;
202
+ }
203
+
199
204
  #if TARGET_OS_SIMULATOR
200
205
  BOOL hasGrantedNetworkPermission = YES;
201
206
  #else
@@ -80,7 +80,7 @@ struct AccountSheet: View {
80
80
  viewModel.signOut()
81
81
  }
82
82
  label: {
83
- Text("Logout")
83
+ Text("Log out")
84
84
  .font(.headline)
85
85
  .fontWeight(.bold)
86
86
  .foregroundColor(.white)
@@ -126,7 +126,7 @@ struct AccountSheet: View {
126
126
  .transition(.scale.combined(with: .opacity))
127
127
  }
128
128
 
129
- Text("Log In")
129
+ Text("Log in")
130
130
  .font(.headline)
131
131
  .fontWeight(.semibold)
132
132
  }
@@ -147,7 +147,7 @@ struct AccountSheet: View {
147
147
  }
148
148
  }
149
149
  label: {
150
- Text("Sign Up")
150
+ Text("Sign up")
151
151
  .font(.headline)
152
152
  .fontWeight(.semibold)
153
153
  .foregroundColor(.black.opacity(0.7))
@@ -68,7 +68,7 @@ struct ErrorView: View {
68
68
  }
69
69
 
70
70
  Button(action: onGoHome) {
71
- Text("Go to home")
71
+ Text("Go home")
72
72
  .font(.headline)
73
73
  .foregroundColor(.black)
74
74
  .frame(maxWidth: .infinity)
@@ -116,8 +116,4 @@ struct NetworkPermissionsBanner: View {
116
116
  .cornerRadius(18)
117
117
  }
118
118
  }
119
-
120
- #Preview {
121
- HomeTabView()
122
- }
123
119
  // swiftlint:enable closure_body_length
@@ -119,7 +119,7 @@ struct SettingsTabView: View {
119
119
  .resizable()
120
120
  .frame(width: 24, height: 24)
121
121
  .opacity(0.6)
122
- Toggle("Shake Device", isOn: $viewModel.shakeDevice)
122
+ Toggle("Shake device", isOn: $viewModel.shakeDevice)
123
123
  }
124
124
  .padding()
125
125
 
@@ -271,8 +271,3 @@ struct SettingsTabView: View {
271
271
  }
272
272
  #endif
273
273
  }
274
-
275
- #Preview {
276
- SettingsTabView()
277
- .environmentObject(DevLauncherViewModel())
278
- }
@@ -13,12 +13,12 @@ struct NotSignedInView: View {
13
13
  .foregroundColor(.blue)
14
14
 
15
15
  VStack(spacing: 8) {
16
- Text("Sign in to view updates")
16
+ Text("Log in to view updates")
17
17
  .font(.title3)
18
18
  .fontWeight(.semibold)
19
19
  .multilineTextAlignment(.center)
20
20
 
21
- Text("Sign in to your Expo account to see available EAS Updates for this project.")
21
+ Text("Log in to your Expo account to see available EAS updates for this project.")
22
22
  .font(.system(size: 14))
23
23
  .multilineTextAlignment(.center)
24
24
  .foregroundStyle(.secondary)
@@ -27,7 +27,7 @@ struct NotSignedInView: View {
27
27
  Button {
28
28
  navigation.showUserProfile()
29
29
  } label: {
30
- Text("Sign in")
30
+ Text("Log in")
31
31
  .padding(.horizontal, 16)
32
32
  .padding(.vertical, 8)
33
33
  .background(Color.black)
@@ -39,7 +39,3 @@ struct NotSignedInView: View {
39
39
  .frame(maxWidth: .infinity, maxHeight: .infinity)
40
40
  }
41
41
  }
42
-
43
- #Preview {
44
- NotSignedInView()
45
- }
@@ -32,7 +32,3 @@ struct NotUsingUpdatesView: View {
32
32
  }
33
33
  }
34
34
  }
35
-
36
- #Preview {
37
- NotUsingUpdatesView()
38
- }
@@ -190,8 +190,4 @@ struct UpdatesListView: View {
190
190
  }
191
191
  }
192
192
  }
193
-
194
- #Preview {
195
- UpdatesListView()
196
- }
197
193
  // swiftlint:enable closure_body_length
@@ -25,7 +25,3 @@ struct UpdatesTabView: View {
25
25
  #endif
26
26
  }
27
27
  }
28
-
29
- #Preview {
30
- UpdatesTabView()
31
- }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-dev-launcher",
3
3
  "title": "Expo Development Launcher",
4
- "version": "55.0.28",
4
+ "version": "55.0.30",
5
5
  "description": "Pre-release version of the Expo development launcher package for testing.",
6
6
  "repository": {
7
7
  "type": "git",
@@ -16,11 +16,11 @@
16
16
  "homepage": "https://docs.expo.dev",
17
17
  "dependencies": {
18
18
  "@expo/schema-utils": "^55.0.3",
19
- "expo-dev-menu": "55.0.23",
20
- "expo-manifests": "~55.0.15"
19
+ "expo-dev-menu": "55.0.25",
20
+ "expo-manifests": "~55.0.16"
21
21
  },
22
22
  "peerDependencies": {
23
23
  "expo": "*"
24
24
  },
25
- "gitHead": "9501516951885373128fc20687b17775c8275453"
25
+ "gitHead": "1528d89d7b1076a4d8b88eb7b1e9e9c4e8c8f9d8"
26
26
  }
@@ -36,6 +36,12 @@ export type PluginConfigOptions = {
36
36
  * @deprecated use the `launchMode` property instead
37
37
  */
38
38
  launchModeExperimental?: 'most-recent' | 'launcher';
39
+ /**
40
+ * Whether to show the tools button by default.
41
+ *
42
+ * @default true
43
+ */
44
+ toolsButton?: boolean;
39
45
  };
40
46
  /**
41
47
  * @ignore
@@ -16,6 +16,10 @@ const schema = {
16
16
  enum: ['most-recent', 'launcher'],
17
17
  nullable: true,
18
18
  },
19
+ toolsButton: {
20
+ type: 'boolean',
21
+ nullable: true,
22
+ },
19
23
  android: {
20
24
  type: 'object',
21
25
  properties: {
@@ -29,6 +33,10 @@ const schema = {
29
33
  enum: ['most-recent', 'launcher'],
30
34
  nullable: true,
31
35
  },
36
+ toolsButton: {
37
+ type: 'boolean',
38
+ nullable: true,
39
+ },
32
40
  },
33
41
  nullable: true,
34
42
  },
@@ -45,6 +53,10 @@ const schema = {
45
53
  enum: ['most-recent', 'launcher'],
46
54
  nullable: true,
47
55
  },
56
+ toolsButton: {
57
+ type: 'boolean',
58
+ nullable: true,
59
+ },
48
60
  },
49
61
  nullable: true,
50
62
  },
@@ -102,6 +102,13 @@ exports.default = (0, config_plugins_1.createRunOncePlugin)((config, props = {})
102
102
  return config;
103
103
  });
104
104
  }
105
+ const iOSToolsButton = props.ios?.toolsButton ?? props.toolsButton;
106
+ if (iOSToolsButton !== undefined) {
107
+ config = (0, config_plugins_1.withInfoPlist)(config, (config) => {
108
+ config.modResults['EXDevMenuShowFloatingActionButton'] = iOSToolsButton;
109
+ return config;
110
+ });
111
+ }
105
112
  const androidLaunchMode = props.android?.launchMode ??
106
113
  props.launchMode ??
107
114
  props.android?.launchModeExperimental ??
@@ -113,6 +120,14 @@ exports.default = (0, config_plugins_1.createRunOncePlugin)((config, props = {})
113
120
  return config;
114
121
  });
115
122
  }
123
+ const androidToolsButton = props.android?.toolsButton ?? props.toolsButton;
124
+ if (androidToolsButton !== undefined) {
125
+ config = (0, config_plugins_1.withAndroidManifest)(config, (config) => {
126
+ const mainApplication = config_plugins_1.AndroidConfig.Manifest.getMainApplicationOrThrow(config.modResults);
127
+ config_plugins_1.AndroidConfig.Manifest.addMetaDataItemToMainApplication(mainApplication, 'EXDevMenuShowFloatingActionButton', String(androidToolsButton));
128
+ return config;
129
+ });
130
+ }
116
131
  config = withLocalNetworkPermission(config);
117
132
  config = withStripLocalNetworkKeysForRelease(config);
118
133
  return config;
@@ -40,6 +40,12 @@ export type PluginConfigOptions = {
40
40
  * @deprecated use the `launchMode` property instead
41
41
  */
42
42
  launchModeExperimental?: 'most-recent' | 'launcher';
43
+ /**
44
+ * Whether to show the tools button by default.
45
+ *
46
+ * @default true
47
+ */
48
+ toolsButton?: boolean;
43
49
  };
44
50
 
45
51
  const schema: JSONSchema<PluginConfigType> = {
@@ -56,6 +62,10 @@ const schema: JSONSchema<PluginConfigType> = {
56
62
  enum: ['most-recent', 'launcher'],
57
63
  nullable: true,
58
64
  },
65
+ toolsButton: {
66
+ type: 'boolean',
67
+ nullable: true,
68
+ },
59
69
  android: {
60
70
  type: 'object',
61
71
  properties: {
@@ -69,6 +79,10 @@ const schema: JSONSchema<PluginConfigType> = {
69
79
  enum: ['most-recent', 'launcher'],
70
80
  nullable: true,
71
81
  },
82
+ toolsButton: {
83
+ type: 'boolean',
84
+ nullable: true,
85
+ },
72
86
  },
73
87
  nullable: true,
74
88
  },
@@ -85,6 +99,10 @@ const schema: JSONSchema<PluginConfigType> = {
85
99
  enum: ['most-recent', 'launcher'],
86
100
  nullable: true,
87
101
  },
102
+ toolsButton: {
103
+ type: 'boolean',
104
+ nullable: true,
105
+ },
88
106
  },
89
107
  nullable: true,
90
108
  },
@@ -130,6 +130,14 @@ export default createRunOncePlugin<PluginConfigType>(
130
130
  });
131
131
  }
132
132
 
133
+ const iOSToolsButton = props.ios?.toolsButton ?? props.toolsButton;
134
+ if (iOSToolsButton !== undefined) {
135
+ config = withInfoPlist(config, (config) => {
136
+ config.modResults['EXDevMenuShowFloatingActionButton'] = iOSToolsButton;
137
+ return config;
138
+ });
139
+ }
140
+
133
141
  const androidLaunchMode =
134
142
  props.android?.launchMode ??
135
143
  props.launchMode ??
@@ -148,6 +156,20 @@ export default createRunOncePlugin<PluginConfigType>(
148
156
  });
149
157
  }
150
158
 
159
+ const androidToolsButton = props.android?.toolsButton ?? props.toolsButton;
160
+ if (androidToolsButton !== undefined) {
161
+ config = withAndroidManifest(config, (config) => {
162
+ const mainApplication = AndroidConfig.Manifest.getMainApplicationOrThrow(config.modResults);
163
+
164
+ AndroidConfig.Manifest.addMetaDataItemToMainApplication(
165
+ mainApplication,
166
+ 'EXDevMenuShowFloatingActionButton',
167
+ String(androidToolsButton)
168
+ );
169
+ return config;
170
+ });
171
+ }
172
+
151
173
  config = withLocalNetworkPermission(config);
152
174
  config = withStripLocalNetworkKeysForRelease(config);
153
175