Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions package/src/expo-plugin/@types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,26 @@ export type ConfigProps = {
* @default false
*/
enableCodeScanner?: boolean
/**
* Android Only
* Whether to require the camera through Androids uses-feature flag.
*
* When set to `true`, the app will only be available in Play Store for phones with a camera.
* When set to `false`, the feature will not be required, and the app will be discoverable for devices without a camera.
* If it is `undefined` or `null`, the uses-feature flag will not be added to the AndroidManifest.
*
* @default undefined
*/
requiresCamera?: boolean | null
/**
* Android Only
* Whether to require the microphone through Androids uses-feature flag.
*
* When set to `true`, the app will only be available in Play Store for phones with a microphone.
* When set to `false`, the feature will not be required, and the app will be discoverable for devices without a microphone.
* If it is `undefined` or `null`, the uses-feature flag will not be added to the AndroidManifest.
*
* @default undefined
*/
requiresMicrophone?: boolean | null
}
19 changes: 19 additions & 0 deletions package/src/expo-plugin/withUsesFeatureAndroid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { ConfigPlugin } from '@expo/config-plugins'
import { withAndroidManifest } from '@expo/config-plugins'

export const withUsesFeatureAndroid: ConfigPlugin<[string, boolean]> = (c, [featureName, featureIsRequired]) => {
return withAndroidManifest(c, (config) => {
if (!Array.isArray(config.modResults.manifest['uses-feature'])) config.modResults.manifest['uses-feature'] = []

if (config.modResults.manifest['uses-feature'].find((item) => item.$['android:name'] === featureName) == null) {
config.modResults.manifest['uses-feature'].push({
$: {
'android:name': featureName,
'android:required': featureIsRequired ? 'true' : 'false',
},
})
}

return config
})
}
9 changes: 9 additions & 0 deletions package/src/expo-plugin/withVisionCamera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { withPlugins, AndroidConfig, createRunOncePlugin } from '@expo/config-pl
import { withEnableFrameProcessorsAndroid } from './withEnableFrameProcessorsAndroid'
import { withEnableFrameProcessorsIOS } from './withEnableFrameProcessorsIOS'
import { withAndroidMLKitVisionModel } from './withAndroidMLKitVisionModel'
import { withUsesFeatureAndroid } from './withUsesFeatureAndroid'
import type { ConfigProps } from './@types'
import { withEnableLocationIOS } from './withEnableLocationIOS'
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-assignment
Expand Down Expand Up @@ -41,6 +42,14 @@ const withCamera: ConfigPlugin<ConfigProps> = (config, props = {}) => {
config = withEnableFrameProcessorsAndroid(config, props.enableFrameProcessors)
config = withEnableFrameProcessorsIOS(config, props.enableFrameProcessors)
}
if (props.requiresCamera !== null && props.requiresCamera !== undefined) {
// add uses-feature element to AndroidManifest.xml for hiding app from Play store in case camera is not available on the device
config = withUsesFeatureAndroid(config, ['android.hardware.camera', props.requiresCamera])
}
if (props.requiresMicrophone !== null && props.requiresMicrophone !== undefined) {
// add uses-feature element to AndroidManifest.xml for hiding app from Play store in case microphone is not available on the device
config = withUsesFeatureAndroid(config, ['android.hardware.microphone', props.requiresMicrophone])
}

if (props.enableCodeScanner) config = withAndroidMLKitVisionModel(config, props)

Expand Down