如何使用Maven为Android项目过滤资源?

时间:2013-09-18 09:52:08

标签: android maven android-xml properties-file maven-resources-plugin

我想使用Maven Resources Filtering plugin从外部为Android项目定义敏感配置数据。因此,我创建了一个包含敏感数据的.properties文件。它被排除在版本控制之外。

# /.app_config.properties
# Application configuration
#
# Do not add this file to source control.
# The values are read and inserted into source files by Maven.

google.maps.v2.api.key = abc123
api.base.url = https://example.com/api

在Android项目中,我在一个单独的.xml文件中管理所有敏感数据:

<!-- /res/values/app_config.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>    
  <string name="config_google_maps_v2_api_key">ENTER_YOUR_GOOGLE_MAPS_V2_API_KEY_HERE</string>
  <string name="config_base_url">ENTER_YOUR_SERVER_URL_HERE</string>
</resources>

对于Maven,我创建了另一个.xml文件,该文件告诉在构建.apk时应该替换哪些字符串:

<!-- /filteres-res/app_config.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>    
  <string name="config_google_maps_v2_api_key">${google.maps.v2.api.key}</string>
  <string name="config_base_url">${api.base.url}</string>
</resources>

以下是 Maven过滤 pom.xml的相关部分:

<!-- /pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <!-- Sure there is more configuration here -->

  <build>
    <finalName>${project.artifactId}</finalName>
    <sourceDirectory>src</sourceDirectory>
    <filters>
      <filter>${project.basedir}/.app_config.properties</filter>
    </filters>
    <resources>
      <resource>
        <directory>${project.basedir}/filtered-res</directory>
        <filtering>true</filtering>
        <targetPath>${project.basedir}/res/values/</targetPath>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
      <resource>
        <directory>${project.basedir}/filtered-res</directory>
        <filtering>false</filtering>
        <excludes>
          <exclude>**/*.xml</exclude>
        </excludes>
      </resource>
    </resources>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>com.jayway.maven.plugins.android.generation2</groupId>
          <artifactId>android-maven-plugin</artifactId>
          <version>${android-maven-plugin.version}</version>
          <extensions>true</extensions>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>${maven-compiler-plugin.version}</version>
          <configuration>
            <compilerArgument>-Xlint:deprecation</compilerArgument>
            <!-- <resourceDirectory>${project.build.directory}/filtered-res</resourceDirectory> -->
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
    <plugins>
      <plugin>
        <groupId>com.jayway.maven.plugins.android.generation2</groupId>
        <artifactId>android-maven-plugin</artifactId>
        <configuration>
          <sdk>
            <platform>${sdk.platform}</platform>
          </sdk>
          <undeployBeforeDeploy>true</undeployBeforeDeploy>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>${maven-resources-plugin.version}</version>
        <executions>
          <execution>
            <phase>initialize</phase>
            <goals>
              <goal>resources</goal>
            </goals>
          </execution>
          <execution>
            <id>default-resources</id>
            <phase>DISABLED</phase>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

</project>

问题是敏感数据实际写入/res/values/app_config.xml而不是仅写入构建。这是构建后文件的样子:

<!-- /res/values/app_config.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>    
  <string name="config_google_maps_v2_api_key">abc123</string>
  <string name="config_base_url">https://example.com/api</string>
</resources>

2 个答案:

答案 0 :(得分:2)

所描述的效果是由资源规范中的targetPath创建的,它会过滤源文件并在之后覆盖它。

以下两种配置都将复制构建文件夹中的过滤后的资源:

<resources>
  <resource>
    ...
    <!-- following defines a replacement target in the source part -->
    <targetPath>${project.basedir}/res/values/</targetPath>
    ...
</resource>

或者你正确定义

<resources>
  <resource>
    ...
    <targetPath>${project.build.directory}/res/values/</targetPath>
    ...
</resource>

但这不会创建合适的apk,因为com.jayway.maven.plugins.android.generation2:android-maven-plugin不会使用构建文件夹中的文件。

作为结论我们可以说,没有办法使用资源过滤器和com.jayway.maven.plugins.android.generation2:android-maven-plugin。 可能正在替换创建的未签名的apk中的xml文件,或者在使用原始构建后替换xml文件。

答案 1 :(得分:0)

在Android Maven插件中,您可以设置从哪里读取资源文件,因此在您的pom中,您将拥有以下内容:

  <plugin>
    <groupId>com.jayway.maven.plugins.android.generation2</groupId>
    <artifactId>android-maven-plugin</artifactId>
    <configuration>
      <sdk>
        <platform>${sdk.platform}</platform>
      </sdk>
      <undeployBeforeDeploy>true</undeployBeforeDeploy>
      <resourceDirectory>${project.build.directory}/res</resourceDirectory>
    </configuration>
  </plugin>

 <resources>
   <resource>
     ...
     <targetPath>${project.build.directory}/res</targetPath>
     ...
 </resource>

链接:android-maven-plugin and resource filtering

希望这有帮助。