diff --git a/native/keyboard/keyboard-state-container.react.js b/native/keyboard/keyboard-state-container.react.js --- a/native/keyboard/keyboard-state-container.react.js +++ b/native/keyboard/keyboard-state-container.react.js @@ -1,5 +1,6 @@ // @flow +import * as MediaLibrary from 'expo-media-library'; import * as React from 'react'; import { Platform } from 'react-native'; import { KeyboardUtils } from 'react-native-keyboard-input'; @@ -68,6 +69,15 @@ } if (this.state.mediaGalleryOpen && !prevState.mediaGalleryOpen) { void (async () => { + if (Platform.OS === 'android') { + // The promise returned from MediaLibrary.requestPermissionsAsync + // never resolves on Android if it's invoked from + // MediaGalleryKeyboard, which runs in a special environment via + // react-native-keyboard-input. To get around this, we invoke it + // here, and then use MediaLibrary.getPermissionsAsync in + // MediaGalleryKeyboard + void MediaLibrary.requestPermissionsAsync(); + } await sleep(tabBarAnimationDuration); await waitForInteractions(); this.setState({ renderKeyboardInputHost: true }); diff --git a/native/media/media-gallery-keyboard.react.js b/native/media/media-gallery-keyboard.react.js --- a/native/media/media-gallery-keyboard.react.js +++ b/native/media/media-gallery-keyboard.react.js @@ -419,7 +419,14 @@ }; async getPermissions(): Promise { - const { granted } = await MediaLibrary.requestPermissionsAsync(); + let granted = false; + if (Platform.OS === 'android') { + const result = await MediaLibrary.getPermissionsAsync(); + granted = result.granted; + } else { + const result = await MediaLibrary.requestPermissionsAsync(); + granted = result.granted; + } if (!granted) { this.guardedSetState({ error: "don't have permission :(" }); }