使用Fragment进行Android NFC开发

时间:2013-01-25 09:17:20

标签: android android-intent android-fragments nfc

NFC的在线源代码使用Activity完成。我想问一下是否有可能使用Fragment开发?

这是我运行代码时遇到的错误

java.lang.RuntimeException:无法实例化活动ComponentInfo {com.mobile.countmein / com.mobile.countmein.activities.NFCScanner}:java.lang.ClassCastException:com.mobile.countmein.activities.NFCScanner无法转换为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);
    }
}

}

我删除了以下内容,因为片段没有方法:

@Override 
public void onNewIntent(Intent intent) {
  setIntent(intent);
  resolveIntent(intent);
}

1 个答案:

答案 0 :(得分:0)

片段是控制Activity中用户界面的一部分。 为什么不将NFC代码放入活动中? 如果你真的需要片段中的Intent,你可以在Bundle中传递它,因为Intent是Parceable。

请参阅:Pass intent to my fragment