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