expo-activity-recognition
v0.3.1
Published
Access system activity recognition
Maintainers
Readme
expo-activity-recognition
A module that provides access to the device activity recognition services, allowing your app to detect the user's current activity such as walking, running, cycling, driving, or being still.
Installation
npx expo install expo-activity-recognitionConfiguration
iOS
Add the plugin to your app.json:
{
"expo": {
"plugins": [
[
"expo-activity-recognition",
{
"motionPermission": "Allow $(PRODUCT_NAME) to access your device motion"
}
]
]
}
}This will add the required NSMotionUsageDescription to your Info.plist.
Android
No additional configuration required for basic usage, but permissions will be requested at runtime on Android Q (API 29) and above.
API
Setup and Teardown
// Setup the activity recognition observer
// interval (Android only): milliseconds between updates (default: 60000ms)
ExpoActivityRecognition.setupObserver(interval?: number): Promise<boolean>
// Remove the activity recognition observer
ExpoActivityRecognition.removeObserver(): Promise<boolean>Permissions
// Request activity recognition permissions
ExpoActivityRecognition.requestPermissions(): Promise<boolean>
// Check activity recognition permission status
ExpoActivityRecognition.checkPermissions(): Promise<PermissionStatus>Activity Data
// Get the current activity if available
ExpoActivityRecognition.getCurrentActivity(): Promise<ActivityChangeEventPayload>
// Listen for activity changes
const subscription = ExpoActivityRecognition.addListener('onActivityChange',
(data: ActivityChangeEventPayload) => {
// Handle activity change
}
);
// Remove the listener when done
subscription.remove();Types
// Possible activity types
type Activity = 'running' | 'cycling' | 'driving' | 'walking' | 'still' | 'unknown';
// Activity change event payload
type ActivityChangeEventPayload = {
// The detected activity type
activity: Activity;
// Confidence level (0-100)
// 100: high confidence
// 75: medium confidence
// 25: low confidence
// 0: unknown confidence
confidence: number;
};
// Permission status
type PermissionStatus = {
// Current permission status
// 'authorized': Permission granted
// 'denied': Permission denied or restricted
// 'undetermined': Permission not requested yet (iOS only)
status: 'authorized' | 'denied' | 'undetermined';
};Example
import ExpoActivityRecognition from 'expo-activity-recognition';
import { useEffect, useState } from 'react';
import { Button, SafeAreaView, StyleSheet, Text, View } from 'react-native';
export default function App() {
const [currentActivity, setCurrentActivity] = useState<string | null>(null);
const [permissionStatus, setPermissionStatus] = useState<string | null>(null);
useEffect(() => {
// Set up activity change listener
const listener = ExpoActivityRecognition.addListener("onActivityChange", (params) => {
setCurrentActivity(params.activity);
});
// Check initial permission status
checkPermissions();
// Clean up listener on unmount
return () => {
listener.remove();
};
}, []);
const checkPermissions = async () => {
try {
const { status } = await ExpoActivityRecognition.checkPermissions();
setPermissionStatus(status);
} catch (error) {
setPermissionStatus('error');
}
};
const setupActivityRecognition = async () => {
try {
// Request permissions first if not already granted
if (permissionStatus !== 'authorized') {
await ExpoActivityRecognition.requestPermissions();
await checkPermissions();
}
// Set up the observer
await ExpoActivityRecognition.setupObserver();
} catch (error) {
// Handle setup errors
}
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.content}>
<Text style={styles.status}>
Permission: {permissionStatus || 'unknown'}
</Text>
<Text style={styles.status}>
Current activity: {currentActivity || 'unknown'}
</Text>
<View style={styles.buttonContainer}>
<Button
title="Start Activity Recognition"
onPress={setupActivityRecognition}
/>
<Button
title="Get Current Activity"
onPress={async () => {
try {
const activity = await ExpoActivityRecognition.getCurrentActivity();
setCurrentActivity(activity.activity);
} catch (error) {
// Handle error
}
}}
/>
<Button
title="Stop Recognition"
onPress={() => ExpoActivityRecognition.removeObserver()}
/>
</View>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff'
},
content: {
flex: 1,
padding: 20,
justifyContent: 'center'
},
status: {
fontSize: 18,
marginBottom: 20
},
buttonContainer: {
marginTop: 20,
gap: 10
}
});