Inspects a link Configuration through reflection API to generate a human readable String with values replaced with their constants names. : String « Date Type « Android

Inspects a link Configuration through reflection API to generate a human readable String with values replaced with their constants names.

 *  Copyright 2010 Emmanuel Astier & Kevin Gaudin
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
//package org.acra.util;

//import static org.acra.ACRA.LOG_TAG;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;

import android.content.res.Configuration;
import android.util.Log;
import android.util.SparseArray;

 * Inspects a {@link Configuration} object through reflection API in order to
 * generate a human readable String with values replaced with their constants
 * names. The {@link Configuration#toString()} method was not enough as values
 * like 0, 1, 2 or 3 don't look readable to me. Using reflection API allows to
 * retrieve hidden fields and can make us hope to be compatible with all Android
 * API levels, even those which are not published yet.
 * @author Kevin Gaudin
final class ConfigurationInspector {

    private static final String SUFFIX_MASK = "_MASK";
    private static final String FIELD_SCREENLAYOUT = "screenLayout";
    private static final String FIELD_UIMODE = "uiMode";
    private static final String FIELD_MNC = "mnc";
    private static final String FIELD_MCC = "mcc";
    private static final String PREFIX_UI_MODE = "UI_MODE_";
    private static final String PREFIX_TOUCHSCREEN = "TOUCHSCREEN_";
    private static final String PREFIX_SCREENLAYOUT = "SCREENLAYOUT_";
    private static final String PREFIX_ORIENTATION = "ORIENTATION_";
    private static final String PREFIX_NAVIGATIONHIDDEN = "NAVIGATIONHIDDEN_";
    private static final String PREFIX_NAVIGATION = "NAVIGATION_";
    private static final String PREFIX_KEYBOARDHIDDEN = "KEYBOARDHIDDEN_";
    private static final String PREFIX_KEYBOARD = "KEYBOARD_";
    private static SparseArray<String> mHardKeyboardHiddenValues = new SparseArray<String>();
    private static SparseArray<String> mKeyboardValues = new SparseArray<String>();
    private static SparseArray<String> mKeyboardHiddenValues = new SparseArray<String>();
    private static SparseArray<String> mNavigationValues = new SparseArray<String>();
    private static SparseArray<String> mNavigationHiddenValues = new SparseArray<String>();
    private static SparseArray<String> mOrientationValues = new SparseArray<String>();
    private static SparseArray<String> mScreenLayoutValues = new SparseArray<String>();
    private static SparseArray<String> mTouchScreenValues = new SparseArray<String>();
    private static SparseArray<String> mUiModeValues = new SparseArray<String>();

    private static final HashMap<String, SparseArray<String>> mValueArrays = new HashMap<String, SparseArray<String>>();

    // Static init
    static {
        mValueArrays.put(PREFIX_HARDKEYBOARDHIDDEN, mHardKeyboardHiddenValues);
        mValueArrays.put(PREFIX_KEYBOARD, mKeyboardValues);
        mValueArrays.put(PREFIX_KEYBOARDHIDDEN, mKeyboardHiddenValues);
        mValueArrays.put(PREFIX_NAVIGATION, mNavigationValues);
        mValueArrays.put(PREFIX_NAVIGATIONHIDDEN, mNavigationHiddenValues);
        mValueArrays.put(PREFIX_ORIENTATION, mOrientationValues);
        mValueArrays.put(PREFIX_SCREENLAYOUT, mScreenLayoutValues);
        mValueArrays.put(PREFIX_TOUCHSCREEN, mTouchScreenValues);
        mValueArrays.put(PREFIX_UI_MODE, mUiModeValues);

        for (final Field f : Configuration.class.getFields()) {
            if (Modifier.isStatic(f.getModifiers()) && Modifier.isFinal(f.getModifiers())) {
                final String fieldName = f.getName();
                try {
                    if (fieldName.startsWith(PREFIX_HARDKEYBOARDHIDDEN)) {
                        mHardKeyboardHiddenValues.put(f.getInt(null), fieldName);
                    } else if (fieldName.startsWith(PREFIX_KEYBOARD)) {
                        mKeyboardValues.put(f.getInt(null), fieldName);
                    } else if (fieldName.startsWith(PREFIX_KEYBOARDHIDDEN)) {
                        mKeyboardHiddenValues.put(f.getInt(null), fieldName);
                    } else if (fieldName.startsWith(PREFIX_NAVIGATION)) {
                        mNavigationValues.put(f.getInt(null), fieldName);
                    } else if (fieldName.startsWith(PREFIX_NAVIGATIONHIDDEN)) {
                        mNavigationHiddenValues.put(f.getInt(null), fieldName);
                    } else if (fieldName.startsWith(PREFIX_ORIENTATION)) {
                        mOrientationValues.put(f.getInt(null), fieldName);
                    } else if (fieldName.startsWith(PREFIX_SCREENLAYOUT)) {
                        mScreenLayoutValues.put(f.getInt(null), fieldName);
                    } else if (fieldName.startsWith(PREFIX_TOUCHSCREEN)) {
                        mTouchScreenValues.put(f.getInt(null), fieldName);
                    } else if (fieldName.startsWith(PREFIX_UI_MODE)) {
                        mUiModeValues.put(f.getInt(null), fieldName);
                } catch (IllegalArgumentException e) {
                 //   Log.w(LOG_TAG, "Error while inspecting device configuration: ", e);
                } catch (IllegalAccessException e) {
                 //   Log.w(LOG_TAG, "Error while inspecting device configuration: ", e);

     * Use this method to generate a human readable String listing all values
     * from the provided Configuration instance.
     * @param conf
     *            The Configuration to be described.
     * @return A String describing all the fields of the given Configuration,
     *         with values replaced by constant names.
    public static String toString(Configuration conf) {
        final StringBuilder result = new StringBuilder();
        for (final Field f : conf.getClass().getFields()) {
            try {
                if (!Modifier.isStatic(f.getModifiers())) {
                    final String fieldName = f.getName();
                    if (f.getType().equals(int.class)) {
                        result.append(getFieldValueName(conf, f));
                    } else {
            } catch (IllegalArgumentException e) {
              //  Log.e(LOG_TAG, "Error while inspecting device configuration: ", e);
            } catch (IllegalAccessException e) {
             //   Log.e(LOG_TAG, "Error while inspecting device configuration: ", e);
        return result.toString();

     * Retrieve the name of the constant defined in the {@link Configuration}
     * class which defines the value of a field in a {@link Configuration}
     * instance.
     * @param conf
     *            The instance of {@link Configuration} where the value is
     *            stored.
     * @param f
     *            The {@link Field} to be inspected in the {@link Configuration}
     *            instance.
     * @return The value of the field f in instance conf translated to its
     *         constant name.
     * @throws IllegalAccessException if the supplied field is inaccessible.
    private static String getFieldValueName(Configuration conf, Field f) throws IllegalAccessException {
        final String fieldName = f.getName();
        if (fieldName.equals(FIELD_MCC) || fieldName.equals(FIELD_MNC)) {
            return Integer.toString(f.getInt(conf));
        } else if (fieldName.equals(FIELD_UIMODE)) {
            return activeFlags(mValueArrays.get(PREFIX_UI_MODE), f.getInt(conf));
        } else if (fieldName.equals(FIELD_SCREENLAYOUT)) {
            return activeFlags(mValueArrays.get(PREFIX_SCREENLAYOUT), f.getInt(conf));
        } else {
            final SparseArray<String> values = mValueArrays.get(fieldName.toUpperCase() + '_');
            if (values == null) {
                // Unknown field, return the raw int as String
                return Integer.toString(f.getInt(conf));

            final String value = values.get(f.getInt(conf));
            if (value == null) {
                // Unknown value, return the raw int as String
                return Integer.toString(f.getInt(conf));
            return value;

     * Some fields contain multiple value types which can be isolated by
     * applying a bitmask. That method returns the concatenation of active
     * values.
     * @param valueNames
     *            The array containing the different values and names for this
     *            field. Must contain mask values too.
     * @param bitfield
     *            The bitfield to inspect.
     * @return The names of the different values contained in the bitfield,
     *         separated by '+'.
    private static String activeFlags(SparseArray<String> valueNames, int bitfield) {
        final StringBuilder result = new StringBuilder();

        // Look for masks, apply it an retrieve the masked value
        for (int i = 0; i < valueNames.size(); i++) {
            final int maskValue = valueNames.keyAt(i);
            if (valueNames.get(maskValue).endsWith(SUFFIX_MASK)) {
                final int value = bitfield & maskValue;
                if (value > 0) {
                    if (result.length() > 0) {
        return result.toString();


Related examples in the same category

1.Split with
2.Split first with
3.split By Space and save result to a List
4.Space trim
5.truncate by length
6.Remove all blanks
7.Is a string a Number
8.Random string
9.Tokenizer. Why? Because StringTokenizer is not available in J2ME.
10.String resource
11.Shows creating text with links from HTML in the Java code, rather than from a string resource. Note that for a
12.Join a collection of strings by a seperator
13.Tests if a string is blank: null, emtpy, or only whitespace (" ", \r\n, \t, etc)
14.Tests if a string is numeric, i.e. contains only digit characters
15.Writer implementation that outputs to a StringBuilder
16.Gets the device's phone number as a String.
17.Returns a String representation of the content of a android.view.Display object.
18.Get String Element Value
19.Join strings
20.Find two consecutive newlines in a string.
21.Retrieve a boolean primitive type from a String.
22.Trim char from string
23.Returns true if the string does not fit in standard ASCII
24.Returns true if the given string is null or empty.
25.4 octets in address string
26.Add space to CSV string
27.String fast Split
28.Split a String by a Character, i.e. Split lines by using '\n'
29.String Capitalizer
30.Count char in a string
31.Search char in a string from a starting position
32.load String From Raw Resource
33.Join Collection of String
34.Padding a string, truncate a string
35.Converts a string to title casing.
36.reversing String
37.load Resource To String
38.convert Duration to String
39.Convert string from one encoding to another
40.Object to String and String to Object
41.IP to String
42.Convert string to bumber and convert number to string
43.line string reader in J2ME
44.String to Map with token
45.Generate the client id, which is a fixed string of length 8 concatenated with 12 random bytes
46.StringBuilder Writer
47.Return a specific raw resource contents as a String value.
48.Returns the ISO 8601-format String corresponding to the given duration (measured in milliseconds).
49.Returns a string representation of the given number of nanoseconds.
50.Simple Tokenizer
51.split By Space
52.Pad Front
53.Count Occurrences
54.Padding Left
55.captalize Words
56.Tokenizer Utils
57.Returns space padding
58.Normalise Whitespace
59.Removes unwanted blank characters
60.Removes unwanted backslashes characters
61.equals Ignore Case
62.A method to decode/encode quoted printable encoded data
63.Title Name Parser
64.Split Camal Case
65.Split and combine by token
66.Shorten text for display in lists etc.