3

In my (non Android test) test I placed a resource called common.properties in src/main/resources into my Android project to read the Maven project version from it:

@Test
public void testReadVersion() throws IOException {      
    Properties props = new Properties();
    props.load(FileUtils.openInputStream(FileUtils.toFile(this.getClass().getResource("/common.properties"))));

    String version = props.getProperty("version");

    assertNotNull(version);
    assertTrue(!"".equals(version));
}

This works. But when I try to access the same resource in production code, I always get NullPointerExceptions when accessing the resource:

    Properties props = new Properties();
    final StringBuilder versionBuilder = new StringBuilder();

    try {
        props.load(FileUtils.openInputStream(FileUtils.toFile(this.getClass().getResource("/common.properties"))));

        versionBuilder.append(props.getProperty("version"));
    } 
    catch (IOException e) {
        // will be ignored.
    }

I debugged it. It's null because it doesn't find the resource. How should I solve this? When I place the file into res/raw to read it by

props.load(getResources().openRawResource(R.raw.common));

the file access works, but it cannot translate the value from my file content: version=${project.version}. The result would be the value string itself ${project.version} and not Version 1.0 or something. What are my options?

[UPDATE]
The solution accepted below doesn't work in my latest project anymore. I always get ${project.version} instead of the value. Don't know why this is so. Not even the solution with AssetManager works for me. I found a good workaround which is less inconvenient too. I fetch and display the information of android:versionName (AndroidManifest).

String versionName = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;

TextView version = (TextView)findViewById(R.id.version);
version.setText(" " + versionName);
Bevor
  • 8,396
  • 15
  • 77
  • 141

2 Answers2

0

First i would suggest to use a simpler approach:

InputStream resourceAsStream = this.getClass().getResourceAsStream("/common.properties");
Properties prop = new Properties();
prop.load(resourceAsStream);

which will work either if you running in your tests or in production code. Furthermore to get values from the pom replaced within your resources you have to setup a filtering:

<project>
  ...
  <build>
    ...
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
      ...
    </resources>
    ...
  </build>
  ...
</project>
khmarbaise
  • 92,914
  • 28
  • 189
  • 235
  • I already had those Maven settings in my pom.xml, but I wonder why FileUtils cannot find the resource. Nevertheless, it works with your proposal, thanks. – Bevor Dec 24 '12 at 18:36
0

@khmarbaise solution doesn't work for me, so I've combined resource filtering (Dmitriy Tarasov example) and asset loading using AssetManager (described here).

Community
  • 1
  • 1
Pawel
  • 798
  • 8
  • 28