Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android NFC development using Fragment

The online source codes for NFC are done using Activity. I would like to ask if it is possible to develop using Fragment instead?

This is the error i hit when i run the codes

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.mobile.countmein/com.mobile.countmein.activities.NFCScanner}: java.lang.ClassCastException: com.mobile.countmein.activities.NFCScanner cannot be cast to android.app.Activity

public class TagViewer extends Fragment {

private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat();
private LinearLayout mTagContent;

private NfcAdapter mAdapter;
private PendingIntent mPendingIntent;
private NdefMessage mNdefPushMessage;

private AlertDialog mDialog;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    return inflater.inflate(R.layout.tag_viewer, container, false);
}


public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

      mTagContent = (LinearLayout)view.findViewById(R.id.list);
        resolveIntent(getActivity().getIntent());

        mDialog = new AlertDialog.Builder(getActivity()).setNeutralButton("Ok", null).create();

        mAdapter = NfcAdapter.getDefaultAdapter(getActivity());
        if (mAdapter == null) {
            showMessage(R.string.error, R.string.no_nfc);
        }

        mPendingIntent = PendingIntent.getActivity(getActivity(), 0,
                new Intent(getActivity(), getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        mNdefPushMessage = new NdefMessage(new NdefRecord[] { newTextRecord(
                "Message from NFC Reader :-)", Locale.ENGLISH, true) });

}


private void showMessage(int title, int message) {
    mDialog.setTitle(title);
    mDialog.setMessage(getText(message));
    mDialog.show();
}

private NdefRecord newTextRecord(String text, Locale locale, boolean encodeInUtf8) {
    byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));

    Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
    byte[] textBytes = text.getBytes(utfEncoding);

    int utfBit = encodeInUtf8 ? 0 : (1 << 7);
    char status = (char) (utfBit + langBytes.length);

    byte[] data = new byte[1 + langBytes.length + textBytes.length];
    data[0] = (byte) status;
    System.arraycopy(langBytes, 0, data, 1, langBytes.length);
    System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);

    return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
}

@Override
public void onResume() {
    super.onResume();
    if (mAdapter != null) {
        if (!mAdapter.isEnabled()) {
            showMessage(R.string.error, R.string.nfc_disabled);
        }
        mAdapter.enableForegroundDispatch(getActivity(), mPendingIntent, null, null);
        mAdapter.enableForegroundNdefPush(getActivity(), mNdefPushMessage);
    }
}

@Override
public void onPause() {
    super.onPause();
    if (mAdapter != null) {
        mAdapter.disableForegroundDispatch(getActivity());
        mAdapter.disableForegroundNdefPush(getActivity());
    }
}

private void resolveIntent(Intent intent) {
    String action = intent.getAction();
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
            || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
            || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        NdefMessage[] msgs;
        if (rawMsgs != null) {
            msgs = new NdefMessage[rawMsgs.length];
            for (int i = 0; i < rawMsgs.length; i++) {
                msgs[i] = (NdefMessage) rawMsgs[i];
            }
        } else {
            // Unknown tag type
            byte[] empty = new byte[0];
            byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
            Parcelable tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            byte[] payload = dumpTagData(tag).getBytes();
            NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, id, payload);
            NdefMessage msg = new NdefMessage(new NdefRecord[] { record });
            msgs = new NdefMessage[] { msg };
        }
        // Setup the views
        buildTagViews(msgs);
    }
}

private String dumpTagData(Parcelable p) {
    StringBuilder sb = new StringBuilder();
    Tag tag = (Tag) p;
    byte[] id = tag.getId();
    sb.append("Tag ID (hex): ").append(getHex(id)).append("\n");
    sb.append("Tag ID (dec): ").append(getDec(id)).append("\n");

    String prefix = "android.nfc.tech.";
    sb.append("Technologies: ");
    for (String tech : tag.getTechList()) {
        sb.append(tech.substring(prefix.length()));
        sb.append(", ");
    }
    sb.delete(sb.length() - 2, sb.length());
    for (String tech : tag.getTechList()) {
        if (tech.equals(MifareClassic.class.getName())) {
            sb.append('\n');
            MifareClassic mifareTag = MifareClassic.get(tag);
            String type = "Unknown";
            switch (mifareTag.getType()) {
            case MifareClassic.TYPE_CLASSIC:
                type = "Classic";
                break;
            case MifareClassic.TYPE_PLUS:
                type = "Plus";
                break;
            case MifareClassic.TYPE_PRO:
                type = "Pro";
                break;
            }
            sb.append("Mifare Classic type: ");
            sb.append(type);
            sb.append('\n');

            sb.append("Mifare size: ");
            sb.append(mifareTag.getSize() + " bytes");
            sb.append('\n');

            sb.append("Mifare sectors: ");
            sb.append(mifareTag.getSectorCount());
            sb.append('\n');

            sb.append("Mifare blocks: ");
            sb.append(mifareTag.getBlockCount());
        }

        if (tech.equals(MifareUltralight.class.getName())) {
            sb.append('\n');
            MifareUltralight mifareUlTag = MifareUltralight.get(tag);
            String type = "Unknown";
            switch (mifareUlTag.getType()) {
            case MifareUltralight.TYPE_ULTRALIGHT:
                type = "Ultralight";
                break;
            case MifareUltralight.TYPE_ULTRALIGHT_C:
                type = "Ultralight C";
                break;
            }
            sb.append("Mifare Ultralight type: ");
            sb.append(type);
        }
    }

    return sb.toString();
}

private String getHex(byte[] bytes) {
    StringBuilder sb = new StringBuilder();
    for (int i = bytes.length - 1; i >= 0; --i) {
        int b = bytes[i] & 0xff;
        if (b < 0x10)
            sb.append('0');
        sb.append(Integer.toHexString(b));
        if (i > 0) {
            sb.append(" ");
        }
    }
    return sb.toString();
}

private long getDec(byte[] bytes) {
    long result = 0;
    long factor = 1;
    for (int i = 0; i < bytes.length; ++i) {
        long value = bytes[i] & 0xffl;
        result += value * factor;
        factor *= 256l;
    }
    return result;
}

void buildTagViews(NdefMessage[] msgs) {
    if (msgs == null || msgs.length == 0) {
        return;
    }
    LayoutInflater inflater = LayoutInflater.from(getActivity());
    LinearLayout content = mTagContent;

    // Parse the first message in the list
    // Build views for all of the sub records
    Date now = new Date();
    List<ParsedNdefRecord> records = NdefMessageParser.parse(msgs[0]);
    final int size = records.size();
    for (int i = 0; i < size; i++) {
        TextView timeView = new TextView(getActivity());
        timeView.setText(TIME_FORMAT.format(now));
        content.addView(timeView, 0);
        ParsedNdefRecord record = records.get(i);
        content.addView(record.getView(getActivity(), inflater, content, i), 1 + i);
        content.addView(inflater.inflate(R.layout.tag_divider, content, false), 2 + i);
    }
}

}

I removed the following because a fragment does not have the method:

@Override 
public void onNewIntent(Intent intent) {
  setIntent(intent);
  resolveIntent(intent);
}
like image 302
chuntato Avatar asked Jan 25 '13 09:01

chuntato


1 Answers

A fragment is to control a portion of the user interface in an Activity. Why not put your NFC code in the activity? If you really need the Intent in the fragment you can pass it in a Bundle because an Intent is Parceable.

See: Pass intent to my fragment

like image 121
John Avatar answered Oct 17 '22 12:10

John