【Android】銀行卡自動(dòng)格式化及歸屬銀行

首先普及一下銀行卡號(hào)組成信息,
銀行卡號(hào)一般由三部分組成:

  • 發(fā)卡行標(biāo)識(shí)代碼(BIN號(hào))
  • 發(fā)卡行自定義位
  • 校驗(yàn)碼闷叉。

銀行卡號(hào)的前6位是BIN號(hào),是bank identification number的縮寫,由國際標(biāo)準(zhǔn)化組織(ISO)分配給各從事跨行轉(zhuǎn)接交換的銀行卡組織。

一般地:4字頭——VISA杯瞻;5字頭——Mastercard;62——中國銀聯(lián)炫掐;3字頭——運(yùn)通魁莉、JCB等。

發(fā)卡行自定義位長(zhǎng)度可以是6-12位,一般可能會(huì)包含銀行內(nèi)部分行標(biāo)識(shí)旗唁,比如第6-7位宙地,01代表北京地區(qū)的卡,其余的就是隨即生成了逆皮。

最后卡號(hào)最末位的校驗(yàn)碼,具有一定的計(jì)算規(guī)則参袱,用于防偽电谣。銀聯(lián)標(biāo)準(zhǔn)卡符合中國銀聯(lián)標(biāo)準(zhǔn),使用中國銀聯(lián)分配的BIN碼(目前為622126-622925抹蚀,共800個(gè))剿牺,在中國銀聯(lián)支付網(wǎng)絡(luò)范圍和協(xié)議網(wǎng)絡(luò)下使用。

項(xiàng)目添加銀行卡信息時(shí)环壤,有這樣一個(gè)需求晒来,要求當(dāng)用戶輸入銀行卡后自動(dòng)檢測(cè)出該銀行卡屬于哪家銀行。

本文實(shí)現(xiàn)自定義EditText郑现,根據(jù)銀行卡號(hào)判斷該銀行卡所歸屬的銀行湃崩,格式化銀行卡號(hào),每四位增加一個(gè)空格接箫。數(shù)據(jù)來源網(wǎng)絡(luò)整理攒读,并不及時(shí),只供參考學(xué)習(xí)辛友。

先看效果圖:

查詢銀行卡信息
查詢銀行卡信息
查詢銀行卡信息

使用方式

    <com.aikaifa.bankcard.BandCardEditText
        android:id="@+id/bankCardEditText"
        android:layout_width="match_parent"
        android:background="@drawable/bg_edittext"
        android:padding="10dp"
        android:layout_height="40dp"
        android:hint="請(qǐng)輸入銀行卡號(hào)" />
        tv_desc = (TextView) findViewById(R.id.tv_desc);
        bankCardEditText = (BandCardEditText) findViewById(R.id.bankCardEditText);
        bankCardEditText.setBankCardListener(new BandCardEditText.BankCardListener() {
            @Override
            public void success(String name) {
                tv_desc.setText(name);
            }

            @Override
            public void failure() {
                tv_desc.setText("沒有查到所屬銀行");
            }
        });

實(shí)現(xiàn)過程:

1薄扁、新建類BandCardEditText繼承EditText

public class BandCardEditText extends EditText {

    private boolean shouldStopChange = false;
    private final String space = " ";

    private BankCardListener listener;

    public BandCardEditText(Context context) {
        this(context, null);
    }

    public BandCardEditText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BandCardEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        format(getText());
        shouldStopChange = false;
        setFocusable(true);
        setEnabled(true);
        setFocusableInTouchMode(true);
        addTextChangedListener(new BandCardWatcher());
    }

    class BandCardWatcher implements TextWatcher {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable editable) {
            format(editable);
        }
    }

    private void format(Editable editable) {
        if (shouldStopChange) {
            shouldStopChange = false;
            return;
        }

        shouldStopChange = true;

        String str = editable.toString().trim().replaceAll(space, "");
        int len = str.length();
        int courPos;

        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < len; i++) {
            builder.append(str.charAt(i));
            if (i == 3 || i == 7 || i == 11 || i == 15) {
                if (i != len - 1)
                    builder.append(space);
            }
        }
        courPos = builder.length();
        setText(builder.toString());
        setSelection(courPos);
        if (listener != null) {
            if (isBankCard()) {
                char[] ss = getBankCardText().toCharArray();
                listener.success(BankInfo.getNameOfBank(ss, 0));
            } else {
                listener.failure();
            }
        }
    }

    public String getBankCardText() {
        return getText().toString().trim().replaceAll(" ", "");
    }

    public boolean isBankCard() {
        return checkBankCard(getBankCardText());
    }
    
    /**
     * 校驗(yàn)銀行卡卡號(hào)
     * @param cardId
     * @return
     */
    public boolean checkBankCard(String cardId) {
        if(TextUtils.isEmpty(cardId)) {
            return  false;
        }
            char bit = getBankCardCheckCode(cardId.substring(0, cardId.length() - 1));
            if (bit == 'N') {
                return false;
            }
            return cardId.charAt(cardId.length() - 1) == bit;
    }


    /**
     * 
     * @param nonCheckCodeCardId
     * @return
     */
    public char getBankCardCheckCode(String nonCheckCodeCardId) {
        if (TextUtils.isEmpty(nonCheckCodeCardId)
                || !nonCheckCodeCardId.matches("\\d+")
                || nonCheckCodeCardId.length() < 16
                || nonCheckCodeCardId.length() > 19) {
            //如果傳的不是數(shù)據(jù)返回N
            return 'N';
        }
        char[] chs = nonCheckCodeCardId.trim().toCharArray();
        int sum = 0;
        for (int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
            int k = chs[i] - '0';
            if (j % 2 == 0) {
                k *= 2;
                k = k / 10 + k % 10;
            }
            sum += k;
        }
        return (sum % 10 == 0) ? '0' : (char) ((10 - sum % 10) + '0');
    }

    public void setBankCardListener(BankCardListener listener) {
        this.listener = listener;
    }

    public interface BankCardListener {
        void success(String name);

        void failure();
    }
}

源碼下載地址 https://pan.baidu.com/s/1qYfJoRy
【END】

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市废累,隨后出現(xiàn)的幾起案子邓梅,更是在濱河造成了極大的恐慌,老刑警劉巖邑滨,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件日缨,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡掖看,警方通過查閱死者的電腦和手機(jī)殿遂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乙各,“玉大人墨礁,你說我怎么就攤上這事《停” “怎么了恩静?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我驶乾,道長(zhǎng)邑飒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任级乐,我火速辦了婚禮疙咸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘风科。我一直安慰自己撒轮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布贼穆。 她就那樣靜靜地躺著题山,像睡著了一般。 火紅的嫁衣襯著肌膚如雪故痊。 梳的紋絲不亂的頭發(fā)上顶瞳,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音愕秫,去河邊找鬼慨菱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛戴甩,可吹牛的內(nèi)容都是我干的抡柿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼等恐,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼洲劣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起课蔬,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤囱稽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后二跋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體战惊,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年扎即,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吞获。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谚鄙,死狀恐怖各拷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闷营,我是刑警寧澤烤黍,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布知市,位于F島的核電站,受9級(jí)特大地震影響速蕊,放射性物質(zhì)發(fā)生泄漏嫂丙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一规哲、第九天 我趴在偏房一處隱蔽的房頂上張望跟啤。 院中可真熱鬧,春花似錦唉锌、人聲如沸隅肥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至议双,卻和暖如春痘番,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背平痰。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工汞舱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宗雇。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓昂芜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親赔蒲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子泌神,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容