Google VR SDK Integration in Mobile Apps
Google VR SDK (Cardboard SDK after 2021 rebranding) — official library for adding Cardboard VR to mobile apps on iOS and Android. SDK handles lens distortion, head tracking, stereo projection, and device profile QR scanning.
Current Status: Cardboard SDK vs Deprecated Google VR SDK
Important: original Google VR SDK (gvr-android-sdk) deprecated since 2019. Current version — open Google Cardboard SDK, actively maintained. If project uses old com.google.vr.sdk — migration recommended.
New Cardboard SDK supports:
- Unity via UPM package
com.google.cardboard - Native Android (C++ via JNI + Java wrapper)
- Native iOS (Objective-C/Swift)
Unity Integration
Most common path. Via Package Manager add com.google.cardboard from git URL:
https://github.com/googlevr/cardboard.git#upm
After installation add CardboardCamera component to Main Camera. SDK automatically:
- Splits screen in half for stereo rendering
- Applies lens distortion correction
- Reads head tracking from IMU
- Handles trigger button
// First launch: show UI for QR scanning
void Start() {
if (!CardboardQrCode.IsDeviceParamsSet()) {
Cardboard.SDK.ScanDeviceParams();
}
}
// Recenter on button press
void Update() {
if (CardboardInput.GetButtonDown()) {
Cardboard.SDK.Recenter();
}
}
Native Android Integration (Java/Kotlin)
For native apps without Unity:
// build.gradle
implementation 'com.google.cardboard:sdk:1.21.0'
Key SDK components:
// Initialization in Activity
private CardboardHeadTracker headTracker;
private CardboardLensDistortion lensDistortion;
private CardboardDistortionRenderer distortionRenderer;
@Override
protected void onCreate(Bundle savedInstanceState) {
CardboardSdk.initializeOnce(this, "your-app-name");
headTracker = CardboardHeadTracker.create();
// ...
}
// In render loop (called from GLSurfaceView)
@Override
public void onDrawFrame(GL10 gl) {
// Get matrices for each eye
long monotonic_time_ns = System.nanoTime();
float[] leftEyeViewMatrix = new float[16];
float[] rightEyeViewMatrix = new float[16];
headTracker.getPose(monotonic_time_ns, leftEyeViewMatrix, rightEyeViewMatrix);
// Render each eye...
// Apply lens distortion via SDK
distortionRenderer.renderEyeToDisplay(
/* display */ 0, /* x */ 0, /* y */ 0,
/* width */ displayWidth, /* height */ displayHeight,
/* leftEyeParams */ leftEyeParams,
/* rightEyeParams */ rightEyeParams
);
}
Native iOS Integration (Swift)
// Podfile or SPM
pod 'GoogleCardboard', '~> 1.21'
// CardboardV1API — main entry point
import CardboardSDK
class VRViewController: UIViewController {
private var renderer: CardboardRenderer!
override func viewDidLoad() {
super.viewDidLoad()
CardboardQrCode.getSavedDeviceParams { [weak self] params in
if params == nil {
CardboardQrCode.scanQrCodeAndSaveDeviceParams(from: self)
}
self?.initRenderer()
}
}
}
QR Scanning: Handling Edge Cases
QR scanner opens on first launch or explicit user request. Potential issues:
- User declined scanning → SDK uses default Cardboard v1 parameters. Lens distortion incorrect for non-standard housings.
- QR not readable (poor lighting, damaged code) → "enter manually" button or "use standard Cardboard."
- After housing change → settings screen "change headset" button, calls
CardboardQrCode.scanQrCodeAndSaveDeviceParams().
Split-screen and Fullscreen Mode
Cardboard SDK expects landscape orientation. On iOS means lock UIInterfaceOrientationMask to .landscapeRight. On Android — android:screenOrientation="landscape" in manifest + handle onConfigurationChanged to avoid activity recreation.
Screen cutouts (notch, Dynamic Island) in landscape may cover part of VR image. Use WindowInsets.displayCutout (Android) and safeAreaInsets (iOS) for correct render region positioning.
Common Integration Issues
IllegalStateException: Surface is not valid on Android startup — GLSurfaceView not ready at Cardboard initialization. Solved by initializing in surfaceCreated() callback, not onCreate().
SDK doesn't compile with new NDK — Cardboard SDK has native C++ part, sometimes requires explicit abiFilters "armeabi-v7a", "arm64-v8a" in gradle.
On iOS 17+ CMMotionManager requires NSMotionUsageDescription in Info.plist — without it crash on VR mode start.
Workflow
Audit existing project: Unity or native, current dependencies, target iOS/Android versions.
Integrate Cardboard SDK, configure QR scanning.
Adapt rendering: split-screen, lens distortion, stereo projections.
Gaze interaction and Cardboard button.
Test on real devices from different manufacturers.
Timeline Estimates
Basic Cardboard SDK integration into Unity project — 2–3 days. Native integration with custom renderer for iOS or Android — 3–5 days.







