Trap of “ListPreference” with “%”


If you set “summary” that contains “%”, you’ll encounter mysterious error.

In developing on Android, when you dealing with preferences, you may use class “Preference”. Among them, it is “ListPreference” that you can use for selecting values in the form of a list.

listpreference
As shown in the figure above, when dealing with choices that include the character “%” in “ListPreference”, you need to be careful.

To indicate to the user the current settings, you can use the “summary” property. If you describe android:summary=”20%” in xml, or setSummary(“20%”) in source, you will be plagued by errors of unknown meaning. These errors you encounter are various patterns. Because you encounter them in unexpected situations, you will take the time to identify the cause.

“summary” is a format string (But on Honycomb or later)

The reason for this is because the “summary” is treated as a format string.
ListPreference | Android Developers

If the summary has a String formatting marker in it (i.e. “%s” or “%1$s”), then the current entry value will be substituted in its place when it’s retrieved.

As a result, the character “%” of a string such as “20%” is treated as a beginning of format string and it is an invalid format of course. So errors occur. Moreover, the cause becomes very confusing because the errors occur in the stage at displaying “summary” rather than reading “xml” or calling “setSummary”.

To avoid this error, if you want to display the “%”, you shoud specify “%%”. In other words, in order to display “20%”, specify setSummary(“20%%”).

It looks so convenient to be able to use format string and replace them to current values. However, the display may not be updated automatically when you change the setting. So “OnSharedPreferenceChangeListener” setting is not avoided. Therefore, it does not save you hassle.

Being more troublesome for you, it is not be mentioned specifically in the reference that “summary” is treated as format string on Honycomb or later but as normal string on Gingerbread or less. In other words, assuming setSummary(“20%%”), appear as “20%” in Honycomb or later but “20%%” in Gingerbread or less.

How should you deal with?

I think it is better to deal with them in the following manner.

  1. The initial value of the “summary”
    You should define them in the resource file (here, pref_default.xml) for each platform.

    [values/pref_default.xml]

    [values-v11/pref_default.xml]

    The values ​​defined in “values-v11” is only applied when the API level 11 or more. So, you can offer differnt value for Gingerbread (API level 9, 10) or less and for Honycomb (API level 12, 13) or later. Using this value, you can set the initial value of “summary” as follows.

    [preferences.xml]

  2. Dealing with the preference is changed
    In “onSharedPreferenceChanged”, you shoud write the code to add one more “%” when in Honycomb or later, as follows.

    * 2012/02/16 Moved findPreference to before setSummary.

At this point, you will be able to see properly “summary” of “ListPreference” on any platform.

[Reference Site]


Log folder of Proguard and .gitignore on IntelliJ


In Android development, output folder of logs of Porguard is different between Eclipse and IntelliJ. In this article, I will explain the difference and managing of Git.

Proguard and Log Files

Proguard is a Java obfuscator and optimizer. You can use it by preparing a little on Eclipse or IntelliJ. Then, if you export a signed “.apk”, log files of proguard are output. In the log files, mapping ifnormation, etc. are recorded. You can use them on debug of the exported “.apk”.

In Eclipse, a folder named “proguard” is made under the project folder as below. Log files will be output in it.
eclipse_proguard_log_compressed

On the other hands, in IntelliJ, the log folder is “proguard_logs”.
intellij_proguard_log

For now, we can not seem to specify the folder of our choice.(YouTRACK:Change Proguard logs output dir)

Git and Logs

To export “.apk” and to modify sources are not one-to-one correspondence. So you should not manage the logs in version control system. (You should save them on release.)

In Git, defining a file named “.gitignore”, you can exclude files to unmanage. You may get a template of “.gitignore” for android from GitHub:A collection of useful .gitignore templates, Android.gitignore. In current version, it support Eclipse and InttelliJ.

However, to support Proguard logs, the templates include definition for Eclipse, but not for IntelliJ. So you should add lines as below.

*2013/04/09 Supplement: Than before, I had to add this PullReques to github. From joeblau, I got a comment that my suggestions have been merged into templates generated by gitignore.io. (add Proguard folder generated by Intellij to Android.gitignore by junf · Pull Request #543 · github/gitignore)
gitignore.io is a service that will automatically generate “.gitignore” for your environment.


To clear the strikethrough of deprecated method in Eclipse


Android is upgraded frequently. Therefore, it is often the case that the old API methods is deprecated and a new method is recommended. Now, it is likely that API methods which have been adopted since 3.x (Honeycomb) is recommended and methods which can be used even less than 2.x are deprecated.

I think that if you can accommodate the situation by Support Library, it is the best to use new API. However, if the method is not supported by the library, you are not forced to use the old API. (At least, Gingerbread has a market share close to 50% yet. For more information, please refer to Dashboards.)

If you use the old methods deprecated in Eclipse, code becomes difficult to read because the “strikethrough” is marked with in the default setting. Then this does not disappear even with the @SuppressWarnings(“deprecation”).

I do not think that even without “strikethrough” you are troubled, because the lint will mark the following warning.
deprecated_method

So I tried to check the settings to turn off the “strikethrough”.

At development of Java (Including Android), to turn off the “strikethrough” for the deprecated method is as easy as following.

  1. Open the menu Window > Preferences > Java > Editor > Syntax Colorling
  2. In Element, select “Deprecated members
  3. Remove the check mark of Enable
  4. Click Apply

syntax_coloring-en
Alternatively, It is a good idea that leaving “Enable”, change the Color or change “Strikethrough” to “Underline”. Of course, if the recommended alternative method is available you should take advantage of that.