Android Open Source - qrcode-android Decode Hint Manager






From Project

Back to project page qrcode-android.

License

The source code is released under:

MIT License

If you think the Android project qrcode-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2013 ZXing authors/*w  w w  .j  a v  a  2 s  . c  om*/
 *
 * 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
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 com.google.zxing.client.android;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import com.google.zxing.DecodeHintType;

import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @author Lachezar Dobrev
 */
final class DecodeHintManager
{

    private static final String TAG = DecodeHintManager.class.getSimpleName();

    // This pattern is used in decoding integer arrays.
    private static final Pattern COMMA = Pattern.compile(",");

    private DecodeHintManager()
    {
    }

    /**
     * <p>Split a query string into a list of name-value pairs.</p>
     * <p/>
     * <p>This is an alternative to the {@link Uri#getQueryParameterNames()} and
     * {@link Uri#getQueryParameters(String)}, which are quirky and not suitable
     * for exist-only Uri parameters.</p>
     * <p/>
     * <p>This method ignores multiple parameters with the same name and returns the
     * first one only. This is technically incorrect, but should be acceptable due
     * to the method of processing Hints: no multiple values for a hint.</p>
     *
     * @param query query to split
     * @return name-value pairs
     */
    private static Map<String, String> splitQuery(String query)
    {
        Map<String, String> map = new HashMap<String, String>();
        int pos = 0;
        while (pos < query.length())
        {
            if (query.charAt(pos) == '&')
            {
                // Skip consecutive ampersand separators.
                pos++;
                continue;
            }
            int amp = query.indexOf('&', pos);
            int equ = query.indexOf('=', pos);
            if (amp < 0)
            {
                // This is the last element in the query, no more ampersand elements.
                String name;
                String text;
                if (equ < 0)
                {
                    // No equal sign
                    name = query.substring(pos);
                    name = name.replace('+', ' '); // Preemptively decode +
                    name = Uri.decode(name);
                    text = "";
                } else
                {
                    // Split name and text.
                    name = query.substring(pos, equ);
                    name = name.replace('+', ' '); // Preemptively decode +
                    name = Uri.decode(name);
                    text = query.substring(equ + 1);
                    text = text.replace('+', ' '); // Preemptively decode +
                    text = Uri.decode(text);
                }
                if (!map.containsKey(name))
                {
                    map.put(name, text);
                }
                break;
            }
            if (equ < 0 || equ > amp)
            {
                // No equal sign until the &: this is a simple parameter with no value.
                String name = query.substring(pos, amp);
                name = name.replace('+', ' '); // Preemptively decode +
                name = Uri.decode(name);
                if (!map.containsKey(name))
                {
                    map.put(name, "");
                }
                pos = amp + 1;
                continue;
            }
            String name = query.substring(pos, equ);
            name = name.replace('+', ' '); // Preemptively decode +
            name = Uri.decode(name);
            String text = query.substring(equ + 1, amp);
            text = text.replace('+', ' '); // Preemptively decode +
            text = Uri.decode(text);
            if (!map.containsKey(name))
            {
                map.put(name, text);
            }
            pos = amp + 1;
        }
        return map;
    }

    static Map<DecodeHintType, ?> parseDecodeHints(Uri inputUri)
    {
        String query = inputUri.getEncodedQuery();
        if (query == null || query.length() == 0)
        {
            return null;
        }

        // Extract parameters
        Map<String, String> parameters = splitQuery(query);

        Map<DecodeHintType, Object> hints = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);

        for (DecodeHintType hintType : DecodeHintType.values())
        {

            if (hintType == DecodeHintType.CHARACTER_SET ||
                        hintType == DecodeHintType.NEED_RESULT_POINT_CALLBACK ||
                        hintType == DecodeHintType.POSSIBLE_FORMATS)
            {
                continue; // This hint is specified in another way
            }

            String parameterName = hintType.name();
            String parameterText = parameters.get(parameterName);
            if (parameterText == null)
            {
                continue;
            }
            if (hintType.getValueType().equals(Object.class))
            {
                // This is an unspecified type of hint content. Use the value as is.
                // TODO: Can we make a different assumption on this?
                hints.put(hintType, parameterText);
                continue;
            }
            if (hintType.getValueType().equals(Void.class))
            {
                // Void hints are just flags: use the constant specified by DecodeHintType
                hints.put(hintType, Boolean.TRUE);
                continue;
            }
            if (hintType.getValueType().equals(String.class))
            {
                // A string hint: use the decoded value.
                hints.put(hintType, parameterText);
                continue;
            }
            if (hintType.getValueType().equals(Boolean.class))
            {
                // A boolean hint: a few values for false, everything else is true.
                // An empty parameter is simply a flag-style parameter, assuming true
                if (parameterText.length() == 0)
                {
                    hints.put(hintType, Boolean.TRUE);
                } else if ("0".equals(parameterText) ||
                                   "false".equalsIgnoreCase(parameterText) ||
                                   "no".equalsIgnoreCase(parameterText))
                {
                    hints.put(hintType, Boolean.FALSE);
                } else
                {
                    hints.put(hintType, Boolean.TRUE);
                }

                continue;
            }
            if (hintType.getValueType().equals(int[].class))
            {
                // An integer array. Used to specify valid lengths.
                // Strip a trailing comma as in Java style array initialisers.
                if (parameterText.length() > 0 && parameterText.charAt(parameterText.length() - 1) == ',')
                {
                    parameterText = parameterText.substring(0, parameterText.length() - 1);
                }
                String[] values = COMMA.split(parameterText);
                int[] array = new int[values.length];
                for (int i = 0; i < values.length; i++)
                {
                    try
                    {
                        array[i] = Integer.parseInt(values[i]);
                    } catch (NumberFormatException ignored)
                    {
                        Log.w(TAG, "Skipping array of integers hint " + hintType + " due to invalid numeric value: '" + values[i] + '\'');
                        array = null;
                        break;
                    }
                }
                if (array != null)
                {
                    hints.put(hintType, array);
                }
                continue;
            }
            Log.w(TAG, "Unsupported hint type '" + hintType + "' of type " + hintType.getValueType());
        }

        Log.i(TAG, "Hints from the URI: " + hints);
        return hints;
    }

    static Map<DecodeHintType, Object> parseDecodeHints(Intent intent)
    {
        Bundle extras = intent.getExtras();
        if (extras == null || extras.isEmpty())
        {
            return null;
        }
        Map<DecodeHintType, Object> hints = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);

        for (DecodeHintType hintType : DecodeHintType.values())
        {

            if (hintType == DecodeHintType.CHARACTER_SET ||
                        hintType == DecodeHintType.NEED_RESULT_POINT_CALLBACK ||
                        hintType == DecodeHintType.POSSIBLE_FORMATS)
            {
                continue; // This hint is specified in another way
            }

            String hintName = hintType.name();
            if (extras.containsKey(hintName))
            {
                if (hintType.getValueType().equals(Void.class))
                {
                    // Void hints are just flags: use the constant specified by the DecodeHintType
                    hints.put(hintType, Boolean.TRUE);
                } else
                {
                    Object hintData = extras.get(hintName);
                    if (hintType.getValueType().isInstance(hintData))
                    {
                        hints.put(hintType, hintData);
                    } else
                    {
                        Log.w(TAG, "Ignoring hint " + hintType + " because it is not assignable from " + hintData);
                    }
                }
            }
        }

        Log.i(TAG, "Hints from the Intent: " + hints);
        return hints;
    }

}




Java Source Code List

com.google.zxing.client.android.BeepManager.java
com.google.zxing.client.android.CaptureActivityHandler.java
com.google.zxing.client.android.CaptureActivity.java
com.google.zxing.client.android.Contents.java
com.google.zxing.client.android.DecodeFormatManager.java
com.google.zxing.client.android.DecodeHandler.java
com.google.zxing.client.android.DecodeHintManager.java
com.google.zxing.client.android.DecodeThread.java
com.google.zxing.client.android.FinishListener.java
com.google.zxing.client.android.InactivityTimer.java
com.google.zxing.client.android.IntentSource.java
com.google.zxing.client.android.Intents.java
com.google.zxing.client.android.LocaleManager.java
com.google.zxing.client.android.ViewfinderResultPointCallback.java
com.google.zxing.client.android.ViewfinderView.java
com.google.zxing.client.android.camera.AutoFocusManager.java
com.google.zxing.client.android.camera.CameraConfigurationManager.java
com.google.zxing.client.android.camera.CameraManager.java
com.google.zxing.client.android.camera.FrontLightMode.java
com.google.zxing.client.android.camera.PreviewCallback.java
com.google.zxing.client.android.camera.exposure.DefaultExposureInterface.java
com.google.zxing.client.android.camera.exposure.ExposureInterface.java
com.google.zxing.client.android.camera.exposure.ExposureManager.java
com.google.zxing.client.android.camera.exposure.FroyoExposureInterface.java
com.google.zxing.client.android.camera.open.DefaultOpenCameraInterface.java
com.google.zxing.client.android.camera.open.GingerbreadOpenCameraInterface.java
com.google.zxing.client.android.camera.open.OpenCameraInterface.java
com.google.zxing.client.android.camera.open.OpenCameraManager.java
com.google.zxing.client.android.common.PlatformSupportManager.java
com.google.zxing.client.android.common.executor.AsyncTaskExecInterface.java
com.google.zxing.client.android.common.executor.AsyncTaskExecManager.java
com.google.zxing.client.android.common.executor.DefaultAsyncTaskExecInterface.java
com.google.zxing.client.android.common.executor.HoneycombAsyncTaskExecInterface.java
com.google.zxing.extra.RGBLuminanceSource.java
eu.livotov.zxscan.AutofocusMode.java
eu.livotov.zxscan.ZXScanHelper.java
eu.livotov.zxscan.ZXUserCallback.java
tw.soleil.constant.Constants.java
tw.soleil.qrcodereadertest.QRCodeReaderTestActivity.java
tw.soleil.service.InvoiceService.java
tw.soleil.to.InvoiceDtl.java
tw.soleil.to.Invoice.java
tw.soleil.util.DateUtil.java
tw.soleil.util.Utils.java