Skip to content

Intent launcher

Send the user to the right system screen: Wi-Fi settings when the network is off, your app’s own permission page after a denied prompt, or straight into another app. @symbiote-native/intent-launcher wraps expo-intent-launcher so every SymbioteNative adapter can launch an Android intent and read another app’s icon, not just React. Every export is a stateless free function, an enum or a plain type, so the React, Vue, Angular, Svelte, and Solid entry points are plain re-exports of the same core.

This is Android only: upstream ships no iOS implementation, so every function throws UnavailabilityError on iOS. Guard calls with a platform check.

OS platform Support
iOS not applicable (throws)
Android live
Framework adapter Support
React live
Vue live
Angular live
Svelte live
Solid live
Terminal window
npm install @symbiote-native/intent-launcher

Scaffolding or extending a SymbioteNative app? npx @symbiote-native/cli new --intent-launcher (or add --intent-launcher in an existing app) installs and wires this for you - see @symbiote-native/cli.

expo-intent-launcher and expo-modules-core come along as regular dependencies, pinned to exact versions. Never install either yourself, and never add the expo meta-package to your project (it bundles its own Metro/Babel pipeline, which conflicts with this project’s own).

No runtime permission or manifest edit is needed to start an activity or read an icon.

All five adapters re-export the same functions; there is no per-adapter hook, composable or service, since nothing here holds live state.

import { ActivityAction, startActivityAsync } from '@symbiote-native/intent-launcher/react';
export default function OpenWifi() {
return (
<button
title="Wi-Fi settings"
onPress={() => startActivityAsync(ActivityAction.WIFI_SETTINGS)}
/>
);
}
import { getApplicationIconAsync, openApplication } from '@symbiote-native/intent-launcher';
openApplication('com.google.android.gm');
const icon = await getApplicationIconAsync('com.google.android.gm'); // a data:image/png;base64 URI
await startActivityAsync(ActivityAction.APPLICATION_DETAILS_SETTINGS, {
data: 'package:com.example.myapp',
});
Signature Description
startActivityAsync(activityAction, params?): Promise<IIntentLauncherResult> Starts an activity and resolves once the user returns to this app. activityAction is an ActivityAction or any action string
openApplication(packageName): void Opens another app by package name. Fire-and-forget
getApplicationIconAsync(packageName): Promise<string> Resolves another app’s icon as a data:image/png;base64,... URI
Field Type Description
data string | undefined URI the intent operates on. Android requires a lowercase scheme
type string | undefined MIME type of data. Omit to let Android infer it
category string | undefined More detail about the action (Intent.addCategory)
extra Record<string, unknown> | undefined Key-value pairs passed with the intent. Keys need a package prefix
flags number | undefined Bitmask of intent flags (Intent.setFlags)
packageName string | undefined Package of the component that should handle the intent
className string | undefined Class name of that component
Name Description
resultCode A ResultCode: Success (-1), Canceled (0) or FirstUser (1, the first custom value)
data Optional data URI the activity returned
extra Optional extras the activity returned
ActivityAction Constants for Android’s own Settings actions, such as WIFI_SETTINGS
  • Every function throws UnavailabilityError off Android. Check Platform.OS before calling.
  • startActivityAsync resolves when the user comes back. The result code tells you whether they finished or cancelled; do not assume the setting was changed.
  • extra is typed Record<string, unknown>. Upstream uses any; the value is forwarded verbatim to the native module.
  • It can only be verified on an Android device or emulator. The headless tests fake the native module, so they prove the argument validation and the UnavailabilityError branches.
  • The call rejects with ActivityNotFoundException. No installed app handles the intent (for example a file type nobody opens). Wrap the call in try/catch and show a fallback.
  • packageName without className rejects. The intent is then restricted to that package; if the app cannot handle it, the promise rejects.
  • Crash returning from a notification-settings intent. Reported with APP_NOTIFICATION_SETTINGS and an extra carrying the package name; test that flow on a device.
  • ERR_UNAVAILABLE. Reported with enableDangerousExperimentalLeanBuilds; Android only, there is no iOS equivalent.

Sources: expo/expo#12078, expo/expo#50511, expo/expo#21876, expo/expo#22995.

expo-intent-launcher’s JS is hand-ported into this package’s core/, resolving the native module through expo-modules-core rather than the expo meta-package; the native resolution is Android-only and the base entry is an empty stub. The five adapter entry points are plain re-exports of core (Angular stays a physical subpath for its separate ngc/AOT build). The native code is never vendored: expo-modules-autolinking resolves it from node_modules (see the native setup guide).