Skip to content

Commit

Permalink
feat: Add location docs and enableLocation to expo config plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Mar 21, 2024
1 parent 037e9a8 commit f2b056a
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 3 deletions.
138 changes: 138 additions & 0 deletions docs/docs/guides/LOCATION.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---
id: location
title: GPS Location Tags
sidebar_label: GPS Location Tags
---

import useBaseUrl from '@docusaurus/useBaseUrl'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'

<div class="image-container">
<img width="283" src={useBaseUrl("img/location.png")} />
</div>

## What are GPS Location Tags?

GPS Location Tags are location properties stored in image files (via EXIF tags) or video files (via QuickTime/MP4 tags).

VisionCamera provides an API to easily add such location tags to captured photos or videos.

### Configure Location Permissions

First, you need to add the required permissions to access the user's location:

<Tabs
groupId="environment"
defaultValue="rn"
values={[
{label: 'React Native', value: 'rn'},
{label: 'Expo', value: 'expo'}
]}>
<TabItem value="rn">

### iOS

Open your project's `Info.plist` and add the following lines inside the outermost `<dict>` tag:

```xml
<key>NSLocationWhenInUseUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your location.</string>
```

### Android

Open your project's `AndroidManifest.xml` and add the following lines inside the `<manifest>` tag:

```xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
```

</TabItem>

<TabItem value="expo">

### Managed Expo

Enable the `enableLocation` property inside your app's Expo config (`app.json`, `app.config.json` or `app.config.js`):

```json
{
"name": "my app",
"plugins": [
[
"react-native-vision-camera",
{
// ...
"enableLocation": true,
"locationPermissionText": "[my app] needs your location."
}
]
]
}
```

Finally, compile the mods:

```bash
npx expo prebuild
```

To apply the changes, build a new binary with EAS:

```bash
eas build
```

</TabItem>
</Tabs>

### Request Location Permissions

After adding the required permissions to your app's manifests, prompt the user to grant location permission at runtime:

<Tabs
groupId="component-style"
defaultValue="hooks"
values={[
{label: 'Hooks API', value: 'hooks'},
{label: 'Imperative API', value: 'imperative'}
]}>
<TabItem value="hooks">

Get or request permissions using the [`useLocationPermission`](/docs/api/#uselocationpermission) hook:

```tsx
const { hasPermission, requestPermission } = useLocationPermission()
```

</TabItem>
<TabItem value="imperative">

Get the current permission status:

```ts
const permissionStatus = Camera.getLocationPermissionStatus()
```

And if it is not `granted`, request permission:

```ts
const newPermissionStatus = await Camera.requestLocationPermission()
```

</TabItem>
</Tabs>

### Enable GPS Location Tags

Use the [`enableLocation`](/docs/api/interfaces/CameraProps#enablelocation) property to start streaming location updates and automatically add GPS Location Tags to images (EXIF tags) and videos:

```tsx
<Camera {...props} enableLocation={true} />
```

Once enabled, all captured photos (see ["Taking Photos"](taking-photos)) and videos (see ["Recording Videos"](recording-videos)) will contain location tags.


#### 🚀 Next section: [Performance](performance)
2 changes: 1 addition & 1 deletion docs/docs/guides/STABILIZATION.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@ Now, the video pipeline will stabilize frames over time.

<br />

#### 🚀 Next section: [Performance](performance)
#### 🚀 Next section: [GPS Location Tags](location)
3 changes: 2 additions & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@
"typedoc": "^0.25.1",
"typedoc-plugin-markdown": "^3.17.1",
"typescript": "^5.2.2"
}
},
"packageManager": "yarn@1.22.19+sha1.4ba7fc5c6e704fce2066ecbfb0b0d8976fe62447"
}
1 change: 1 addition & 0 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module.exports = {
'guides/exposure',
'guides/hdr',
'guides/stabilization',
'guides/location',
'guides/performance',
'guides/errors',
'guides/mocking',
Expand Down
Binary file added docs/static/img/location.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 11 additions & 1 deletion package/src/expo-plugin/@types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,20 @@ export type ConfigProps = {
*/
enableMicrophonePermission?: boolean
/**
* The text to show in the native dialog when asking for Camera Permissions.
* Whether to add Location Permissions to the native manifest or not.
* @default false
*/
enableLocationPermission?: boolean
/**
* The text to show in the native dialog when asking for Microphone Permissions.
* @default 'Allow $(PRODUCT_NAME) to access your microphone'
*/
microphonePermissionText?: string
/**
* The text to show in the native dialog when asking for Location Permissions.
* @default 'Allow $(PRODUCT_NAME) to access your location'
*/
locationPermissionText?: string
/**
* Whether to enable the Frame Processors runtime, or explicitly disable it.
* Disabling Frame Processors will make your app smaller as the C++ files will not be compiled.
Expand Down
9 changes: 9 additions & 0 deletions package/src/expo-plugin/withVisionCamera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,27 @@ const pkg = require('../../../package.json')

const CAMERA_USAGE = 'Allow $(PRODUCT_NAME) to access your camera'
const MICROPHONE_USAGE = 'Allow $(PRODUCT_NAME) to access your microphone'
const LOCATION_USAGE = 'Allow $(PRODUCT_NAME) to access your location'

const withCamera: ConfigPlugin<ConfigProps> = (config, props = {}) => {
if (config.ios == null) config.ios = {}
if (config.ios.infoPlist == null) config.ios.infoPlist = {}
// Camera permission
config.ios.infoPlist.NSCameraUsageDescription =
props.cameraPermissionText ?? (config.ios.infoPlist.NSCameraUsageDescription as string | undefined) ?? CAMERA_USAGE
if (props.enableMicrophonePermission) {
// Microphone permission
config.ios.infoPlist.NSMicrophoneUsageDescription =
props.microphonePermissionText ?? (config.ios.infoPlist.NSMicrophoneUsageDescription as string | undefined) ?? MICROPHONE_USAGE
}
if (props.enableLocationPermission) {
// Location permission
config.ios.infoPlist.NSLocationWhenInUseUsageDescription =
props.locationPermissionText ?? (config.ios.infoPlist.NSLocationWhenInUseUsageDescription as string | undefined) ?? LOCATION_USAGE
}
const androidPermissions = ['android.permission.CAMERA']
if (props.enableMicrophonePermission) androidPermissions.push('android.permission.RECORD_AUDIO')
if (props.enableLocationPermission) androidPermissions.push('android.permission.ACCESS_FINE_LOCATION')

if (props.disableFrameProcessors) {
config = withDisableFrameProcessorsAndroid(config)
Expand Down

0 comments on commit f2b056a

Please sign in to comment.