Skip to content

Commit d3ff62c

Browse files
Abbondanzofacebook-github-bot
authored andcommitted
Resolve sendIntent call, reject on exception thrown
Summary: Promises created from `Linking.sendIntent` calls never resolve, leaving them dangling. This change fixes the issue in two spots: 1. By calling promise.resolve directly after the startActivity call 1. By wrapping startActivity in a try/catch so any exceptions thrown are forwarded to the promise as a rejection Changelog: [Android][Fixed] - Ensure Linking.sendIntent promises resolve or reject Differential Revision: D72606918
1 parent 22eb457 commit d3ff62c

File tree

2 files changed

+54
-41
lines changed

2 files changed

+54
-41
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.kt

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -202,39 +202,44 @@ public open class IntentModule(reactContext: ReactApplicationContext) :
202202
return
203203
}
204204

205-
if (extras != null) {
206-
for (i in 0..<extras.size()) {
207-
val map = extras.getMap(i) ?: continue
208-
val name = map.getString("key")
209-
val type = map.getType(EXTRA_MAP_KEY_FOR_VALUE)
210-
211-
when (type) {
212-
ReadableType.String -> {
213-
intent.putExtra(name, map.getString(EXTRA_MAP_KEY_FOR_VALUE))
214-
}
205+
try {
206+
if (extras != null) {
207+
for (i in 0..<extras.size()) {
208+
val map = extras.getMap(i) ?: continue
209+
val name = map.getString("key")
210+
val type = map.getType(EXTRA_MAP_KEY_FOR_VALUE)
211+
212+
when (type) {
213+
ReadableType.String -> {
214+
intent.putExtra(name, map.getString(EXTRA_MAP_KEY_FOR_VALUE))
215+
}
215216

216-
ReadableType.Number -> {
217-
// We cannot know from JS if is an Integer or Double
218-
// See: https://github.com/facebook/react-native/issues/4141
219-
// We might need to find a workaround if this is really an issue
220-
val number = map.getDouble(EXTRA_MAP_KEY_FOR_VALUE)
221-
intent.putExtra(name, number)
222-
}
217+
ReadableType.Number -> {
218+
// We cannot know from JS if is an Integer or Double
219+
// See: https://github.com/facebook/react-native/issues/4141
220+
// We might need to find a workaround if this is really an issue
221+
val number = map.getDouble(EXTRA_MAP_KEY_FOR_VALUE)
222+
intent.putExtra(name, number)
223+
}
223224

224-
ReadableType.Boolean -> {
225-
intent.putExtra(name, map.getBoolean(EXTRA_MAP_KEY_FOR_VALUE))
226-
}
225+
ReadableType.Boolean -> {
226+
intent.putExtra(name, map.getBoolean(EXTRA_MAP_KEY_FOR_VALUE))
227+
}
227228

228-
else -> {
229-
promise.reject(
230-
JSApplicationIllegalArgumentException("Extra type for $name not supported."))
231-
return
229+
else -> {
230+
promise.reject(
231+
JSApplicationIllegalArgumentException("Extra type for $name not supported."))
232+
return
233+
}
232234
}
233235
}
234236
}
235-
}
236237

237-
sendOSIntent(intent, true)
238+
sendOSIntent(intent, true)
239+
promise.resolve(null)
240+
} catch (e: Exception) {
241+
promise.reject(e)
242+
}
238243
}
239244

240245
private fun sendOSIntent(intent: Intent, useNewTaskFlag: Boolean) {

packages/rn-tester/js/examples/Linking/LinkingExample.js

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,30 @@ class OpenSettingsExample extends React.Component<Props, any> {
6464
}
6565
}
6666

67-
class SendIntentButton extends React.Component<Props> {
68-
handleIntent = async () => {
67+
const SendIntentButton = ({action, extras}: Props) => {
68+
const [isOpeningIntent, setIsOpeningIntent] = React.useState(false);
69+
70+
const handleIntent = async () => {
71+
setIsOpeningIntent(true);
6972
try {
70-
await Linking.sendIntent(this.props.action, this.props.extras);
73+
await Linking.sendIntent(action, extras);
7174
} catch (e) {
7275
ToastAndroid.show(e.message, ToastAndroid.LONG);
76+
} finally {
77+
setIsOpeningIntent(false);
7378
}
7479
};
7580

76-
render() {
77-
return (
78-
<TouchableOpacity onPress={this.handleIntent}>
79-
<View style={[styles.button, styles.buttonIntent]}>
80-
<RNTesterText style={styles.text}>{this.props.action}</RNTesterText>
81-
</View>
82-
</TouchableOpacity>
83-
);
84-
}
85-
}
81+
return (
82+
<TouchableOpacity onPress={handleIntent}>
83+
<View style={[styles.button, styles.buttonIntent]}>
84+
<RNTesterText style={styles.text}>
85+
{isOpeningIntent ? `Opening ${action}...` : action}
86+
</RNTesterText>
87+
</View>
88+
</TouchableOpacity>
89+
);
90+
};
8691

8792
class IntentAndroidExample extends React.Component {
8893
render() {
@@ -100,12 +105,15 @@ class IntentAndroidExample extends React.Component {
100105
<RNTesterBlock title="Send intents">
101106
<SendIntentButton action="android.intent.action.POWER_USAGE_SUMMARY" />
102107
<RNTesterText style={styles.textSeparator}>
103-
Next one will crash if Facebook app is not installed.
108+
Next one will throw an exception if Facebook app is not installed.
104109
</RNTesterText>
105110
<SendIntentButton
106111
action="android.settings.APP_NOTIFICATION_SETTINGS"
107112
extras={[
108-
{'android.provider.extra.APP_PACKAGE': 'com.facebook.katana'},
113+
{
114+
key: 'android.provider.extra.APP_PACKAGE',
115+
value: 'com.facebook.katana',
116+
},
109117
]}
110118
/>
111119
</RNTesterBlock>

0 commit comments

Comments
 (0)