diff --git a/src/Plugins/Compilers/AndroidPluginCompiler.php b/src/Plugins/Compilers/AndroidPluginCompiler.php
index 1f6ee29..d12a3db 100644
--- a/src/Plugins/Compilers/AndroidPluginCompiler.php
+++ b/src/Plugins/Compilers/AndroidPluginCompiler.php
@@ -496,6 +496,9 @@ protected function buildMetaDataEntry(array $metaData): string
// Handle different value types
if (is_bool($value)) {
$value = $value ? 'true' : 'false';
+ } elseif (is_string($value)) {
+ // Substitute ${ENV_VAR} placeholders, mirroring iOS info_plist handling
+ $value = $this->substituteEnvPlaceholders($value);
}
return "";
@@ -648,6 +651,9 @@ protected function buildComponentMetaData(array $metaDataEntries): string
} elseif ($value !== null) {
if (is_bool($value)) {
$value = $value ? 'true' : 'false';
+ } elseif (is_string($value)) {
+ // Substitute ${ENV_VAR} placeholders, mirroring iOS info_plist handling
+ $value = $this->substituteEnvPlaceholders($value);
}
$xml .= " \n";
}
diff --git a/tests/Feature/Plugins/AndroidCompilerTest.php b/tests/Feature/Plugins/AndroidCompilerTest.php
index f7e048c..7acf701 100644
--- a/tests/Feature/Plugins/AndroidCompilerTest.php
+++ b/tests/Feature/Plugins/AndroidCompilerTest.php
@@ -693,6 +693,90 @@ public function it_adds_meta_data_with_value_inside_service(): void
$this->assertStringContainsString('', $content);
}
+ /**
+ * @test
+ *
+ * Application-level meta-data values should have ${ENV_VAR} placeholders
+ * substituted from the environment, matching iOS info_plist handling.
+ */
+ public function it_substitutes_env_placeholders_in_application_meta_data(): void
+ {
+ putenv('NATIVEPHP_TEST_META_KEY=resolved-secret');
+ $_ENV['NATIVEPHP_TEST_META_KEY'] = 'resolved-secret';
+
+ try {
+ $plugin = $this->createTestPlugin([
+ 'android' => [
+ 'permissions' => [],
+ 'dependencies' => [],
+ 'meta_data' => [
+ ['name' => 'com.example.API_KEY', 'value' => '${NATIVEPHP_TEST_META_KEY}'],
+ ],
+ ],
+ ]);
+
+ $this->mockRegistry
+ ->shouldReceive('all')
+ ->andReturn(collect([$plugin]));
+
+ $this->compiler->compile();
+
+ $manifestPath = $this->testBasePath.'/android/app/src/main/AndroidManifest.xml';
+ $content = $this->files->get($manifestPath);
+
+ $this->assertStringContainsString('', $content);
+ $this->assertStringNotContainsString('${NATIVEPHP_TEST_META_KEY}', $content);
+ } finally {
+ putenv('NATIVEPHP_TEST_META_KEY');
+ unset($_ENV['NATIVEPHP_TEST_META_KEY']);
+ }
+ }
+
+ /**
+ * @test
+ *
+ * Component-level (service) meta-data values should also have ${ENV_VAR}
+ * placeholders substituted from the environment.
+ */
+ public function it_substitutes_env_placeholders_in_service_meta_data(): void
+ {
+ putenv('NATIVEPHP_TEST_META_KEY=resolved-secret');
+ $_ENV['NATIVEPHP_TEST_META_KEY'] = 'resolved-secret';
+
+ try {
+ $plugin = $this->createTestPlugin([
+ 'android' => [
+ 'permissions' => [],
+ 'dependencies' => [],
+ 'services' => [
+ [
+ 'name' => 'com.example.MyService',
+ 'exported' => false,
+ 'meta_data' => [
+ ['name' => 'com.example.API_KEY', 'value' => '${NATIVEPHP_TEST_META_KEY}'],
+ ],
+ ],
+ ],
+ ],
+ ]);
+
+ $this->mockRegistry
+ ->shouldReceive('all')
+ ->andReturn(collect([$plugin]));
+
+ $this->compiler->compile();
+
+ $manifestPath = $this->testBasePath.'/android/app/src/main/AndroidManifest.xml';
+ $content = $this->files->get($manifestPath);
+
+ $this->assertStringContainsString('', $content);
+ $this->assertStringNotContainsString('${NATIVEPHP_TEST_META_KEY}', $content);
+ } finally {
+ putenv('NATIVEPHP_TEST_META_KEY');
+ unset($_ENV['NATIVEPHP_TEST_META_KEY']);
+ }
+ }
+
/**
* @test
*