I was able to get this working by following the "MyActivity" example given by @alex-aelenei, however, I also had to add a plugin to correctly update the AndroidManifest.xml file, otherwise I received the following error when starting the activity:
expo android.content.ActivityNotFoundException: Unable to find explicit activity class {example.com/expo.modules.mymodule.MyActivity}; have you declared this activity in your AndroidManifest.xml, or does your intent not match its declared <intent-filter>?
I added a file ./plugin/android/withAndroidCustomActivity.js
that contains the following (taken from https://forums.expo.dev/t/how-to-create-a-plugin-that-writes-a-new-activity-in-manifes-xml/68257/6 and modified):
const { withAndroidManifest } = require("@expo/config-plugins");
const customActivity = {
$: {
"android:name": "expo.modules.mymodule.MyActivity",
},
};
function addCustomActivityToMainApplication(androidManifest, attributes) {
const { manifest } = androidManifest;
// Check if there are any application tags
if (!Array.isArray(manifest.application)) {
console.warn(
"withAndroidMainActivityAttributes: No application array in manifest?",
);
return androidManifest;
}
// Find the "application" called ".MainApplication"
const application = manifest.application.find(
(item) => item.$["android:name"] === ".MainApplication",
);
if (!application) {
console.warn("addCustomActivityToMainApplication: No .MainApplication?");
return androidManifest;
}
// Check if there are any activity tags
const activities = application.activity;
if (!Array.isArray(activities)) {
console.warn(
"addCustomActivityToMainApplication: No activity array in .MainApplication?",
);
return androidManifest;
}
// If we don't find the custom activity, add it
// If we do find it, assume it's correct
if (
!activities.find(
(item) => item.$["android:name"] === "expo.modules.mymodule.MyActivity",
)
) {
activities.push(customActivity);
}
return androidManifest;
}
module.exports = function withAndroidCustomActivity(config, attributes) {
return withAndroidManifest(config, (config) => {
config.modResults = addCustomActivityToMainApplication(
config.modResults,
attributes,
);
return config;
});
};
and updating my app.config.js
to include:
plugins: [<other plugins (e.g. "expo-router")>, "./plugin/android/withAndroidCustomActivity.js"],
I also had to run npx expo prebuild -p android
to correctly regenerate the AndroidManifest file