Android XML Percent Symbol

133,371

Solution 1

The Android Asset Packaging Tool (aapt) has become very strict in its latest release and is now used for all Android versions. The aapt-error you're getting is generated because it no longer allows non-positional format specifiers.

Here are a few ideas how you can include the %-symbol in your resource strings.

If you don't need any format specifiers or substitutions in your string you can simply make use of the formatted attribute and set it to false:

<string formatted="false">%a + %a == 2%a</string>

In this case the string is not used as a format string for the Formatter so you don't have to escape your %-symbols. The resulting string is "%a + %a == 2%a".

If you omit the formatted="false" attribute, the string is used as a format string and you have to escape the %-symbols. This is correctly done with double-%:

<string>%%a + %%a == 2%%a</string>

Now aapt gives you no errors but depending on how you use it, the resulting string can be "%%a + %%a == 2%%a" if a Formatter is invoked without any format arguments:

Resources res = context.getResources();

String s1 = res.getString(R.string.str);
// s1 == "%%a + %%a == 2%%a"

String s2 = res.getString(R.string.str, null);
// s2 == "%a + %a == 2%a"

Without any xml and code it is difficult to say what exactly your problem is but hopefully this helps you understand the mechanisms a little better.

Solution 2

To allow the app using formatted strings from resources you should correct your xml. So, for example

<string name="app_name">Your App name, ver.%d</string>

should be replaced with

<string name="app_name">Your App name, ver.%1$d</string>

You can see this for details.

Solution 3

You can escape % using %% for XML parser, but it is shown twice in device.

To show it once, try following format: \%%

For Example

<string name="zone_50">Fat Burning (50\%% to 60\%%)</string> 

is shown as Fat Burning (50% to 60%) in device

Solution 4

Use

<string name="win_percentage">%d%% wins</string>

to get

80% wins as a formatted string.

I'm using String.format() method to get the number inserted instead of %d.

Solution 5

to escape the percent symbol, you just need %%

for example :

String.format("%1$d%%", 10)

returns "10%"

Share:
133,371
zaid
Author by

zaid

Updated on September 30, 2022

Comments

  • zaid
    zaid over 1 year

    I have an array of strings in which the % symbol is used. Proper format for using the % is &#37;. When I have a string in that array with multiple &#37; it gives me this error.

     Multiple annotations found at this
     line:
     - error: Multiple substitutions specified in non-positional format;
       did you mean to add the formatted="false" attribute?
     - error: Found tag </item> where </string-array> is expected
    
  • zaid
    zaid over 13 years
    i selected this as the answer because it should work, but apparently there is a bug that im running into with that string, so ive decided to use %% and "XXX.replaceAll("%%", "%");"
  • Someone Somewhere
    Someone Somewhere almost 13 years
    using formatted=false works nicely. This is how I used it: <string name="information_description" formatted="false">\'Sweet\' 10% to 20% even 35% sugar by weight</string>
  • samwize
    samwize almost 13 years
    Yes it does escape with double %, and compile nicely. But when run on emulator, or even devices, it could show up as %%.
  • samwize
    samwize almost 13 years
    formatted=false works nicely for me too. Using %%, it literally showed up as %% on my device and emulator..
  • Jon Willis
    Jon Willis about 11 years
    \%% causes crashes on Nexus 4 4.2.1. Haven't tested others.
  • android developer
    android developer almost 11 years
    formatted=false worked fine for me in the past. now (ADT 22) , for some reason it doesn't. and if i use : " str=mContext.getString(R.string.str,"hello") " , it will have this lint warning: "Format string 'str' is not a valid format string so it should not be passed to String.format"
  • BeniBela
    BeniBela about 10 years
    That does not make any sense. &#x0025; and % are identical in a xml file.
  • Bahadır Yıldırım
    Bahadır Yıldırım about 10 years
    The resource file is converted into a Java resource, and in doing so, the % character returns. I'm afraid this doesn't resolve the problem.
  • akauppi
    akauppi almost 10 years
    Thanks, you provided the missing link - literally.
  • htafoya
    htafoya almost 10 years
    Forget it, I just needed to clean the project
  • Shishir Gupta
    Shishir Gupta almost 10 years
    If not for formatting purpose, this answer provides best way to do display any number of % symbols in view using XML and string resources.
  • Maurício Giordano
    Maurício Giordano about 9 years
    You should always use formatted="false" when using String.format.
  • CJBS
    CJBS about 9 years
    For multiple parameter substitution (e.g. with strings), use %1$s, %2$s etc.
  • Chintan Shah
    Chintan Shah over 8 years
    If you are accessing from <string-array/>, then for printing percentage use \u0025. This worked for me.
  • Ben Rhys-Lewis
    Ben Rhys-Lewis about 8 years
    Your answer is pretty much the same as several other existing answers
  • Janaka R Rajapaksha
    Janaka R Rajapaksha almost 8 years
    who will read such a big answer for this little thing? Thanks, I scroll down to find you.
  • Aranda
    Aranda over 7 years
    As per the answer from Paul E, on SDK 22 I had to add the dollars symbol to apply a format: %1$s and %2$d
  • portfoliobuilder
    portfoliobuilder about 7 years
    This works well and is easy when you already know the percent you want to include into your strings, versus using string formatter and always having to set those hardcoded values programmatically.
  • mtrakal
    mtrakal almost 7 years
    ... and wrong, because returns 10% not %10. FIY: When you use String.format you should everytime specify Locale. You can be really surprised when you don't put Locale and use Arabic locale for format numbers...
  • Chan Jing Hong
    Chan Jing Hong almost 7 years
    This crashed for me as well on Nexus 5.1.1. @ViliusK answer is the correct one.
  • Sundeep1501
    Sundeep1501 almost 6 years
    just use %% instead of %
  • Prinkal Kumar
    Prinkal Kumar over 5 years
    This solution leads to crashing .