Android Open Source - bankomatinfos Utils






From Project

Back to project page bankomatinfos.

License

The source code is released under:

GNU General Public License

If you think the Android project bankomatinfos 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

package at.zweng.bankomatinfos.util;
//ww w .  j a  va2  s. c om
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.ByteBuffer;
import java.security.InvalidParameterException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.text.Html;
import android.text.Spanned;
import android.util.Log;
import at.zweng.bankomatinfos.ui.AboutDialogFragment;
import at.zweng.bankomatinfos.ui.ChangelogDialogFragment;
import at.zweng.bankomatinfos2.R;

/**
 * Some static helper methods
 * 
 * @author Johannes Zweng <johannes@zweng.at>
 */
public class Utils {

  /**
   * Log tag
   */
  public final static String TAG = "BankomatInfos";

  private static SimpleDateFormat fullTimeWithDateFormat = new SimpleDateFormat(
      "dd.MM.yyyy HH:mm:ss", Locale.US);

  private static SimpleDateFormat dateOnlyDateFormat = new SimpleDateFormat(
      "dd.MM.yyyy", Locale.US);

  private final static SimpleDateFormat fullTimeMilliseconds = new SimpleDateFormat(
      "HH:mm:ss.SSS", Locale.US);

  /**
   * Helper method, returns current time as string
   * 
   * @return
   */
  public static String getFullTimestampString() {
    return fullTimeMilliseconds.format(new Date());
  }

  /**
   * Returns a hexadecimal String representation of a byte array (without
   * spaces)
   * 
   * @param bytes
   * @return
   */
  public static String bytesToHex(byte[] bytes) {
    final char[] hexArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
        '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    char[] hexChars = new char[bytes.length * 2];
    int v;
    for (int j = 0; j < bytes.length; j++) {
      v = bytes[j] & 0xFF;
      hexChars[j * 2] = hexArray[v >>> 4];
      hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
  }

  /**
   * Returns a hexadecimal String representation of a byte array (without
   * spaces), also null parameter allowed
   * 
   * @param bytes
   * @return
   */
  public static String bytesToHexNullAllowed(byte[] bytes) {
    if (bytes == null) {
      return "<null>";
    }
    return bytesToHex(bytes);
  }

  /**
   * @param b
   * @return hex representation as string
   */
  public static String byte2Hex(byte b) {
    String[] HEX_DIGITS = { "0", "1", "2", "3", "4", "5", "6", "7", "8",
        "9", "A", "B", "C", "D", "E", "F" };
    int nb = b & 0xFF;
    int i_1 = (nb >> 4) & 0xF;
    int i_2 = nb & 0xF;
    return HEX_DIGITS[i_1] + HEX_DIGITS[i_2];
  }

  /**
   * Takes an string and inserts a whitespace every second char
   * 
   * @param in
   *            hex string (or any other string) (ex: "0011AAEEFF")
   * @return string with inserted whitespaces (ex: "00 11 AA EE FF")
   */
  public static String prettyPrintString(String in, int groupCount) {
    StringBuilder buf = new StringBuilder();
    for (int i = 0; i < in.length(); i++) {
      char c = in.charAt(i);
      buf.append(c);
      int nextPos = i + 1;
      if (nextPos % groupCount == 0 && nextPos != in.length()) {
        buf.append(" ");
      }
    }
    return buf.toString();
  }

  /**
   * returns a new byte array containing only the last 2 bytes of the input
   * array
   * 
   * @param input
   * @return
   */
  public static byte[] getLast2Bytes(byte[] input) {
    if (input == null) {
      throw new IllegalArgumentException("getLast2Bytes: input was null");
    }
    if (input.length < 2) {
      throw new IllegalArgumentException(
          "getLast2Bytes: input was shorter than 2 bytes");
    }
    byte[] output = new byte[2];
    output[0] = input[(input.length) - 2];
    output[1] = input[(input.length) - 1];
    return output;
  }

  /**
   * Dumb helper method, only used to compare 2 byte arrays
   * 
   * @param first
   * @param second
   * @return true only if both arrays are identical
   */
  public static boolean compare2byteArrays(byte[] first, byte[] second) {
    if (first == null)
      return false;
    if (second == null)
      return false;
    if (first.length != second.length)
      return false;
    for (int i = 0; i < first.length; i++) {
      if (first[i] != second[i]) {
        return false;
      }
    }
    return true;
  }

  /**
   * @param balance
   * @return
   */
  public static String formatBalance(long balance) {
    if (balance < 100) {
      return "0,"
          + String.format(Locale.GERMANY, "%02d",
              Long.valueOf(balance % 100L));
    }
    String format;
    format = "%,d";
    // format = "%d";
    return String.format(Locale.GERMANY, format, (balance / 100L))
        + ","
        + String.format(Locale.GERMANY, "%02d",
            Long.valueOf(balance % 100L));
  }

  /**
   * Reads a long value out of a byte array, beginning on the given offset and
   * the given length
   * 
   * @param rawData
   * @param offset
   * @param lenght
   * @return
   * @throws InvalidParameterException
   */
  public static long readLongFromBytes(byte[] rawData, int offset, int lenght)
      throws InvalidParameterException {
    if (lenght > 8) {
      throw new InvalidParameterException(
          "cannot parse more than 8 bytes into LONG type");
    }
    int i = offset + lenght;
    if (i > rawData.length) {
      throw new InvalidParameterException(
          "offset plus length exceeds input data");
    }
    if (offset < 0 || lenght < 0) {
      throw new InvalidParameterException("offset or length are <0");
    }
    byte[] cutoutBalance = new byte[8];
    System.arraycopy(rawData, offset, cutoutBalance, 8 - lenght, lenght);
    ByteBuffer buf = ByteBuffer.wrap(cutoutBalance);
    long result = buf.getLong();
    return result;
  }

  /**
   * Parses a BCD encoded integer from the given byte array
   * 
   * @param data
   * @return
   */
  public static int readBcdIntegerFromBytes(byte[] data) {
    if (data.length > 4) {
      throw new InvalidParameterException(
          "cannot parse more than 4 bytes into int type");
    }
    return Integer.parseInt(bytesToHex(data));
  }

  /**
   * Display a alert dialog
   * 
   * @param ctx
   * @param title
   * @param message
   */
  public static void displaySimpleAlertDialog(Context ctx, String title,
      String message) {
    Builder builder = new AlertDialog.Builder(ctx);
    if (title != null) {
      builder.setTitle(title);
    }
    if (message != null) {
      builder.setMessage(message);
    }
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int id) {
      }
    }).create().show();
  }

  /**
   * format date
   * 
   * @param d
   * @return
   */
  public static String formatDateWithTime(Date d) {
    if (d == null) {
      return "00.00.0000 00:00:00";
    }
    return fullTimeWithDateFormat.format(d);
  }

  /**
   * format date
   * 
   * @param d
   * @return
   */
  public static String formatDateOnly(Date d) {
    if (d == null) {
      return "00.00.0000";
    }
    return dateOnlyDateFormat.format(d);
  }

  /**
   * Integer to hex string
   * 
   * @param i
   * @return
   */
  public static String int2Hex(int i) {
    String hex = Integer.toHexString(i);
    if (hex.length() % 2 != 0) {
      hex = "0" + hex;
    }
    return hex;
  }

  /**
   * Remove all space characters
   * 
   * @param s
   * @return
   */
  public static String removeSpaces(String s) {
    return s.replaceAll(" ", "");
  }

  /**
   * Returns num spaces
   * 
   * @param num
   * @return
   */
  public static String getSpaces(int num) {
    StringBuilder buf = new StringBuilder(num);
    for (int i = 0; i < num; i++) {
      buf.append(" ");
    }
    return buf.toString();
  }

  /**
   * COnvert a given hex string into byte array
   * 
   * @param hexString
   * @return
   */
  public static byte[] fromHexString(String hexString) {
    hexString = removeSpaces(hexString);
    if (hexString.length() == 0) {
      return new byte[0];
    }
    if ((hexString.length() % 2) != 0) {
      throw new IllegalArgumentException(
          "hex string must contain an even number of characters: "
              + hexString);
    }
    final byte result[] = new byte[hexString.length() / 2];
    final char hexChars[] = hexString.toCharArray();
    for (int i = 0; i < hexChars.length; i += 2) {
      StringBuilder curr = new StringBuilder(2);
      curr.append(hexChars[i]).append(hexChars[i + 1]);
      result[i / 2] = (byte) Integer.parseInt(curr.toString(), 16);
    }
    return result;
  }

  /**
   * Returns the input byte array without the last 2 bytes (status word)
   * 
   * @param input
   * @return
   */
  public static byte[] cutoffLast2Bytes(byte[] input) {
    if (input == null) {
      throw new IllegalArgumentException(
          "cutoffLast2Bytes: input was null");
    }
    if (input.length < 2) {
      throw new IllegalArgumentException(
          "cutoffLast2Bytes: input was shorter than 2 bytes");
    }
    byte[] output = new byte[input.length - 2];
    for (int i = 0; i < input.length - 2; i++) {
      output[i] = input[i];
    }
    return output;
  }

  /**
   * Returns a part of a byte array
   * 
   * @param srcArray
   * @param startIndex
   *            (included)
   * @param endIndex
   *            (included)
   * @return
   */
  public static byte[] getByteArrayPart(byte[] srcArray, int startIndex,
      int endIndex) {
    return Arrays.copyOfRange(srcArray, startIndex, endIndex + 1);
  }

  /**
   * returns copy of given byte array
   * 
   * source: https://code.google.com/p/javaemvreader/
   * 
   * @param array2Copy
   * @return
   */
  public static byte[] copyByteArray(byte[] array2Copy) {
    if (array2Copy == null) {
      // return new byte[0] instead?
      throw new IllegalArgumentException(
          "Argument 'array2Copy' cannot be null");
    }
    return copyByteArray(array2Copy, 0, array2Copy.length);
  }

  /**
   * returns copy of byte-array (or part of it)
   * 
   * source: https://code.google.com/p/javaemvreader/
   * 
   * @param array2Copy
   * @param startPos
   * @param length
   * @return
   */
  public static byte[] copyByteArray(byte[] array2Copy, int startPos,
      int length) {
    if (array2Copy == null) {
      // return new byte[0] instead?
      throw new IllegalArgumentException(
          "Argument 'array2Copy' cannot be null");
    }
    if (array2Copy.length < startPos + length) {
      throw new IllegalArgumentException("startPos(" + startPos
          + ")+length(" + length + ") > byteArray.length("
          + array2Copy.length + ")");
    }
    byte[] copy = new byte[array2Copy.length];
    System.arraycopy(array2Copy, startPos, copy, 0, length);
    return copy;
  }

  /**
   * Calculate int value from given byte array
   * 
   * source: https://code.google.com/p/javaemvreader/
   * 
   * @param byteArray
   * @return
   */
  public static int byteArrayToInt(byte[] byteArray) {
    return byteArrayToInt(byteArray, 0, byteArray.length);
  }

  /**
   * Calculate int value from given byte array
   * 
   * source: https://code.google.com/p/javaemvreader/
   * 
   * @param byteArray
   * @param startPos
   * @param length
   * @return
   */
  public static int byteArrayToInt(byte[] byteArray, int startPos, int length) {
    if (byteArray == null) {
      throw new IllegalArgumentException(
          "Parameter 'byteArray' cannot be null");
    }
    if (length <= 0 || length > 4) {
      throw new IllegalArgumentException(
          "Length must be between 1 and 4. Length = " + length);
    }
    int value = 0;
    for (int i = startPos; i < length; i++) {
      value += ((byteArray[i] & 0xFF) << 8 * (byteArray.length - i - 1));
    }
    return value;
  }

  /**
   * Checks if a specific bit is set source:
   * https://code.google.com/p/javaemvreader/
   * 
   * @param val
   * @param bitPos
   *            The leftmost bit is 8 (the most significant bit)
   * @return
   */
  public static boolean isBitSet(byte val, int bitPos) {
    if (bitPos < 1 || bitPos > 8) {
      throw new IllegalArgumentException(
          "parameter 'bitPos' must be between 1 and 8. bitPos="
              + bitPos);
    }
    if ((val >> (bitPos - 1) & 0x1) == 1) {
      return true;
    }
    return false;
  }

  /**
   * Returns int value of a single byte (sets left 3 bytes to 00)
   * 
   * source: https://code.google.com/p/javaemvreader/
   * 
   * @param b
   * @return
   */
  public static int byteToInt(byte b) {
    return (int) b & 0xFF;
  }

  /**
   * This returns a String with length = 8
   * 
   * source: https://code.google.com/p/javaemvreader/
   * 
   * @param val
   * @return
   */
  public static String byte2BinaryLiteral(byte val) {
    String s = Integer.toBinaryString(byteToInt(val));
    if (s.length() < 8) {
      StringBuilder sb = new StringBuilder();
      for (int i = 0; i < 8 - s.length(); i++) {
        sb.append('0');
      }
      sb.append(s);
      s = sb.toString();
    }
    return s;
  }

  /**
   * convert an hex string to ASCII
   * 
   * @param hex
   * @return
   */
  public static String hex2Ascii(String hex) {
    hex.replaceAll(" ", "");
    StringBuilder output = new StringBuilder();
    for (int i = 0; i < hex.length(); i += 2) {
      String str = hex.substring(i, i + 2);
      output.append((char) Integer.parseInt(str, 16));
    }
    return output.toString();
  }

  /**
   * The length of the returned array depends on the size of the int
   * 
   * @param value
   * @return
   */
  public static byte[] intToByteArray(int value) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    byte one = (byte) (value >>> 24);
    byte two = (byte) (value >>> 16);
    byte three = (byte) (value >>> 8);
    byte four = (byte) (value);

    boolean found = false;

    if (one > 0x00) {
      baos.write(one);
      found = true;
    }
    if (found || two > 0x00) {
      baos.write(two);
      found = true;
    }

    if (found || three > 0x00) {
      baos.write(three);
      found = true;
    }

    baos.write(four);

    return baos.toByteArray();
  }

  /**
   * Returns a byte array with length = 4
   * 
   * @param value
   * @return
   */
  public static byte[] intToByteArray4(int value) {
    return new byte[] { (byte) (value >>> 24), (byte) (value >>> 16),
        (byte) (value >>> 8), (byte) value };
  }

  /**
   * Pretty print a hex string with indentation
   * 
   * source: https://code.google.com/p/javaemvreader/
   * 
   * @param in
   * @param indent
   * @param wrapLines
   * @return
   */
  public static String prettyPrintHex(String in, int indent, boolean wrapLines) {
    StringBuilder buf = new StringBuilder();

    for (int i = 0; i < in.length(); i++) {
      char c = in.charAt(i);
      buf.append(c);

      int nextPos = i + 1;
      if (wrapLines && nextPos % 32 == 0 && nextPos != in.length()) {
        buf.append("\n").append(getSpaces(indent));
      } else if (nextPos % 2 == 0 && nextPos != in.length()) {
        buf.append(" ");
      }
    }
    return buf.toString();
  }

  /**
   * Pretty print a hex string with indentation
   * 
   * source: https://code.google.com/p/javaemvreader/
   * 
   * @param in
   * @param indent
   * @return
   */
  public static String prettyPrintHex(String in, int indent) {
    return prettyPrintHex(in, indent, true);
  }

  /**
   * Returns app version string.
   * 
   * @param ctx
   * @return
   */
  public static String getAppVersion(Context ctx) {
    PackageManager pm = ctx.getPackageManager();
    try {
      PackageInfo info = pm.getPackageInfo(ctx.getPackageName(),
          PackageManager.GET_ACTIVITIES);
      if (info == null) {
        Log.w(TAG, "PackageInfo is null");
        return "?";
      }
      return info.versionName;
    } catch (NameNotFoundException e) {
      Log.w(TAG, "PackageInfo NameNotFoundException", e);
      return "?";
    }
  }

  /**
   * Parse the byte "cryptogram infrmation data". See EMV specifications 4.3,
   * EMV Book 3, page 56 (page 72 in the pdf), Table 14:
   * "Coding of Cryptogram Information Data"
   * 
   * @param b
   * @param ctx
   * @return
   */
  public static String explainCryptogramInformationByte(byte b, Context ctx) {
    // b8 b7
    // 0 0 --> AAC
    // 0 1 --> TC
    // 1 0 --> ARQC
    // 1 1 --> RFU
    //
    // b6 b5
    // reserved for payment system specific cryptograms
    //
    // b4
    // 0 --> No advice required
    // 1 --> Advice reequired
    //
    // b3 b1 b1 : reason/advice code
    // 1 x x: RFU
    // 0 0 0: no information given
    // 0 0 1: service not allowed
    // 0 1 0: pin try limit exceeded
    // 0 1 1: issuer authentication failed

    StringBuilder s = new StringBuilder();

    // bit 8 == 1 and bit 7 == 0
    if (((b >>> 7 & (byte) 0x01) == 1) && ((b >>> 6 & (byte) 0x01) == 0)) {
      s.append("ARQC:\n" + ctx.getString(R.string.cryptogram_type_arqc));
    } else
    // bit 8 == 0 and bit 7 == 1
    if (((b >>> 7 & (byte) 0x01) == 0) && ((b >>> 6 & (byte) 0x01) == 1)) {
      s.append("TC:\n" + ctx.getString(R.string.cryptogram_type_tc));
    } else
    // bit 8 == 0 and bit 7 == 0
    if (((b >>> 7 & (byte) 0x01) == 0) && ((b >>> 6 & (byte) 0x01) == 0)) {
      s.append("AAC:\n" + ctx.getString(R.string.cryptogram_type_aac));
    } else
    // bit 8 == 1 and bit 7 == 1
    if (((b >>> 7 & (byte) 0x01) == 1) && ((b >>> 6 & (byte) 0x01) == 1)) {
      s.append("RFU:\n" + ctx.getString(R.string.cryptogram_type_rfu));
    }

    // TODO: parse and explaining remaining bits
    // (but as it seems most of the time they are zero)

    return s.toString();
  }

  /**
   * show about dialog
   */
  public static void showAboutDialog(FragmentManager fm) {
    DialogFragment aboutFragment = new AboutDialogFragment();
    aboutFragment.show(fm, "dialog_about");
  }

  /**
   * show changelog dialog
   * 
   * @param <code>true</code> if full changelog should be shown,
   *        <code>false</code> if only changes since last installed app
   *        version should be shown
   */
  public static void showChangelogDialog(FragmentManager fm,
      boolean fullChangelog) {
    DialogFragment changelogFragment = ChangelogDialogFragment
        .newInstance(fullChangelog);
    changelogFragment.show(fm, "dialog_changelog");
  }

  /**
   * about dialog text
   * 
   * @param ctx
   * @return
   */
  public static Spanned getAboutDialogText(Context ctx) {
    StringBuilder sb = new StringBuilder();
    sb.append("<b><font color=\"#ff3232\">");
    sb.append(ctx.getResources().getString(R.string.app_name));
    sb.append("</font></b>");
    sb.append("<br/><br/>");

    sb.append("<b><font color=\"#ff3232\">Version:</font></b> ");
    sb.append(getAppVersion(ctx));
    sb.append("<br/><br/>");

    sb.append("<b><font color=\"#ff3232\">License:</font></b> ");
    sb.append("GPL-3");
    sb.append("<br/><br/>");

    sb.append("<b><font color=\"#ff3232\">Author:</font></b>");
    sb.append("<br/>Johannes Zweng<br/><a");
    sb.append("href=\"mailto:android-dev@zweng.at?subject=Feedback%20Bankomat%20Info%20App\">");
    sb.append("android-dev@zweng.at</a><br/>");
    sb.append("<i>Be curious! Have fun! :-)</i>");
    sb.append("<br/><br/>");

    // SOURCECODE
    sb.append("<b><font color=\"#ff3232\">Sourcecode:</font></b>");
    sb.append("<br/>Sourcecode of this app: https://github.com/johnzweng/bankomatinfos");
    sb.append("<br/><br/>");

    // DOWNLOADS
    sb.append("<b><font color=\"#ff3232\">Downloads:</font></b>");
    sb.append("<br/>You can find this (and all previous versions) of this app here: http://johannes.zweng.at/android/Market/BankomatInfos");
    sb.append("<br/><br/>");

    // ICON
    sb.append("<b><font color=\"#ff3232\">App icon:</font></b>");
    sb.append("<br/>Copyright owner of the app's icon: https://www.iconfinder.com/zohanimasi");
    sb.append("<br/>The icon <b>may not be used or re-distributed</b> in any form without the ");
    sb.append("permission of the icon's copyright owner!");
    sb.append("<br/><br/>");

    // CREDITS
    sb.append("<b><font color=\"#ff3232\">Credits:</font></b>");

    // javaemvreader
    sb.append("<br/>&#8226; Uses some classes from http://code.google.com/p/javaemvreader/ ");
    sb.append("project (licensed under Apache 2.0 license). Many thanks! :-)");
    sb.append("<br/>");

    // changelog
    sb.append("<br/>&#8226; Thanks to Karsten Priegnitz for his easy-to-use changelog builder: https://code.google.com/p/android-change-log/");

    sb.append("<br/>");
    return Html.fromHtml(sb.toString());
  }

  /**
   * Returns the stackstrace as String
   * 
   * @param t
   * @return
   */
  public static String getStacktrace(Throwable t) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    t.printStackTrace(pw);
    return sw.toString();
  }

}




Java Source Code List

at.zweng.bankomatinfos.AppController.java
at.zweng.bankomatinfos.exceptions.NoSmartCardException.java
at.zweng.bankomatinfos.exceptions.TlvParsingException.java
at.zweng.bankomatinfos.iso7816emv.BERTLV.java
at.zweng.bankomatinfos.iso7816emv.ByteArrayWrapper.java
at.zweng.bankomatinfos.iso7816emv.CPLC.java
at.zweng.bankomatinfos.iso7816emv.EMVTags.java
at.zweng.bankomatinfos.iso7816emv.EmvTag.java
at.zweng.bankomatinfos.iso7816emv.EmvUtils.java
at.zweng.bankomatinfos.iso7816emv.GPTags.java
at.zweng.bankomatinfos.iso7816emv.Iso3166CountryCodes.java
at.zweng.bankomatinfos.iso7816emv.Iso4217CurrencyCodes.java
at.zweng.bankomatinfos.iso7816emv.NfcBankomatCardReader.java
at.zweng.bankomatinfos.iso7816emv.TagAndValue.java
at.zweng.bankomatinfos.iso7816emv.TagImpl.java
at.zweng.bankomatinfos.iso7816emv.TagType.java
at.zweng.bankomatinfos.iso7816emv.TagValueType.java
at.zweng.bankomatinfos.model.AbstractTransactionLogEntry.java
at.zweng.bankomatinfos.model.CardInfo.java
at.zweng.bankomatinfos.model.EmvTransactionLogEntry.java
at.zweng.bankomatinfos.model.InfoKeyValuePair.java
at.zweng.bankomatinfos.model.QuickTransactionLogEntry.java
at.zweng.bankomatinfos.ui.AboutDialogFragment.java
at.zweng.bankomatinfos.ui.ChangelogDialogFragment.java
at.zweng.bankomatinfos.ui.ListAdapterEmvTransactions.java
at.zweng.bankomatinfos.ui.ListAdapterInfos.java
at.zweng.bankomatinfos.ui.ListAdapterQuickTransactions.java
at.zweng.bankomatinfos.ui.MainActivity.java
at.zweng.bankomatinfos.ui.NfcDisabledActivity.java
at.zweng.bankomatinfos.ui.ResultActivity.java
at.zweng.bankomatinfos.ui.ResultEmvTxListFragment.java
at.zweng.bankomatinfos.ui.ResultInfosListFragment.java
at.zweng.bankomatinfos.ui.ResultLogFragment.java
at.zweng.bankomatinfos.ui.ResultQuickTxListFragment.java
at.zweng.bankomatinfos.ui.SettingsActivity.java
at.zweng.bankomatinfos.util.ChangeLog.java
at.zweng.bankomatinfos.util.CustomAlertDialog.java
at.zweng.bankomatinfos.util.Utils.java