High-level plugins for modifying Android project files including AndroidManifest.xml, resource files, build configurations, and Java/Kotlin source files. These plugins provide convenient interfaces for common Android development tasks.
Modify the AndroidManifest.xml file with structured XML manipulation.
function withAndroidManifest(
config: ExpoConfig,
action: Mod<AndroidManifest>
): ExpoConfig;Usage:
config = withAndroidManifest(config, async (config) => {
const manifest = config.modResults;
// Add meta-data to application
AndroidConfig.Manifest.addMetaDataItemToMainApplication(
manifest,
"com.example.api_key",
"your-api-key"
);
return config;
});Helper for creating manifest modification plugins.
function createAndroidManifestPlugin(
action: (expo: ExportedConfigWithProps<AndroidManifest>, data: AndroidManifest) => OptionalPromise<AndroidManifest>,
name: string
): ConfigPlugin;Modify the strings.xml resource file for localized strings.
function withStringsXml(
config: ExpoConfig,
action: Mod<ResourceXML>
): ExpoConfig;Usage:
config = withStringsXml(config, async (config) => {
const strings = config.modResults;
AndroidConfig.Strings.setStringItem(
strings,
"app_name",
"My Custom App Name"
);
return config;
});Modify the colors.xml resource file for color definitions.
function withAndroidColors(
config: ExpoConfig,
action: Mod<ResourceXML>
): ExpoConfig;Modify the colors.xml resource file for dark theme colors.
function withAndroidColorsNight(
config: ExpoConfig,
action: Mod<ResourceXML>
): ExpoConfig;Modify the styles.xml resource file for theme and style definitions.
function withAndroidStyles(
config: ExpoConfig,
action: Mod<ResourceXML>
): ExpoConfig;Modify the MainActivity.java or MainActivity.kt file.
function withMainActivity(
config: ExpoConfig,
action: Mod<ApplicationProjectFile>
): ExpoConfig;Usage:
config = withMainActivity(config, async (config) => {
const mainActivity = config.modResults;
// Add imports
mainActivity.contents = AndroidConfig.CodeMod.addImports(
mainActivity.contents,
["com.example.CustomModule"]
);
return config;
});Modify the MainApplication.java or MainApplication.kt file.
function withMainApplication(
config: ExpoConfig,
action: Mod<ApplicationProjectFile>
): ExpoConfig;Modify the app-level build.gradle file.
function withAppBuildGradle(
config: ExpoConfig,
action: Mod<GradleProjectFile>
): ExpoConfig;Usage:
config = withAppBuildGradle(config, async (config) => {
const buildGradle = config.modResults;
// Add dependencies
if (!buildGradle.contents.includes("implementation 'com.example:library:1.0.0'")) {
buildGradle.contents = buildGradle.contents.replace(
/dependencies\s*{/,
`dependencies {
implementation 'com.example:library:1.0.0'`
);
}
return config;
});Modify the project-level build.gradle file.
function withProjectBuildGradle(
config: ExpoConfig,
action: Mod<GradleProjectFile>
): ExpoConfig;Modify the settings.gradle file.
function withSettingsGradle(
config: ExpoConfig,
action: Mod<GradleProjectFile>
): ExpoConfig;Modify the gradle.properties file.
function withGradleProperties(
config: ExpoConfig,
action: Mod<Properties.PropertiesItem[]>
): ExpoConfig;Usage:
config = withGradleProperties(config, async (config) => {
const properties = config.modResults;
// Add or update a property
const existingProp = properties.find(prop => prop.key === "android.useAndroidX");
if (existingProp) {
existingProp.value = "true";
} else {
properties.push({ key: "android.useAndroidX", value: "true" });
}
return config;
});interface AndroidManifest {
manifest: {
$: {
"xmlns:android": string;
package: string;
};
application: ManifestApplication[];
"uses-permission"?: ManifestUsesPermission[];
"uses-feature"?: ManifestUsesFeature[];
};
}
interface ResourceXML {
resources: {
string?: ResourceItem[];
color?: ResourceItem[];
style?: StyleItem[];
};
}
interface ResourceItem {
$: {
name: string;
translatable?: string;
};
_: string;
}
interface ApplicationProjectFile {
path: string;
contents: string;
language: "java" | "kotlin";
}
interface GradleProjectFile {
path: string;
contents: string;
}
namespace Properties {
interface PropertiesItem {
key: string;
value: string;
}
}import {
withAndroidManifest,
withStringsXml,
withAndroidColors,
withAppBuildGradle,
AndroidConfig,
ConfigPlugin
} from "@expo/config-plugins";
const withCompleteAndroidSetup: ConfigPlugin<{
appName: string;
primaryColor: string;
dependency: string;
}> = (config, { appName, primaryColor, dependency }) => {
// Update app name
config = withStringsXml(config, async (config) => {
AndroidConfig.Strings.setStringItem(
config.modResults,
"app_name",
appName
);
return config;
});
// Set primary color
config = withAndroidColors(config, async (config) => {
AndroidConfig.Colors.setColorItem(
config.modResults,
"colorPrimary",
primaryColor
);
return config;
});
// Add build dependency
config = withAppBuildGradle(config, async (config) => {
const buildGradle = config.modResults;
const depLine = ` implementation '${dependency}'`;
if (!buildGradle.contents.includes(dependency)) {
buildGradle.contents = buildGradle.contents.replace(
/(\s+dependencies\s*{[^}]*)/,
`$1\n${depLine}`
);
}
return config;
});
// Add manifest permissions
config = withAndroidManifest(config, async (config) => {
const manifest = config.modResults;
AndroidConfig.Permissions.ensurePermissions(manifest, [
"android.permission.INTERNET",
"android.permission.ACCESS_NETWORK_STATE"
]);
return config;
});
return config;
};const withResourceSetup: ConfigPlugin = (config) => {
// Setup colors for both light and dark themes
config = withAndroidColors(config, async (config) => {
const colors = config.modResults;
AndroidConfig.Colors.setColorItem(colors, "background", "#FFFFFF");
AndroidConfig.Colors.setColorItem(colors, "text", "#000000");
return config;
});
config = withAndroidColorsNight(config, async (config) => {
const colors = config.modResults;
AndroidConfig.Colors.setColorItem(colors, "background", "#000000");
AndroidConfig.Colors.setColorItem(colors, "text", "#FFFFFF");
return config;
});
// Setup custom styles
config = withAndroidStyles(config, async (config) => {
const styles = config.modResults;
AndroidConfig.Styles.setStylesItem(styles, "CustomButtonStyle", {
parent: "Widget.AppCompat.Button",
items: [
{ name: "android:textColor", value: "@color/text" },
{ name: "android:background", value: "@color/background" }
]
});
return config;
});
return config;
};