00001 package com.github.rosjava.android_remocons.common_tools.nfc;
00002
00003 import android.app.Activity;
00004 import android.app.PendingIntent;
00005 import android.content.Context;
00006 import android.content.Intent;
00007 import android.content.IntentFilter;
00008 import android.content.IntentFilter.MalformedMimeTypeException;
00009 import android.nfc.FormatException;
00010 import android.nfc.NdefMessage;
00011 import android.nfc.NdefRecord;
00012 import android.nfc.NfcAdapter;
00013 import android.nfc.Tag;
00014 import android.nfc.TagLostException;
00015 import android.nfc.tech.IsoDep;
00016 import android.nfc.tech.MifareClassic;
00017 import android.nfc.tech.MifareUltralight;
00018 import android.nfc.tech.Ndef;
00019 import android.nfc.tech.NdefFormatable;
00020 import android.nfc.tech.NfcA;
00021 import android.nfc.tech.NfcB;
00022 import android.nfc.tech.NfcF;
00023 import android.nfc.tech.NfcV;
00024 import android.os.Parcelable;
00025 import android.util.Log;
00026 import android.widget.Toast;
00027
00028 import com.github.robotics_in_concert.rocon_rosjava_core.rosjava_utils.ByteArrays;
00029
00030 import java.io.IOException;
00031 import java.lang.reflect.InvocationTargetException;
00032 import java.lang.reflect.Method;
00033 import java.nio.charset.Charset;
00034 import java.util.Locale;
00035
00036 public class NfcManager {
00037
00038 private Context mContext = null;
00039 private PendingIntent mPendingIntent = null;
00040 private IntentFilter[] mFilters;
00041 private String[][] mTechList;
00042 private Intent mPassedIntent = null;
00043 private NfcAdapter mNfcAdapter = null;
00044 private String mCurrentNdefString = "";
00045
00046 public NfcManager(Context context) {
00047 mContext = context;
00048 mNfcAdapter = NfcAdapter.getDefaultAdapter(mContext);
00049
00050 Intent targetIntent = new Intent(mContext, mContext.getClass());
00051 targetIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
00052 mPendingIntent = PendingIntent.getActivity(mContext, 0, targetIntent, 0);
00053
00054 IntentFilter filter_1 = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
00055 IntentFilter filter_2 = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
00056 IntentFilter filter_3 = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
00057
00058 try {
00059 filter_1.addDataType("*/*");
00060 filter_2.addDataType("*/*");
00061 filter_3.addDataType("*/*");
00062 } catch (MalformedMimeTypeException e) {
00063 throw new RuntimeException("fail", e);
00064 }
00065
00066 mFilters = new IntentFilter[]{filter_1, filter_2, filter_3};
00067 mTechList = new String[][]{new String[]{NfcF.class.getName()},
00068 new String[]{MifareClassic.class.getName()},
00069 new String[]{NfcA.class.getName()},
00070 new String[]{NfcB.class.getName()},
00071 new String[]{NfcV.class.getName()},
00072 new String[]{Ndef.class.getName()},
00073 new String[]{NdefFormatable.class.getName()},
00074 new String[]{MifareUltralight.class.getName()},
00075 new String[]{IsoDep.class.getName()}};
00076 }
00077
00078 public boolean checkNfcStatus() {
00079 return mNfcAdapter.isEnabled();
00080 }
00081
00082 public boolean changeNfcStatus(boolean enable) {
00083
00084 if (mNfcAdapter == null) return false;
00085
00086 boolean success = false;
00087 Class<?> nfcManagerClass = null;
00088 Method setNfcEnabled = null, setNfcDisabled = null;
00089
00090 if (enable) {
00091 try {
00092 nfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
00093 setNfcEnabled = nfcManagerClass.getDeclaredMethod("enable");
00094 setNfcEnabled.setAccessible(true);
00095 success = (Boolean) setNfcEnabled.invoke(mNfcAdapter);
00096 } catch (ClassNotFoundException e) {
00097 e.printStackTrace();
00098 } catch (NoSuchMethodException e) {
00099 e.printStackTrace();
00100 } catch (IllegalArgumentException e) {
00101 e.printStackTrace();
00102 } catch (IllegalAccessException e) {
00103 e.printStackTrace();
00104 } catch (InvocationTargetException e) {
00105 e.printStackTrace();
00106 System.out.println(e.toString());
00107 }
00108
00109 } else {
00110 try {
00111 nfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
00112 setNfcDisabled = nfcManagerClass.getDeclaredMethod("disable");
00113 setNfcDisabled.setAccessible(true);
00114 success = (Boolean) setNfcDisabled.invoke(mNfcAdapter);
00115 } catch (ClassNotFoundException e) {
00116 e.printStackTrace();
00117 } catch (NoSuchMethodException e) {
00118 e.printStackTrace();
00119 } catch (IllegalArgumentException e) {
00120 e.printStackTrace();
00121 } catch (IllegalAccessException e) {
00122 e.printStackTrace();
00123 } catch (InvocationTargetException e) {
00124 e.printStackTrace();
00125 }
00126 }
00127
00128 return success;
00129 }
00130
00131 public boolean enableForegroundDispatch() {
00132 if (mNfcAdapter != null) {
00133 mNfcAdapter.enableForegroundDispatch((Activity) mContext, mPendingIntent, mFilters, mTechList);
00134 return true;
00135 } else {
00136 return false;
00137 }
00138 }
00139
00140 public boolean disableForegroundDispatch() {
00141
00142 if (mNfcAdapter != null) {
00143 mNfcAdapter.disableForegroundDispatch((Activity) mContext);
00144 return true;
00145 } else {
00146 return false;
00147 }
00148 }
00149
00150 public boolean onNewIntent(Intent intent) {
00151
00152 mPassedIntent = intent;
00153 String action = mPassedIntent.getAction();
00154
00155 Toast.makeText(mContext, action, Toast.LENGTH_SHORT).show();
00156
00157 if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) ||
00158 NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) ||
00159 NfcAdapter.ACTION_NDEF_DISCOVERED.equalsIgnoreCase(action))
00160 return true;
00161 else
00162 return false;
00163 }
00164
00165 public String processTag() {
00166
00167 if (mPassedIntent == null) return "NFC Tag is not discovered.";
00168
00169 Parcelable[] rawMsgs = mPassedIntent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
00170
00171 if (rawMsgs == null) {
00172 return "NDEF Message is null";
00173 }
00174
00175 mCurrentNdefString = "";
00176
00177 NdefMessage[] msgs = new NdefMessage[rawMsgs.length];
00178
00179 for (int i = 0; i < rawMsgs.length; i++) {
00180 msgs[i] = (NdefMessage) rawMsgs[i];
00181 mCurrentNdefString += ndefMessageToString(msgs[i]);
00182 }
00183
00184 return mCurrentNdefString;
00185 }
00186
00187 public String ndefMessageToString(NdefMessage message) {
00188
00189 String ndefString = "";
00190 NdefRecord[] ndef_records = message.getRecords();
00191
00192 ndefString += "**Num of NdefRecord : " + ndef_records.length + "\n";
00193
00194 for (int i = 0; i < ndef_records.length; i++) {
00195 String temp = "**Record No. " + i + "\n";
00196 byte[] type = ndef_records[i].getType();
00197 byte[] id = ndef_records[i].getId();
00198 byte[] pl = ndef_records[i].getPayload();
00199 byte[] arr = ndef_records[i].toByteArray();
00200
00201 temp = temp + "- TNF=" + ndef_records[i].getTnf() +
00202 "\n - TYPE=" + ByteArrays.getHexString(type, type.length) + " " + new String(type) +
00203 "\n - ID=" + ByteArrays.getHexString(id, id.length) + " " + new String(id) +
00204 "\n - PayLoad=" + ByteArrays.getHexString(pl, pl.length) + " " + new String(pl) +
00205 "\n - ByteArray=" + ByteArrays.getHexString(arr, arr.length) + " " + new String(arr) + "\n";
00206
00207 ndefString += temp;
00208 }
00209
00210 return ndefString;
00211 }
00212
00213 public byte[] getPayload() {
00214
00215 if (mPassedIntent == null)
00216 return null;
00217
00218 Parcelable[] rawMsgs = mPassedIntent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
00219
00220 if (rawMsgs == null) {
00221 return null;
00222 }
00223
00224 NdefMessage[] msgs = new NdefMessage[rawMsgs.length];
00225
00226 for (int i = 0; i < rawMsgs.length; i++) {
00227 msgs[i] = (NdefMessage) rawMsgs[i];
00228 }
00229
00230 NdefRecord[] records = msgs[0].getRecords();
00231 if (records.length > 0)
00232 return records[0].getPayload();
00233
00234 return null;
00235 }
00236
00237 private NdefRecord createTextRecord(String text, Locale locale, boolean encodeInUtf8) {
00238
00239 final byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
00240 final Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
00241 final byte[] textBytes = text.getBytes(utfEncoding);
00242 final int utfBit = encodeInUtf8 ? 0 : (1 << 7);
00243 final char status = (char) (utfBit + langBytes.length);
00244 final byte[] data = ByteArrays.concat(new byte[]{(byte) status}, langBytes, textBytes);
00245
00246 return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
00247 }
00248
00249 public boolean writeTextNdefMessage(String payload, boolean isAAR) {
00250 NdefRecord record = createTextRecord(payload, Locale.KOREAN, true);
00251 NdefMessage msg = null;
00252 if (isAAR)
00253 msg = new NdefMessage(new NdefRecord[]{record, NdefRecord.createApplicationRecord(mContext.getPackageName())});
00254 else
00255 msg = new NdefMessage(new NdefRecord[]{record});
00256
00257 return writeNdefMessage(msg);
00258 }
00259
00260 public boolean writeTextNdefMessage(byte[] payload, String AAR) {
00261 final byte[] langBytes = Locale.KOREAN.getLanguage().getBytes(Charset.forName("US-ASCII"));
00262 final Charset utfEncoding = Charset.forName("UTF-8");
00263 final int utfBit = 0;
00264 final char status = (char) (utfBit + langBytes.length);
00265 final byte[] data = ByteArrays.concat(new byte[]{(byte) status}, langBytes, payload);
00266
00267 NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
00268 NdefMessage msg = null;
00269 if (AAR != null)
00270 msg = new NdefMessage(new NdefRecord[]{record, NdefRecord.createApplicationRecord(AAR)});
00271 else
00272 msg = new NdefMessage(new NdefRecord[]{record});
00273
00274 return writeNdefMessage(msg);
00275 }
00276
00277 public boolean writeUriNdefMessage(String payload, String AAR) {
00278
00279 NdefRecord record = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI,
00280 NdefRecord.RTD_URI, new byte[0], payload.getBytes());
00281 NdefMessage msg = null;
00282 if (AAR != null)
00283 msg = new NdefMessage(new NdefRecord[]{record, NdefRecord.createApplicationRecord(AAR)});
00284 else
00285 msg = new NdefMessage(new NdefRecord[]{record});
00286
00287 return writeNdefMessage(msg);
00288 }
00289
00290 public boolean writeMimeNdefMessage(String payload, String AAR) {
00291
00292 NdefRecord record = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
00293 ("application/" + mContext.getPackageName()).getBytes(), new byte[0], payload.getBytes());
00294 NdefMessage msg = null;
00295 if (AAR != null)
00296 msg = new NdefMessage(new NdefRecord[]{record, NdefRecord.createApplicationRecord(AAR)});
00297 else
00298 msg = new NdefMessage(new NdefRecord[]{record});
00299
00300 return writeNdefMessage(msg);
00301 }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 public boolean writeNdefMessage(NdefMessage message) {
00317
00318 if (mPassedIntent == null) return false;
00319
00320 Tag tag = mPassedIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
00321 Ndef ndefTag = Ndef.get(tag);
00322
00323 try {
00324 ndefTag.connect();
00325 } catch (IOException e) {
00326 Log.e("NfcWriter", "Connect to tag failed. " + e.getMessage());
00327 e.printStackTrace();
00328 return false;
00329 }
00330
00331 try {
00332 ndefTag.writeNdefMessage(message);
00333 } catch (TagLostException e) {
00334 Log.e("NfcWriter", "The tag left the field. " + e.getMessage());
00335 e.printStackTrace();
00336 return false;
00337 } catch (IOException e) {
00338 Log.e("NfcWriter", "Message writing failure. " + e.getMessage());
00339 e.printStackTrace();
00340 return false;
00341 } catch (FormatException e) {
00342 Log.e("NfcWriter", "Malformed NDEF message. " + e.getMessage());
00343 e.printStackTrace();
00344 return false;
00345 }
00346
00347 try {
00348 ndefTag.close();
00349 } catch (IOException e) {
00350 Log.e("NfcWriter", "Close tag failed. " + e.getMessage());
00351 e.printStackTrace();
00352 return false;
00353 }
00354
00355 return true;
00356 }
00357 }