package mifare.info; import com.google.appinventor.components.runtime.*; import android.app.Activity; import android.content.Intent; import android.nfc.NfcAdapter; import android.nfc.Tag; import android.util.Log; import android.nfc.tech.MifareClassic; import android.nfc.tech.MifareUltralight; import com.google.appinventor.components.annotations.DesignerComponent; import com.google.appinventor.components.annotations.DesignerProperty; import com.google.appinventor.components.annotations.PropertyCategory; import com.google.appinventor.components.annotations.SimpleEvent; import com.google.appinventor.components.annotations.SimpleObject; import com.google.appinventor.components.annotations.SimpleProperty; import com.google.appinventor.components.annotations.UsesPermissions; import com.google.appinventor.components.annotations.UsesActivities; import com.google.appinventor.components.annotations.androidmanifest.*; import com.google.appinventor.components.common.ComponentCategory; import com.google.appinventor.components.common.PropertyTypeConstants; import com.google.appinventor.components.common.YaVersion; import com.google.appinventor.components.runtime.util.GingerbreadUtil; import com.google.appinventor.components.runtime.util.SdkLevel; /** * Non-visible component to provide MIFARE Info. The component provides the Tag UID and other info *(if supported by the device). * **Note:** This component will only work on Screen1 of any App Inventor app. */ @DesignerComponent(version = YaVersion.NEARFIELD_COMPONENT_VERSION, description = "

Non-visible component to provide MIFARE Info. " + "The component provides the Tag UID and other info" + "(if supported by the device)

" + "

Note: This component will only work on Screen1 of" + " any App Inventor app.

", category = ComponentCategory.EXTENSION, nonVisible = true, iconName = "images/nearfield.png") @SimpleObject(external=true) @UsesPermissions(permissionNames = "android.permission.NFC") @UsesActivities( activities = { @ActivityElement( intentFilters = { @IntentFilterElement( actionElements = { @ActionElement( name = "android.nfc.action.TAG_DISCOVERED" ) }, categoryElements = { @CategoryElement( name = "android.intent.category.DEFAULT" ) } ) } ,launchMode="singleTask" ,name=".Screen1" ) } ) public class MifareInfo extends AndroidNonvisibleComponent implements OnStopListener, OnResumeListener, OnPauseListener, OnNewIntentListener, Deleteable { private static final String TAG = "nearfield"; private Activity activity; private NfcAdapter nfcAdapter; private boolean readMode = true; private int writeType; private String LastUid = ""; private String LastType = ""; private int LastSize = 0; private int LastBlocks = 0; private int LastSectors = 0; private String textToWrite = ""; /* Used to identify the call to startActivityForResult. Will be passed back into the resultReturned() callback method. */ protected int requestCode; /** * Creates a new NearField component * @param container ignored (because this is a non-visible component) */ public MifareInfo(ComponentContainer container) { super(container.$form()); activity = container.$context(); writeType = 1; nfcAdapter = (SdkLevel.getLevel() >= SdkLevel.LEVEL_GINGERBREAD) ? GingerbreadUtil.newNfcAdapter(activity) : null; // register with the forms to that OnResume and OnNewIntent // messages get sent to this component form.registerForOnResume(this); form.registerForOnNewIntent(this); form.registerForOnPause(this); Log.d(TAG, "Nearfield component created"); } // Events /** * The UID of the Mifare Tag read */ @SimpleEvent public void GetUid(String TagUid) { Log.d(TAG, "Uid: got message " + TagUid); LastUid = TagUid; EventDispatcher.dispatchEvent(this, "Uid", TagUid); } /** * The Type of the Mifare Tag read */ @SimpleEvent public void GetType(String TagType) { Log.d(TAG, "Type: got message " + TagType); LastType = TagType; EventDispatcher.dispatchEvent(this, "Type", TagType); } /** * The Size of the Mifare Tag read */ @SimpleEvent public void GetSize(int TagSize) { Log.d(TAG, "Size: got message " + TagSize); LastSize = TagSize; EventDispatcher.dispatchEvent(this, "Size", TagSize); } /** * The number of Sectors of the Mifare Tag read */ @SimpleEvent public void GetSectors(int TagSectors) { Log.d(TAG, "Sectors: got message " + TagSectors); LastSectors = TagSectors; EventDispatcher.dispatchEvent(this, "Sectors", TagSectors); } /** * The number of Blocks of the Mifare Tag read */ @SimpleEvent public void GetBlocks(int TagBlocks) { Log.d(TAG, "Blocks: got message " + TagBlocks); LastBlocks = TagBlocks; EventDispatcher.dispatchEvent(this, "Blocks", TagBlocks); } // Properties /** * Returns the UID of the last Mifare Tag Read. */ @SimpleProperty(category = PropertyCategory.BEHAVIOR) public String LastReadUid() { Log.d(TAG, "String message method stared"); return LastUid; } /** * Returns the Type of the last Mifare Tag Read. */ @SimpleProperty(category = PropertyCategory.BEHAVIOR) public String LastReadType() { Log.d(TAG, "String message method stared"); return LastType; } /** * Returns the Size of the last Mifare Tag Read. */ @SimpleProperty(category = PropertyCategory.BEHAVIOR) public int LastReadSize() { Log.d(TAG, "String message method stared"); return LastSize; } /** * Returns the number of Sectors of the last Mifare Tag Read. */ @SimpleProperty(category = PropertyCategory.BEHAVIOR) public int LastReadSectors() { Log.d(TAG, "String message method stared"); return LastSectors; } /** * Returns the number of Blocks of the last Mifare Tag Read. */ @SimpleProperty(category = PropertyCategory.BEHAVIOR) public int LastReadBlocks() { Log.d(TAG, "String message method stared"); return LastBlocks; } /** * Returns true if in read mode, false if in write mode. */ @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN, defaultValue = "True") @SimpleProperty(category = PropertyCategory.BEHAVIOR) public boolean ReadMode() { Log.d(TAG, "boolean method stared"); return readMode; } /** * Specifies whether the NFC hardware should operate in read mode (`true`{:.logic.block}) or * write mode (`false`{:.logic.block}). */ @SimpleProperty(category = PropertyCategory.BEHAVIOR, description = "Specifies whether the NFC hardware should operate in read or write mode.") public void ReadMode(boolean newMode) { Log.d(TAG, "Read mode set to" + newMode); readMode = newMode; if(!readMode && SdkLevel.getLevel() >= SdkLevel.LEVEL_GINGERBREAD){ GingerbreadUtil.enableNFCWriteMode(activity, nfcAdapter, textToWrite); } } @Override public void onNewIntent(Intent intent) { Log.d(TAG, "Nearfield on onNewIntent. Intent is: " + intent); resolveIntent(intent); } // TODO: Re-enable NFC communication if it had been disabled @Override public void onResume() { Intent intent = activity.getIntent(); Log.d(TAG, "Nearfield on onResume. Intent is: " + intent); } void resolveIntent(Intent intent) { Log.d(TAG, "resolve intent. Intent is: " + intent); String action = intent.getAction(); if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) { Tag tag = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); GetUid(ByteArrayToHexString(tag.getId())); assert tag != null; detectTagData(tag); } } void detectTagData(Tag tag) { GetUid(ByteArrayToHexString(tag.getId())); for (String tech : tag.getTechList()) { if (tech.equals(MifareClassic.class.getName())) { MifareClassic mifareTag = MifareClassic.get(tag); String type = "Unknown"; switch (mifareTag.getType()) { case MifareClassic.TYPE_CLASSIC: type = "Classic"; break; case MifareClassic.TYPE_PLUS: type = "Plus"; break; case MifareClassic.TYPE_PRO: type = "Pro"; break; } GetType(type); GetSize(mifareTag.getSize()); GetSectors(mifareTag.getSectorCount()); GetBlocks(mifareTag.getBlockCount()); } if (tech.equals(MifareUltralight.class.getName())) { MifareUltralight mifareUlTag = MifareUltralight.get(tag); String type = "Unknown"; switch (mifareUlTag.getType()) { case MifareUltralight.TYPE_ULTRALIGHT: type = "Ultralight"; break; case MifareUltralight.TYPE_ULTRALIGHT_C: type = "Ultralight C"; break; } GetType(type); } } } public void onPause() { Log.d(TAG, "OnPause method started."); if (nfcAdapter != null) { GingerbreadUtil.disableNFCAdapter(activity, nfcAdapter); } } @Override public void onDelete() { // TODO Auto-generated method stub // need to delete the nearfieldActivity } @Override public void onStop() { // TODO Auto-generated method stub } private String ByteArrayToHexString(byte [] inarray) { int i, j, in; String [] hex = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}; String out= ""; for(j = 0 ; j < inarray.length ; ++j) { in = (int) inarray[j] & 0xff; i = (in >> 4) & 0x0f; out += hex[i]; i = in & 0x0f; out += hex[i]; } return out; } }