flutter_combainsdk 0.4.19
flutter_combainsdk: ^0.4.19 copied to clipboard
A Flutter wrapper for the Combain AI Navigation SDK.
Combain Indoor AI Navigation Plugin #
This plugin is a wrapper for the Combain Indoor AI Navigation SDK. It provides a simple way to integrate the SDK into your Flutter app.
Installation #
First update android/build.gradle.kt to include the Combain Maven repository:
repositories {
maven(url = "https://gitlab.com/api/v4/projects/3194773/packages/maven") <- ADD THIS
google()
mavenCentral()
}
Then include the SDK in your pubspec.yaml:
dependencies:
flutter_combainsdk: ^0.4.9
...
Permissions #
After this you need to manage permissions
Android #
For proper permission handling, your MainActivity must extend FlutterFragmentActivity instead of the default FlutterActivity. This is required because the SDK needs access to ComponentActivity features for permission management.
In your android/app/src/main/kotlin/.../MainActivity.kt:
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterFragmentActivity()
Note: If your MainActivity currently extends FlutterActivity, simply change it to FlutterFragmentActivity and update the import statement.
Required Permissions in AndroidManifest.xml
Add the following permissions to your android/app/src/main/AndroidManifest.xml file:
<!-- Required permissions for Bluetooth and location services -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
Note: These permissions are required for the SDK to function properly, especially for Bluetooth beacon detection and location services. The neverForLocation flag on BLUETOOTH_SCAN indicates that Bluetooth scanning is not used for location purposes.
Note: You might want to ask for notifications more gracefully. When you run ´start()´ the SDK will ask for all required permissions. If you wish to use onboarding for this see example project: at lib/screens/setup/permissions_setup.dart
Permissions #
iOS #
The following values needs to be specified in the info.plist
NSMotionUsageDescriptionNSLocationWhenInUseUsageDescription
And this needs to be added to Podfile:
target.build_configurations.each do |config|
# You can remove unused permissions here
# for more information: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
# e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## The 'PERMISSION_LOCATION' macro enables the `locationWhenInUse` and `locationAlways` permission. If
## the application only requires `locationWhenInUse`, only specify the `PERMISSION_LOCATION_WHENINUSE`
## macro.
##
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
'PERMISSION_LOCATION_WHENINUSE=1',
'PERMISSION_SENSORS=1',
]
end
See https://github.com/Baseflow/flutter-permission-handler/tree/main/permission_handler#setup
ONNX Runtime Framework - App Store Validation Fix #
The SDK includes the ONNX Runtime framework which may have a MinimumOSVersion that doesn't match your app's deployment target. This can cause App Store Connect validation failures with the error:
Validation failed
Invalid Bundle. The bundle Runner.app/Frameworks/onnxruntime.framework does not support the minimum OS Version specified in the Info.plist.
Solution:
Add a build phase script to automatically patch the framework's Info.plist during the build process.
- Create
scripts/fix-onnxruntime.shin your Flutter project root:
#!/bin/bash
# Fix ONNX Runtime framework MinimumOSVersion to match app deployment target
# This script patches the Info.plist of onnxruntime.framework
set -e
echo "Fixing onnxruntime.framework MinimumOSVersion..."
# Find onnxruntime.framework in the built app
FRAMEWORK_PATH="${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/onnxruntime.framework"
if [ ! -d "$FRAMEWORK_PATH" ]; then
echo "onnxruntime.framework not found at $FRAMEWORK_PATH, skipping..."
exit 0
fi
INFO_PLIST="$FRAMEWORK_PATH/Info.plist"
if [ ! -f "$INFO_PLIST" ]; then
echo "Info.plist not found in onnxruntime.framework, skipping..."
exit 0
fi
echo "Found framework at: $FRAMEWORK_PATH"
# Update MinimumOSVersion to match your app's IPHONEOS_DEPLOYMENT_TARGET
# Change "15.6" to match your deployment target if different
if /usr/libexec/PlistBuddy -c "Print :MinimumOSVersion" "$INFO_PLIST" 2>/dev/null; then
echo "Updating existing MinimumOSVersion to 15.6..."
/usr/libexec/PlistBuddy -c "Set :MinimumOSVersion 15.6" "$INFO_PLIST"
else
echo "Adding MinimumOSVersion 15.6..."
/usr/libexec/PlistBuddy -c "Add :MinimumOSVersion string 15.6" "$INFO_PLIST"
fi
echo "Successfully updated onnxruntime.framework MinimumOSVersion to 15.6"
- Make the script executable:
chmod +x scripts/fix-onnxruntime.sh
- Add a build phase in Xcode:
- Open
ios/Runner.xcodeprojin Xcode - Select the "Runner" target
- Go to "Build Phases" tab
- Click "+" and select "New Run Script Phase"
- Name it "Fix ONNX Runtime Framework"
- Add this script:
"${SRCROOT}/../scripts/fix-onnxruntime.sh" - Move it to run after "[CP] Embed Pods Frameworks" but before "[CP] Copy Pods Resources"
- Open
Note: Adjust the MinimumOSVersion value in the script to match your app's IPHONEOS_DEPLOYMENT_TARGET setting in Xcode.
Getting Started #
Now you are ready to start recieving indoor location updates This is all the code needed to start receiving indoor location updates from the Combain Indoor AI Navigation SDK.
CombainSDKConfig indoorNavigationConfig = CombainSDKConfig(
apiKey: env.combainApiKey,
settingsKey: env.combainApiKey, // Leave as empty string to only use apiKey
locationProvider: FlutterLocationProvider.aiNavigation,
routingConfig: FlutterRoutingConfig(
routableNodesOptions: FlutterRoutableNodesOptions.allExceptDefaultName,
),
appInfo: FlutterAppInfo(
packageName: _packageInfo.packageName, // See https://pub.dev/packages/package_info_plus
versionName: _packageInfo.version,
versionCode: int.tryParse(_packageInfo.buildNumber) ?? 0,
),
syncingInterval: FlutterSyncingInterval(
type: FlutterSyncingIntervalType.interval,
intervalMilliseconds: 60 * 1000 * 60,
),
wifiEnabled: true,
bluetoothEnabled: true,
beaconUUIDs: ["E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"], // For iOS iBeacon to work, leave as empty array if not used on iOS
)
CombainSDKConfig slamConfig = CombainSDKConfig(
apiKey: env.combainApiKey,
settingsKey: env.combainApiKey, // Leave as empty string to only use apiKey
locationProvider: FlutterLocationProvider.slam,
appInfo: FlutterAppInfo(
packageName: _packageInfo.packageName, // See https://pub.dev/packages/package_info_plus
versionName: _packageInfo.version,
versionCode: int.tryParse(_packageInfo.buildNumber) ?? 0,
),
syncingInterval: FlutterSyncingInterval(
type: FlutterSyncingIntervalType.interval,
intervalMilliseconds: 60 * 1000 * 60,
),
wifiEnabled: true,
bluetoothEnabled: true,
beaconUUIDs: ["E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"], // For iOS iBeacon to work, leave as empty array if not used on iOS
);
Future<void> initSDK() async {
// Step 1: Create the SDK instance with logging and exception capture
final combainSDK = await FlutterCombainSDK.create();
await _combainSDK.initializeSDK(indoorNavigationConfig); // Use slamConfig for SLAM
await combainSDK.start();
}
Demo #
For a demo project see https://gitlab.combain.com/Hugo-Persson/flutter-ai-navigation-demo or https://github.com/careerfairsystems/arkad-app-flutter