package com.michaelfotiadis.eventtriggeredskypecaller.activities;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import org.ndeftools.Record;
import org.ndeftools.externaltype.AndroidApplicationRecord;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.Vibrator;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.github.johnpersano.supertoasts.SuperActivityToast;
import com.github.johnpersano.supertoasts.SuperCardToast;
import com.michaelfotiadis.eventtriggeredskypecaller.R;
import com.michaelfotiadis.eventtriggeredskypecaller.containers.CustomConstants;
import com.michaelfotiadis.eventtriggeredskypecaller.utils.DataUtils;
import com.michaelfotiadis.eventtriggeredskypecaller.utils.Logger;
import com.michaelfotiadis.eventtriggeredskypecaller.utils.ToastUtils;
public class WriteNFCActivity extends Activity {
private class WriteResponse {
int status;
String message;
WriteResponse(int Status, String Message) {
this.status = Status;
this.message = Message;
}
public String getMessage() {
return message;
}
public int getStatus() {
return status;
}
}
private String mSkype_Name;
private String mMD5 = "Message";
private static final String TAG = "NFC_WRITER";
public static boolean supportedTechs(String[] techs) {
boolean ultralight = false;
boolean nfcA = false;
boolean ndef = false;
for (String tech : techs) {
if (tech.equals("android.nfc.tech.MifareUltralight")) {
ultralight = true;
} else if (tech.equals("android.nfc.tech.NfcA")) {
nfcA = true;
} else if (tech.equals("android.nfc.tech.Ndef")
|| tech.equals("android.nfc.tech.NdefFormatable")) {
ndef = true;
} else {
}
}
if (ultralight && nfcA && ndef) {
return true;
} else {
return false;
}
}
private NfcAdapter mNfcAdapter;
private PendingIntent mNfcPendingIntent;
private boolean writeProtect = false;
protected TextView mReportTextView;
private SuperActivityToast mSuperActivityToast;
private final String TOAST_STRING_1 = "Please Touch an NFC Tag to the Device";
private final long VIBRATION_DURATION = 500;
private long THREAD_SLEEP_TIME = 2000;
protected void checkForNFCAdapter() {
if (mNfcAdapter != null) {
if (!mNfcAdapter.isEnabled()) {
LayoutInflater inflater = getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.activity_write_nfc,
(ViewGroup) findViewById(R.layout.activity_write_nfc));
new AlertDialog.Builder(this)
.setView(dialoglayout)
.setPositiveButton(
"Please Enable the Wireless Network",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0,
int arg1) {
Intent setnfc = new Intent(
Settings.ACTION_WIRELESS_SETTINGS);
startActivity(setnfc);
}
})
.setOnCancelListener(
new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
finish(); // exit application if user
// cancels
}
}).create().show();
} else {
Logger.d(TAG, "NFC Scanning is Enabled");
}
} else {
ToastUtils.makeWarningToast(this, "Sorry, No NFC Adapter found.");
}
}
public void disableForegroundMode() {
Logger.d(TAG, "disableForegroundMode");
SuperActivityToast.cancelAllSuperActivityToasts();
mNfcAdapter.disableForegroundDispatch(this);
}
public void enableForegroundMode() {
Logger.d(TAG, "enableForegroundMode");
// foreground mode gives the current active application priority for
// reading scanned tags
IntentFilter tagDetected = new IntentFilter(
NfcAdapter.ACTION_TAG_DISCOVERED); // filter for tags
IntentFilter[] writeTagFilters = new IntentFilter[] { tagDetected };
mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent,
writeTagFilters, null);
}
private NdefMessage getTagAsNdef() {
boolean addAAR = false;
String uniqueId = mMD5;
byte[] uriField = uniqueId.getBytes(Charset.forName("US-ASCII"));
byte[] payload = new byte[uriField.length + 1];
System.arraycopy(uriField, 0, payload, 1, uriField.length);
NdefRecord rtdTextRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_TEXT, new byte[0], payload);
if (addAAR) {
// note: returns AAR for different app (nfcreadtag)
return new NdefMessage(
new NdefRecord[] {
rtdTextRecord,
NdefRecord
.createApplicationRecord("com.eratosthenes.eventtriggeredskypecaller") });
} else {
return new NdefMessage(new NdefRecord[] { rtdTextRecord });
}
}
private void isTagSupported(Intent intent) {
Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String message;
if (supportedTechs(detectedTag.getTechList())) {
message = "Tag is Writable";
Logger.d(TAG, message);
// check if tag is writable (to the extent that we can
if (writableTag(detectedTag)) {
// writeTag here
WriteResponse wr = writeTag(getTagAsNdef(), detectedTag);
message = (wr.getStatus() == 1 ? "Success: " : "Failed: ")
+ wr.getMessage();
Logger.d(TAG, message);
showProgressDialog(message);
} else {
message = "This tag is not writable";
Logger.d(TAG, message);
mReportTextView.append("\n" + message);
}
} else {
message = "This tag type is not supported";
Logger.d(TAG, message);
mReportTextView.append("\n" + message);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_write_nfc);
// Set the textview
mReportTextView = (TextView) findViewById(R.id.textViewNFCWriterTitle);
// initialize NFC
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
mNfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
Bundle extras = getIntent().getExtras();
if (extras != null) {
mSkype_Name = extras.getString(CustomConstants.EXTRA_PAYLOAD);
mMD5 = new DataUtils().getMd5(mSkype_Name);
mReportTextView.setText("Registering NFC Tag for : " + mSkype_Name);
ToastUtils.makeProgressToast(this, mSuperActivityToast, TOAST_STRING_1 );
}
}
@Override
public void onNewIntent(Intent intent) { // this method is called when an
// NFC tag is scanned
Logger.d(TAG, "onNewIntent");
// check for NFC related actions
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
// Call the intent to read the tag
readTag(intent);
isTagSupported(intent);
} else {
}
}
@Override
protected void onPause() {
super.onResume();
Logger.d(TAG, "onPause");
disableForegroundMode();
}
@Override
protected void onResume() {
super.onResume();
Logger.d(TAG, "onResume");
checkForNFCAdapter();
enableForegroundMode();
}
private void readTag(Intent intent) {
ToastUtils.makeInfoToast(this, "Tag Detected");
String message;
Parcelable[] messages = intent
.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
Logger.d(TAG, "Found " + messages.length + " NDEF messages");
vibrate(); // signal found messages :-)
// parse to records
for (int i = 0; i < messages.length; i++) {
try {
List<Record> records = new org.ndeftools.Message(
(NdefMessage) messages[i]);
message = "Found " + records.size()
+ " records in message " + i;
Logger.d(TAG, message);
for (int k = 0; k < records.size(); k++) {
message = " Record #" + k + " is of class "
+ records.get(k).getClass().getSimpleName();
Logger.d(TAG, message);
Record record = records.get(k);
Logger.d(TAG, record.toString());
if (record instanceof AndroidApplicationRecord) {
AndroidApplicationRecord aar = (AndroidApplicationRecord) record;
message = "Package is " + aar.getPackageName();
Logger.d(TAG, message);
}
}
} catch (Exception e) {
message = "Problem parsing message";
Logger.e(TAG, "\n" + message, e);
}
}
}
}
private void sendResult(String result) {
Logger.d(TAG, "Sending Result: " + result);
Intent returnIntent = new Intent();
returnIntent.putExtra(CustomConstants.EXTRA_RESULT, result);
setResult(RESULT_OK, returnIntent);
finish();
}
private void showProgressDialog(final String message) {
// Cancel all SuperCardToasts already showing
SuperCardToast.cancelAllSuperCardToasts();
// Create a progress dialogue
final ProgressDialog progressDialogue = ProgressDialog.show(WriteNFCActivity.this, "NFC Tag Found",
message);
// start a new thread to process job
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(THREAD_SLEEP_TIME);
progressDialogue.cancel();
sendResult(mMD5);
} catch (InterruptedException e) {
progressDialogue.cancel();
Logger.e(TAG, e.getLocalizedMessage());
}
}
});
t.start();
}
private void vibrate() {
Logger.d(TAG, "vibrate");
Vibrator vibe = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibe.vibrate(VIBRATION_DURATION);
}
private boolean writableTag(Tag tag) {
try {
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
if (!ndef.isWritable()) {
ToastUtils.makeWarningToast(this, "Tag is Read-Only.");
ndef.close();
return false;
}
ndef.close();
return true;
}
} catch (Exception e) {
Logger.e(TAG, e.getLocalizedMessage());
ToastUtils.makeWarningToast(this, "Failed to Read Tag");
}
return false;
}
public WriteResponse writeTag(NdefMessage message, Tag tag) {
int size = message.toByteArray().length;
String messsage = "";
try {
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
if (!ndef.isWritable()) {
return new WriteResponse(0, "Tag is read-only");
}
if (ndef.getMaxSize() < size) {
messsage = "Tag capacity is " + ndef.getMaxSize()
+ " bytes, message is " + size + " bytes.";
return new WriteResponse(0, messsage);
}
ndef.writeNdefMessage(message);
if (writeProtect)
ndef.makeReadOnly();
messsage = "Tag Written Successfully";
return new WriteResponse(1, messsage);
} else {
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
try {
format.connect();
format.format(message);
messsage = "Tag Formatted and Written Successfully";
return new WriteResponse(1, messsage);
} catch (IOException e) {
messsage = "Failed to Format Tag";
Logger.e(TAG, e.getLocalizedMessage());
return new WriteResponse(0, messsage);
}
} else {
messsage = "Tag does not support NDEF";
return new WriteResponse(0, messsage);
}
}
} catch (Exception e) {
messsage = "Failed to write tag";
Logger.e(TAG, e.getLocalizedMessage());
return new WriteResponse(0, messsage);
}
}
}