Android Open Source - NfcMifare Nfc Mifare Activity






From Project

Back to project page NfcMifare.

License

The source code is released under:

Apache License

If you think the Android project NfcMifare 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 org.nfc.mifare;
/*from  w  w w. ja va  2 s . co m*/
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareClassic;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.*;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class NfcMifareActivity extends Activity {
    private static final String TAG = NfcMifareActivity.class.getSimpleName();
    private static final String LINE_SEPARATOR = System.getProperty("line.separator", "\n");

    private boolean mDebug = true;

    private String mCharset = "ISO-8859-1";
    private boolean mShowDataAsHexString;
    private boolean mReadAll;

    private boolean mWriteToBlock;
    private boolean mWriteAll;

    private NfcAdapter mAdapter;
    private PendingIntent mPendingIntent;
    private IntentFilter[] mIntentFilters;
    private String[][] mTechList;

    private EditText mReadBlockIndex;
    private RadioGroup mReadOptions;
    private CheckBox mReadAllData;

    private EditText mWriteBlockContent;
    private RadioGroup mWriteOptions;
    private EditText mWriteBlockIndex;

    private CheckBox mDebugCheckBox;

    private RelativeLayout mWriteBlockIndexLayout;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.nfc);

        mAdapter = NfcAdapter.getDefaultAdapter(this);
        if (mAdapter == null) {
            this.finish();
            return;
        }

        mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
        try {
            filter.addDataType("*/*");
        } catch (IntentFilter.MalformedMimeTypeException e) {
            e.printStackTrace();
        }
        mIntentFilters = new IntentFilter[]{filter};
        mTechList = new String[][]{new String[]{MifareClassic.class.getName()}};

        initViews();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mAdapter.enableForegroundDispatch(this, mPendingIntent, mIntentFilters, mTechList);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mAdapter.disableForegroundDispatch(this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        if (!NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
            return;
        }
        resolveIntent(intent);
    }

    private void resolveIntent(Intent intent) {
        debug("resolveIntent...", false);
        if (getText(mReadBlockIndex) == null && getText(mWriteBlockContent) == null && !mReadAll) {
            debug(getString(R.string.toast_need_data), true);
            return;
        }

        MifareClassic mfc = MifareClassic.get((Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
        if (mfc == null) {
            debug(getString(R.string.toast_not_mifare_classic), true);
            return;
        }

        disableAllOptions();
        try {
            String result1 = performRead(mfc);
            if (result1 != null) {
                if (mReadAll) {
                    alert(result1);
                } else {
                    debug(result1, true);
                }
            }

            List<Integer> result2 = performWrite(mfc);
            if (result2 != null) {
                if (result2.size() == 0) {
                    debug(getString(R.string.toast_write_success), true);
                } else if (result2.size() == 1 && !mReadAll) {
                    debug(getString(R.string.toast_write_fail), true);
                } else {
                    StringBuilder sb = new StringBuilder();
                    sb.append(getString(R.string.result_failed_the_following));
                    sb.append(LINE_SEPARATOR);
                    for (int i = 0; i < result2.size(); i++) {
                        sb.append(result2.get(i));
                        if (i != 0 && i % 5 == 0) {
                            sb.append(LINE_SEPARATOR);
                        } else {
                            sb.append(", ");
                        }
                    }
                    sb.delete(sb.length() - 2, sb.length());
                    alert(sb.toString());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            enableAllOptions();
            try {
                mfc.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private String performRead(MifareClassic mfc) throws IOException {
        if (getText(mReadBlockIndex) == null && !mReadAll) {
            return null;
        }
        if (!mfc.isConnected()) {
            mfc.connect();
        }

        String ret = null;
        if (mReadAll) {
            StringBuilder sb = new StringBuilder();
            boolean auth;
            int blockCount = mfc.getBlockCount();
            for (int i = 0; i < blockCount; i++) {
                auth = mfc.authenticateSectorWithKeyA(mfc.blockToSector(i), MifareClassic.KEY_DEFAULT);
                if (auth) {
                    byte[] data = readBlock(mfc, i);
                    sb.append(String.format(getString(R.string.block_index_dynamic), i));
                    sb.append(LINE_SEPARATOR);
                    sb.append(convertBytes2String(data));
                    sb.append(LINE_SEPARATOR);
                    sb.append(LINE_SEPARATOR);
                }
            }
            sb.delete(sb.length() - 2, sb.length());
            ret = sb.toString();
        } else {
            int blockIndex = Integer.parseInt(getText(mReadBlockIndex));
            if (!validateBlockIndex(mfc, blockIndex)) {
                debug(getString(R.string.err_block_index_out_of_bound), true);
                return ret;
            }
            int sectorIndex = mfc.blockToSector(blockIndex);
            boolean auth = mfc.authenticateSectorWithKeyA(sectorIndex, MifareClassic.KEY_DEFAULT);
            if (auth) {
                byte[] data = readBlock(mfc, blockIndex);
                ret = convertBytes2String(data);
            } else {
                debug(getString(R.string.auth_failed), true);
            }
        }
        return ret;
    }

    private List<Integer> performWrite(MifareClassic mfc) throws IOException {
        if (getText(mWriteBlockContent) == null) {
            return null;
        }

        if (!mfc.isConnected()) {
            mfc.connect();
        }

        List<Integer> ret = new ArrayList<Integer>();
        String content = getText(mWriteBlockContent);
        if (mWriteAll) {
            for (int i = 1; i < mfc.getBlockCount(); i++) {
                if ((i + 1) % 4 == 0) {
                    continue;
                }
                boolean auth = mfc.authenticateSectorWithKeyA(mfc.blockToSector(i), MifareClassic.KEY_DEFAULT);
                if (auth) {
                    writeBlock(mfc, i, convertString2Bytes(content));
                } else {
                    ret.add(i);
                }
            }
        } else {
            int blockIndex;
            if (mWriteToBlock && getText(mWriteBlockIndex) != null) {
                blockIndex = Integer.parseInt(getText(mWriteBlockIndex));
                if (!validateBlockIndex(mfc, blockIndex)) {
                    debug(getString(R.string.err_block_index_out_of_bound), true);
                    return null;
                }
                if (blockIndex == 0 || (blockIndex + 1) % 4 == 0) {
                    debug(getString(R.string.err_write_to_forbidden_block), true);
                    return null;
                }
            } else {
                blockIndex = randomBlockIndex(mfc);
            }
            debug(String.format(getString(R.string.write_random_dynamic), blockIndex), false);
            boolean auth = mfc.authenticateSectorWithKeyA(mfc.blockToSector(blockIndex), MifareClassic.KEY_DEFAULT);
            if (auth) {
                writeBlock(mfc, blockIndex, convertString2Bytes(content));
            } else {
                ret.add(blockIndex);
                debug(getString(R.string.auth_failed), true);
            }
        }
        return ret;
    }

    private byte[] readBlock(MifareClassic mfc, int blockIndex) throws IOException {
        return mfc.readBlock(blockIndex);
    }

    private void writeBlock(MifareClassic mfc, int blockIndex, byte[] data) throws IOException {
        mfc.writeBlock(blockIndex, data);
    }

    private String convertBytes2String(byte[] data) throws UnsupportedEncodingException {
        String ret;
        if (mShowDataAsHexString) {
            StringBuilder sb = new StringBuilder();
            for (byte b : data) {
                int i = (int) b;
                sb.append(Integer.toHexString(i).toUpperCase());
            }
            ret = sb.toString();
        } else {
            int pos = data.length;
            for (int i = data.length - 1; i >= 0; i--) {
                if (data[i] != 0) {
                    break;
                }
                pos = i;
            }
            ret = new String(data, 0, pos, mCharset);
        }
        return ret;
    }

    private byte[] convertString2Bytes(String content) throws UnsupportedEncodingException {
        byte[] ret = new byte[16];
        byte[] buf = content.getBytes(mCharset);
        int retLen = ret.length;
        int bufLen = buf.length;
        boolean b = retLen > bufLen;

        for (int i = 0; i < retLen; i++) {
            if (b && i >= bufLen) {
                ret[i] = 0;
                continue;
            }
            ret[i] = buf[i];
        }
        return ret;
    }

    private String getText(EditText et) {
        if (TextUtils.isEmpty(et.getText())) {
            return null;
        }
        return et.getText().toString().trim();
    }

    private int randomBlockIndex(MifareClassic mfc) {
        int i = new Random().nextInt(mfc.getBlockCount());
        if (i == 0 || (i + 1) % 4 == 0) {
            return randomBlockIndex(mfc);
        }
        return i;
    }

    private boolean validateBlockIndex(MifareClassic mfc, int blockIndex) {
        if (blockIndex >= mfc.getBlockCount()) {
            return false;
        }
        return true;
    }

    private void alert(String msg) {
        new AlertDialog.Builder(this).setMessage(msg).show();
    }

    private void enableAllOptions() {
        mReadBlockIndex.setEnabled(true);
        for (int i = 0; i < mReadOptions.getChildCount(); i++) {
            mReadOptions.getChildAt(i).setEnabled(true);
        }
        mReadAllData.setEnabled(true);

        mWriteBlockContent.setEnabled(true);
        for (int i = 0; i < mWriteOptions.getChildCount(); i++) {
            mWriteOptions.getChildAt(i).setEnabled(true);
        }
        mWriteBlockIndex.setEnabled(true);

        mDebugCheckBox.setEnabled(true);
    }

    private void disableAllOptions() {
        mReadBlockIndex.setEnabled(false);
        for (int i = 0; i < mReadOptions.getChildCount(); i++) {
            mReadOptions.getChildAt(i).setEnabled(false);
        }
        mReadAllData.setEnabled(false);

        mWriteBlockContent.setEnabled(false);
        for (int i = 0; i < mWriteOptions.getChildCount(); i++) {
            mWriteOptions.getChildAt(i).setEnabled(false);
        }
        mWriteBlockIndex.setEnabled(false);

        mDebugCheckBox.setEnabled(false);
    }

    public void clearText(View view) {
        switch (view.getId()) {
            case R.id.btn_et_read_block_index:
                mReadBlockIndex.setText(null);
                break;

            case R.id.btn_write_block_content:
                mWriteBlockContent.setText(null);
                break;

            case R.id.btn_write_block_index:
                mWriteBlockIndex.setText(null);
                break;
        }
    }

    private void initViews() {
        mReadBlockIndex = (EditText) findViewById(R.id.et_read_block_index);
        mReadOptions = (RadioGroup) findViewById(R.id.rg_read_options);
        mReadAllData = (CheckBox) findViewById(R.id.cb_read_all_data);

        mWriteBlockContent = (EditText) findViewById(R.id.et_write_block_content);
        mWriteOptions = (RadioGroup) findViewById(R.id.rg_write_options);
        mWriteBlockIndex = (EditText) findViewById(R.id.et_write_block_index);

        mDebugCheckBox = (CheckBox) findViewById(R.id.cb_debug);

        mWriteBlockIndexLayout = (RelativeLayout) findViewById(R.id.rl_write_block_index);

        mReadAllData.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                mReadAll = isChecked;
            }
        });

        mReadOptions.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.rb_charset_ascii:
                        mCharset = "ISO-8859-1";
                        mShowDataAsHexString = false;
                        break;

                    case R.id.rb_charset_utf8:
                        mCharset = "UTF-8";
                        mShowDataAsHexString = false;
                        break;

                    case R.id.rb_hex:
                        mCharset = "ISO-8859-1";
                        mShowDataAsHexString = true;
                        break;
                }
            }
        });

        mWriteOptions.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.rb_write_block_index:
                        mWriteBlockIndexLayout.setVisibility(View.VISIBLE);
                        mWriteToBlock = true;
                        mWriteAll = false;
                        break;

                    case R.id.rb_write_all_data:
                        mWriteBlockIndexLayout.setVisibility(View.GONE);
                        mWriteToBlock = false;
                        mWriteAll = true;
                        break;
                }
            }
        });

        mDebugCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                mDebug = !isChecked;
            }
        });
    }

    private void debug(String info, boolean toast) {
        if (mDebug) {
            Log.i(TAG, info);
            if (toast) {
                showToast(info);
            }
        }
    }

    private void showToast(String toast) {
        Toast.makeText(this, toast, Toast.LENGTH_SHORT).show();
    }
}




Java Source Code List

org.nfc.mifare.NfcMifareActivity.java