Java tutorial
/* * Copyright (C) 2013 - Gareth Llewellyn * * This file is part of Rhybudd - http://blog.NetworksAreMadeOfString.co.uk/Rhybudd/ * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/> */ package net.networksaremadeofstring.rhybudd; import android.app.PendingIntent; import android.content.Intent; import android.content.IntentFilter; import android.nfc.FormatException; 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.nfc.tech.NfcA; import android.nfc.tech.NfcF; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.app.FragmentActivity; import android.view.MenuItem; import android.view.View; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import com.bugsense.trace.BugSenseHandler; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.net.URI; import java.nio.charset.Charset; public class WriteNFCActivity extends FragmentActivity { public static String PAYLOAD_UID = "uid"; IntentFilter[] intentFiltersArray = null; String[][] techListsArray; private NfcAdapter mAdapter; private PendingIntent pendingIntent; String UID = ""; Handler tagHandler = null; NdefRecord aaRecord, idRecord; static int READY = 1000; static int WRITE_SUCCESS = 1001; static int IOEXCEPTION = 1002; static int FORMATEXCEPTION = 1003; static int TAG_IO_IN_PROGRESS = 1004; static int SERVER_IO_IN_PROGRESS = 1005; static int SERVER_IO_FAILURE = 1006; static int READONLY = 1007; static int SIZE_ERROR = 1008; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); BugSenseHandler.initAndStartSession(WriteNFCActivity.this, "44a76a8c"); setContentView(R.layout.write_tag_activity); try { getActionBar().setSubtitle(getString(R.string.NFCTitle)); getActionBar().setDisplayHomeAsUpEnabled(true); } catch (Exception gab) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "onCreate", gab); } //Quick test try { UID = getIntent().getExtras().getString(PAYLOAD_UID).replace("/zport/dmd/Devices/", ""); aaRecord = NdefRecord.createApplicationRecord("net.networksaremadeofstring.rhybudd"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { //idRecord = NdefRecord.createExternal("rhybudd:tag", "z", UID.getBytes(Charset.forName("US-ASCII"))); idRecord = NdefRecord.createMime("application/vnd.rhybudd.device", UID.getBytes()); } else { idRecord = NdefRecord.createUri("rhybudd://" + UID); } ((TextView) findViewById(R.id.SizesText)).setText("This payload is " + (aaRecord.toByteArray().length + idRecord.toByteArray().length) + " bytes.\n\nAn ultralight can store up to 46 bytes.\nAn Ultralight C or NTAG203 can store up to 137 bytes.\nDespite the name a 1K can only store up to 716 bytes."); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "onCreate", e); try { Toast.makeText(this, "Sorry there was error parsing the passed UID, we cannot continue.", Toast.LENGTH_SHORT).show(); } catch (Exception t) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "onCreate", t); } finish(); } try { mAdapter = NfcAdapter.getDefaultAdapter(this); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "onCreate getDefaultAdapter", e); mAdapter = null; } try { pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "onCreate pendingIntent", e); } IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try { ndef.addDataType("*/*"); /* Handles all MIME based dispatches. You should specify only the ones that you need. */ } catch (IntentFilter.MalformedMimeTypeException e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "onCreate", e); throw new RuntimeException("fail", e); } try { IntentFilter td = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); intentFiltersArray = new IntentFilter[] { ndef, td }; techListsArray = new String[][] { new String[] { NfcF.class.getName(), NfcA.class.getName(), Ndef.class.getName(), NdefFormatable.class.getName() } }; } catch (Exception e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "onCreate IntentFilter", e); } CreateHandlers(); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: { finish(); return true; } default: return false; } } public void onPause() { super.onPause(); try { if (mAdapter != null) mAdapter.disableForegroundDispatch(this); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "onPause", e); } } public void onResume() { super.onResume(); try { if (mAdapter != null) mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "onResume", e); } } public void onNewIntent(Intent intent) { try { Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); WriteTag(tagFromIntent); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "onNewIntent", e); } } public void CreateHandlers() { tagHandler = new Handler() { public void handleMessage(Message msg) { try { if (msg.what == SERVER_IO_FAILURE) { Toast.makeText(WriteNFCActivity.this, "There was an error communicating with the Zenoss Server", Toast.LENGTH_LONG) .show(); Intent in = new Intent(); setResult(SERVER_IO_FAILURE, in); finish(); } if (msg.what == SERVER_IO_FAILURE) { Toast.makeText(WriteNFCActivity.this, "The Device UID is too large to write to the tag.", Toast.LENGTH_LONG).show(); Intent in = new Intent(); setResult(SERVER_IO_FAILURE, in); finish(); } else if (msg.what == READY) { ((RelativeLayout) findViewById(R.id.WriteTagIndicator)) .setBackgroundResource(R.drawable.writetag_ready); ((ProgressBar) findViewById(R.id.IOProgressBar)).setVisibility(View.GONE); ((ImageView) findViewById(R.id.instructionImage)).setVisibility(View.VISIBLE); ((TextView) findViewById(R.id.IODesc)).setText(R.string.TagReadyFirst); } else if (msg.what == TAG_IO_IN_PROGRESS) { ((RelativeLayout) findViewById(R.id.WriteTagIndicator)) .setBackgroundResource(R.drawable.writetag_working); ((ProgressBar) findViewById(R.id.IOProgressBar)).setVisibility(View.VISIBLE); ((ImageView) findViewById(R.id.instructionImage)).setVisibility(View.GONE); ((TextView) findViewById(R.id.IODesc)).setText(R.string.TagIOWait); } else if (msg.what == WRITE_SUCCESS) { ((RelativeLayout) findViewById(R.id.WriteTagIndicator)) .setBackgroundResource(R.drawable.writetag_ready); ((ProgressBar) findViewById(R.id.IOProgressBar)).setVisibility(View.GONE); ((ImageView) findViewById(R.id.instructionImage)).setVisibility(View.VISIBLE); ((TextView) findViewById(R.id.IODesc)).setText(R.string.TagReadyNext); Toast.makeText(WriteNFCActivity.this, "Tag Written successfully!", Toast.LENGTH_LONG) .show(); Intent in = new Intent(); setResult(0, in); finish(); } else if (msg.what == READONLY) { Toast.makeText(WriteNFCActivity.this, "That tag was Read Only and couldn't be written too", Toast.LENGTH_LONG).show(); ((RelativeLayout) findViewById(R.id.WriteTagIndicator)) .setBackgroundResource(R.drawable.writetag_ready); ((ProgressBar) findViewById(R.id.IOProgressBar)).setVisibility(View.GONE); ((ImageView) findViewById(R.id.instructionImage)).setVisibility(View.VISIBLE); ((TextView) findViewById(R.id.IODesc)).setText(R.string.TagReadyNext); } else if (msg.what == FORMATEXCEPTION) { Toast.makeText(WriteNFCActivity.this, "There was an error trying to format that tag", Toast.LENGTH_LONG).show(); ((RelativeLayout) findViewById(R.id.WriteTagIndicator)) .setBackgroundResource(R.drawable.writetag_ready); ((ProgressBar) findViewById(R.id.IOProgressBar)).setVisibility(View.GONE); ((ImageView) findViewById(R.id.instructionImage)).setVisibility(View.VISIBLE); ((TextView) findViewById(R.id.IODesc)).setText(R.string.TagReadyNext); } else if (msg.what == IOEXCEPTION) { Toast.makeText(WriteNFCActivity.this, "AN I/O Error was encountered\n(Did you move the tag away before it was finished writing?)", Toast.LENGTH_LONG).show(); ((RelativeLayout) findViewById(R.id.WriteTagIndicator)) .setBackgroundResource(R.drawable.writetag_ready); ((ProgressBar) findViewById(R.id.IOProgressBar)).setVisibility(View.GONE); ((ImageView) findViewById(R.id.instructionImage)).setVisibility(View.VISIBLE); ((TextView) findViewById(R.id.IODesc)).setText(R.string.TagReadyNext); } } catch (Exception e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "tagHandler handleMessage", e); } } }; tagHandler.sendEmptyMessage(READY); } public void WriteTag(final Tag receivedTag) { tagHandler.sendEmptyMessage(TAG_IO_IN_PROGRESS); (new Thread() { public void run() { //This could go all kinds of weird Ndef thisNdef = null; try { thisNdef = Ndef.get(receivedTag); } catch (Exception e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "WriteTag", e); e.printStackTrace(); } if (null == thisNdef) { NdefFormatable formatter = null; try { formatter = NdefFormatable.get(receivedTag); formatter.connect(); formatter.format( new NdefMessage(new NdefRecord[] { NdefRecord.createApplicationRecord("io.d0") })); formatter.close(); thisNdef = Ndef.get(receivedTag); } catch (Exception d) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "WriteTag", d); d.printStackTrace(); tagHandler.sendEmptyMessage(FORMATEXCEPTION); } } try { if (null == thisNdef) { throw new FormatException("No NDEF Tag returned from get"); } else { thisNdef.connect(); } if (thisNdef.isWritable()) { //Is this a 203 or larger? if (thisNdef.getMaxSize() < aaRecord.toByteArray().length + idRecord.toByteArray().length) { /*Log.i("WriteTag","This tag was too big. tried to write " + (aaRecord.toByteArray().length + idRecord.toByteArray().length) + " to " + thisNdef.getMaxSize()); idRecord = NdefRecord.createMime("text/plain", Integer.toString(tagMetaData.getInt("i")).getBytes(Charset.forName("US-ASCII"))); Log.i("WriteTag Size Check", "Writing " + (idRecord.toByteArray().length + aaRecord.toByteArray().length) + " to " + thisNdef.getMaxSize());*/ tagHandler.sendEmptyMessage(SIZE_ERROR); } else { //Log.i("WriteTag Size Check", "Writing " + (aaRecord.toByteArray().length + idRecord.toByteArray().length) + " to " + thisNdef.getMaxSize()); NdefMessage tagMsg = new NdefMessage(new NdefRecord[] { idRecord, aaRecord }); //Log.i("WriteTag Size Check", "Wrote " + tagMsg.getByteArrayLength()); thisNdef.writeNdefMessage(tagMsg); thisNdef.makeReadOnly(); thisNdef.close(); tagHandler.sendEmptyMessage(WRITE_SUCCESS); } } else { tagHandler.sendEmptyMessage(READONLY); } } catch (IOException e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "WriteTag", e); tagHandler.sendEmptyMessage(IOEXCEPTION); } catch (FormatException e) { BugSenseHandler.sendExceptionMessage("WriteNFCActivity", "WriteTag", e); e.printStackTrace(); tagHandler.sendEmptyMessage(FORMATEXCEPTION); } } }).start(); } }