package com.chariotsolutions.nfc.plugin; import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.Tag; import android.nfc.tech.Ndef; import android.util.Log; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Util { static final String TAG = "NfcPlugin"; static JSONObject ndefToJSON(Ndef ndef) { JSONObject json = new JSONObject(); if (ndef != null) { try { Tag tag = ndef.getTag(); // tag is going to be null for NDEF_FORMATABLE until NfcUtil.parseMessage is refactored if (tag != null) { json.put("id", byteArrayToJSON(tag.getId())); json.put("techTypes", new JSONArray(Arrays.asList(tag.getTechList()))); } json.put("type", translateType(ndef.getType())); json.put("maxSize", ndef.getMaxSize()); json.put("isWritable", ndef.isWritable()); json.put("ndefMessage", messageToJSON(ndef.getCachedNdefMessage())); // Workaround for bug in ICS (Android 4.0 and 4.0.1) where // mTag.getTagService(); of the Ndef object sometimes returns null // see http://issues.mroland.at/index.php?do=details&task_id=47 try { json.put("canMakeReadOnly", ndef.canMakeReadOnly()); } catch (NullPointerException e) { json.put("canMakeReadOnly", JSONObject.NULL); } } catch (JSONException e) { Log.e(TAG, "Failed to convert ndef into json: " + ndef.toString(), e); } } return json; } static JSONObject tagToJSON(Tag tag) { JSONObject json = new JSONObject(); if (tag != null) { try { json.put("id", byteArrayToJSON(tag.getId())); json.put("techTypes", new JSONArray(Arrays.asList(tag.getTechList()))); } catch (JSONException e) { Log.e(TAG, "Failed to convert tag into json: " + tag.toString(), e); } } return json; } static String translateType(String type) { String translation; if (type.equals(Ndef.NFC_FORUM_TYPE_1)) { translation = "NFC Forum Type 1"; } else if (type.equals(Ndef.NFC_FORUM_TYPE_2)) { translation = "NFC Forum Type 2"; } else if (type.equals(Ndef.NFC_FORUM_TYPE_3)) { translation = "NFC Forum Type 3"; } else if (type.equals(Ndef.NFC_FORUM_TYPE_4)) { translation = "NFC Forum Type 4"; } else { translation = type; } return translation; } static NdefRecord[] jsonToNdefRecords(String ndefMessageAsJSON) throws JSONException { JSONArray jsonRecords = new JSONArray(ndefMessageAsJSON); NdefRecord[] records = new NdefRecord[jsonRecords.length()]; for (int i = 0; i < jsonRecords.length(); i++) { JSONObject record = jsonRecords.getJSONObject(i); byte tnf = (byte) record.getInt("tnf"); byte[] type = jsonToByteArray(record.getJSONArray("type")); byte[] id = jsonToByteArray(record.getJSONArray("id")); byte[] payload = jsonToByteArray(record.getJSONArray("payload")); records[i] = new NdefRecord(tnf, type, id, payload); } return records; } static JSONArray byteArrayToJSON(byte[] bytes) { JSONArray json = new JSONArray(); for (byte aByte : bytes) { json.put(aByte); } return json; } static byte[] jsonToByteArray(JSONArray json) throws JSONException { byte[] b = new byte[json.length()]; for (int i = 0; i < json.length(); i++) { b[i] = (byte) json.getInt(i); } return b; } static JSONArray messageToJSON(NdefMessage message) { if (message == null) { return null; } List<JSONObject> list = new ArrayList<JSONObject>(); for (NdefRecord ndefRecord : message.getRecords()) { list.add(recordToJSON(ndefRecord)); } return new JSONArray(list); } static JSONObject recordToJSON(NdefRecord record) { JSONObject json = new JSONObject(); try { json.put("tnf", record.getTnf()); json.put("type", byteArrayToJSON(record.getType())); json.put("id", byteArrayToJSON(record.getId())); json.put("payload", byteArrayToJSON(record.getPayload())); } catch (JSONException e) { //Not sure why this would happen, documentation is unclear. Log.e(TAG, "Failed to convert ndef record into json: " + record.toString(), e); } return json; } }