feat: Add new enableCodeScanner
prop to build.gradle
to make sure CodeScanner
always works (#2355)
* feat: Always download model instead of relying on Google Play Services * feat: Use `VisionCamera_enableCodeScanner` flag instead of unsafely replacing * Update CODE_SCANNING.mdx
This commit is contained in:
parent
a8c16e31d6
commit
5c99728561
@ -30,7 +30,7 @@ A Code Scanner is a separate Camera output (just like photo or video) that can d
|
|||||||
|
|
||||||
On iOS, the Code Scanner uses the platform-native APIs and can be used out of the box.
|
On iOS, the Code Scanner uses the platform-native APIs and can be used out of the box.
|
||||||
|
|
||||||
On Android, the [MLKit Vision Barcode Scanning](https://developers.google.com/ml-kit/vision/barcode-scanning) API will be used, and the model (2.2MB) needs to be downloaded first.
|
On Android, the [MLKit Vision Barcode Scanning](https://developers.google.com/ml-kit/vision/barcode-scanning) API will be used, and the model (2.2MB) needs to be included into your app first.
|
||||||
|
|
||||||
<Tabs
|
<Tabs
|
||||||
groupId="environment"
|
groupId="environment"
|
||||||
@ -41,21 +41,16 @@ On Android, the [MLKit Vision Barcode Scanning](https://developers.google.com/ml
|
|||||||
]}>
|
]}>
|
||||||
<TabItem value="rn">
|
<TabItem value="rn">
|
||||||
|
|
||||||
To download the model when the user installs your app, add this to your `AndroidManifest.xml` file:
|
Inside your `gradle.properties` file, add the `enableCodeScanner` flag:
|
||||||
|
|
||||||
```xml
|
```groovy
|
||||||
<application ...>
|
VisionCamera_enableCodeScanner=true
|
||||||
...
|
|
||||||
<meta-data
|
|
||||||
android:name="com.google.mlkit.vision.DEPENDENCIES"
|
|
||||||
android:value="barcode" />
|
|
||||||
</application>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem value="expo">
|
<TabItem value="expo">
|
||||||
|
|
||||||
To download the model when the user installs your app, add the `enableCodeScanner` flag to your Expo config (`app.json`, `app.config.json` or `app.config.js`):
|
Add the `enableCodeScanner` flag to your Expo config (`app.json`, `app.config.json` or `app.config.js`):
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -77,7 +72,7 @@ To download the model when the user installs your app, add the `enableCodeScanne
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
To use a codescanner, simply create a [`CodeScanner`](/docs/api/interfaces/CodeScanner) and pass it to the `<Camera>`:
|
To scan codes, simply create a [`CodeScanner`](/docs/api/interfaces/CodeScanner) instance and pass it to the `<Camera>`:
|
||||||
|
|
||||||
<Tabs
|
<Tabs
|
||||||
groupId="component-style"
|
groupId="component-style"
|
||||||
|
@ -71,6 +71,8 @@ def nodeModules = findNodeModules(projectDir)
|
|||||||
def hasWorklets = !safeExtGet("VisionCamera_disableFrameProcessors", false) && findProject(":react-native-worklets-core") != null
|
def hasWorklets = !safeExtGet("VisionCamera_disableFrameProcessors", false) && findProject(":react-native-worklets-core") != null
|
||||||
logger.warn("[VisionCamera] react-native-worklets-core ${hasWorklets ? "found" : "not found"}, Frame Processors ${hasWorklets ? "enabled" : "disabled"}!")
|
logger.warn("[VisionCamera] react-native-worklets-core ${hasWorklets ? "found" : "not found"}, Frame Processors ${hasWorklets ? "enabled" : "disabled"}!")
|
||||||
|
|
||||||
|
def enableCodeScanner = safeExtGet("VisionCamera_enableCodeScanner", false)
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@ -162,7 +164,15 @@ dependencies {
|
|||||||
//noinspection GradleDynamicVersion
|
//noinspection GradleDynamicVersion
|
||||||
implementation "com.facebook.react:react-android:+"
|
implementation "com.facebook.react:react-android:+"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2"
|
||||||
|
|
||||||
|
if (enableCodeScanner) {
|
||||||
|
// User enabled code-scanner, so we bundle the 2.4 MB model in the app.
|
||||||
|
implementation 'com.google.mlkit:barcode-scanning:17.2.0'
|
||||||
|
} else {
|
||||||
|
// Fall-back to just including the code for the CodeScanner to avoid the 2.4 MB bundle in the app.
|
||||||
|
// On devices with Google Play Services, this can also download the CodeScanner model on-demand.
|
||||||
implementation "com.google.android.gms:play-services-mlkit-barcode-scanning:18.3.0"
|
implementation "com.google.android.gms:play-services-mlkit-barcode-scanning:18.3.0"
|
||||||
|
}
|
||||||
|
|
||||||
if (hasWorklets) {
|
if (hasWorklets) {
|
||||||
// Frame Processor integration (optional)
|
// Frame Processor integration (optional)
|
||||||
|
@ -41,3 +41,5 @@ hermesEnabled=true
|
|||||||
|
|
||||||
# Can be set to true to disable the build setup
|
# Can be set to true to disable the build setup
|
||||||
#VisionCamera_disableFrameProcessors=true
|
#VisionCamera_disableFrameProcessors=true
|
||||||
|
# Can be set to true to include the full 2.4 MB MLKit dependency
|
||||||
|
#VisionCamera_enableCodeScanner=true
|
||||||
|
@ -22,13 +22,15 @@ export type ConfigProps = {
|
|||||||
*/
|
*/
|
||||||
disableFrameProcessors?: boolean
|
disableFrameProcessors?: boolean
|
||||||
/**
|
/**
|
||||||
* Whether to enable the QR/Barcode Scanner Model. If true, the MLKit Model will
|
* Whether to enable the QR/Barcode Scanner Model.
|
||||||
* automatically be downloaded on app startup. If false, it will be downloaded
|
*
|
||||||
* once the Camera is created with a `CodeScanner`.
|
* - When set to `true`, the MLKit Model will be bundled alongside
|
||||||
|
* with your app. (~2.4 MB in size).
|
||||||
|
* - When set to `false`, it can still be downloaded on-the-fly on devices with Google Play Services installed if you are using the `CodeScanner`.
|
||||||
|
*
|
||||||
* See [QR/Barcode Scanning](https://react-native-vision-camera.com/docs/guides/code-scanning)
|
* See [QR/Barcode Scanning](https://react-native-vision-camera.com/docs/guides/code-scanning)
|
||||||
*
|
*
|
||||||
* If set to true, it fallbacks to `android-manifest`.
|
|
||||||
* @default false
|
* @default false
|
||||||
*/
|
*/
|
||||||
enableCodeScanner?: boolean | 'android-manifest' | 'gradle-implementation'
|
enableCodeScanner?: boolean
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,24 @@
|
|||||||
import { AndroidConfig, ConfigPlugin, withAndroidManifest, withAppBuildGradle } from '@expo/config-plugins'
|
import { ConfigPlugin, withGradleProperties } from '@expo/config-plugins'
|
||||||
import { ConfigProps } from './@types'
|
import { ConfigProps } from './@types'
|
||||||
|
|
||||||
const { addMetaDataItemToMainApplication, getMainApplicationOrThrow } = AndroidConfig.Manifest
|
/**
|
||||||
|
* Set the `VisionCamera_enableCodeScanner` value in the static `gradle.properties` file.
|
||||||
export const withAndroidMLKitVisionModel: ConfigPlugin<ConfigProps> = (config, props) => {
|
* This is used to add the full MLKit dependency to the project.
|
||||||
if (props.enableCodeScanner === 'gradle-implementation') {
|
*/
|
||||||
return withAppBuildGradle(config, (conf) => {
|
export const withAndroidMLKitVisionModel: ConfigPlugin<ConfigProps> = (c) => {
|
||||||
const buildGradle = conf.modResults
|
const key = 'VisionCamera_enableCodeScanner'
|
||||||
const implementation = "implementation 'com.google.mlkit:barcode-scanning:17.2.0'"
|
return withGradleProperties(c, (config) => {
|
||||||
|
config.modResults = config.modResults.filter((item) => {
|
||||||
if (buildGradle.contents.includes(implementation) === false) {
|
if (item.type === 'property' && item.key === key) return false
|
||||||
// Inspired by https://github.com/invertase/react-native-firebase/blob/main/packages/app/plugin/src/android/buildscriptDependency.ts
|
return true
|
||||||
// TODO: Find a better way to do this
|
|
||||||
buildGradle.contents = buildGradle.contents.replace(
|
|
||||||
/dependencies\s?{/,
|
|
||||||
`dependencies {
|
|
||||||
${implementation}`,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return conf
|
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
return withAndroidManifest(config, (conf) => {
|
config.modResults.push({
|
||||||
const androidManifest = conf.modResults
|
type: 'property',
|
||||||
const mainApplication = getMainApplicationOrThrow(androidManifest)
|
key: key,
|
||||||
|
value: 'true',
|
||||||
|
})
|
||||||
|
|
||||||
addMetaDataItemToMainApplication(mainApplication, 'com.google.mlkit.vision.DEPENDENCIES', 'barcode')
|
return config
|
||||||
|
|
||||||
conf.modResults = androidManifest
|
|
||||||
|
|
||||||
return conf
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ const withCamera: ConfigPlugin<ConfigProps> = (config, props = {}) => {
|
|||||||
config = withDisableFrameProcessorsIOS(config)
|
config = withDisableFrameProcessorsIOS(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.enableCodeScanner !== false) config = withAndroidMLKitVisionModel(config, props)
|
if (props.enableCodeScanner) config = withAndroidMLKitVisionModel(config, props)
|
||||||
|
|
||||||
return withPlugins(config, [[AndroidConfig.Permissions.withPermissions, androidPermissions]])
|
return withPlugins(config, [[AndroidConfig.Permissions.withPermissions, androidPermissions]])
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user