Develop

Android Permissions sample overview

Updated: May 7, 2026

Overview

This sample demonstrates how to request and handle Android runtime permissions and query platform state in Unreal Engine for Meta Quest. It covers checking and requesting microphone, internet, and storage permissions, and reading battery state, volume, and device information using C++ and Blueprint integration.

Learning objectives

Complete this guide to learn how to:
  • request Android runtime permissions (microphone, internet, storage) and respond to grant or deny results
  • check permission status before accessing protected features
  • query device state (battery level, charging status, volume) in real time
  • read Android platform information (version, device make/model)
  • use platform guard patterns to write Android-specific code that compiles safely in editor builds

Requirements

  • Meta Quest 2, Quest 3, or Quest 3S device
  • Unreal Engine development environment configured for Meta Quest
For detailed SDK version and toolchain requirements, see the sample README.

Get started

Clone the Unreal-AndroidPermissions repository. Open AndroidPermissions.uproject in Unreal Engine, build the project for Android, and deploy to your Quest device.

Explore the sample

File / SceneWhat it demonstratesKey concepts
Permission checking and requesting logic
UAndroidPermissionFunctionLibrary, delegate binding
Platform guard pattern, async permission callbacks
#if PLATFORM_ANDROID, OnPermissionsGrantedDynamicDelegate
Device state queries (battery, volume, version)
FAndroidMisc API, NativeTick override
Content/PermissionsSample.umap
Main VR scene with UI widgets
VR pawn setup, UMG widget integration
Config/DefaultEngine.ini
Manifest permission declarations
+ExtraPermissions, bAndroidVoiceEnabled

Runtime behavior

When you launch the sample, you see two UI panels in VR. The left panel displays the current status of three permissions (microphone, internet, write external storage) and provides buttons to request microphone and internet permissions. The right panel shows live platform information: battery level, charging state, temperature, current volume, Android version, and device make/model. When you press a permission request button, the Android OS displays a system permission dialog. After you grant or deny the permission, the status indicator updates immediately.

Key concepts

Requesting permissions at runtime

The sample handles permission requests using Unreal’s UAndroidPermissionFunctionLibrary:
bool UPermissionsUserWidget::HasPermission(const FString& PermissionStr)
{
    return `UAndroidPermissionFunctionLibrary`::CheckPermission(PermissionStr);
}
When the user clicks a request button, the sample calls AcquirePermissions() with a single-element array. The result arrives asynchronously via the OnPermissionsGrantedDynamicDelegate multicast delegate.

Platform guard pattern for cross-platform builds

All Android-specific code is wrapped in #if PLATFORM_ANDROID guards. In editor and desktop builds, permission checks return safe defaults:
#if PLATFORM_ANDROID
    return `UAndroidPermissionFunctionLibrary`::CheckPermission(PermissionStr);
#else
    return true;  // Assume granted in editor
#endif
This pattern ensures the sample builds for all platforms while preserving Android-specific functionality.

Querying battery and device state

The sample reads battery state using FAndroidMisc::GetBatteryState(), which returns a struct with State, Level, and Temperature fields:
FAndroidMisc::FBatteryState BatteryState = FAndroidMisc::GetBatteryState();
BatteryIsCharging = BatteryState.State == FAndroidMisc::BATTERY_STATE_CHARGING;
BatteryLevel = BatteryState.Level;
BatteryTemp = BatteryState.Temperature;

C++ and Blueprint hybrid architecture

The sample uses a hybrid pattern where C++ provides the Android API logic and Blueprint provides the visual layout. C++ properties marked UPROPERTY(VisibleAnywhere, BlueprintReadOnly) expose data for UMG widget binding. C++ methods marked UFUNCTION(BlueprintCallable) serve as button event handlers.

Extend the sample

  • Add support for additional runtime permissions (camera, location, contacts) by extending PermissionsUserWidget.
  • Create a permission status history log that records grant/deny events with timestamps.
  • Integrate permission checks into a VR feature that requires microphone access such as voice chat.