Android Open Source - wherewithal Card Deck Activity






From Project

Back to project page wherewithal.

License

The source code is released under:

GNU General Public License

If you think the Android project wherewithal listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.curchod.wherewithal;
/*from ww w  .  java 2s  .  c o m*/
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableLayout.*;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

import com.curchod.domartin.Constants;
import com.curchod.domartin.HouseDeck;
import com.curchod.domartin.IWantTo;
import com.curchod.domartin.UtilityTo;
import com.curchod.dto.Card;
import com.curchod.dto.DeckCard;

public class CardDeckActivity extends Activity 
{

  private String DEBUG_TAG = "CardDeckActivity";
  Hashtable <String,DeckCard> id_deck_cards;
  private TableLayout table;
  /** To identify the rows in the table later. */
  private Hashtable <String,String> card_row_ids;
  private HouseDeck house_deck;
  final Context context = this;
  /** When a user clicks on a card, we get the card name from the view, so this allows us to get that cards id. */
  private Hashtable <String,String> deck_card_name_ids;
  // from card player words activity
  private NfcAdapter nfc_adapter;
  private NfcAdapter mfc_adapter;
  private String[][] tech_lists_array;    
  private IntentFilter ndef_filter;
  private IntentFilter filters[];
  private IntentFilter writeTagFilters[];
  private IntentFilter[] intentFiltersArray;
  private PendingIntent pending_intent;
  boolean writeMode;
  private Tag card_tag;
  private boolean write_failed;
  boolean testing;
  private Intent new_intent;
  /** This flag lets us know that the user has selected a card to write an id to so that 
   * the usual behavior to show the contents of the existing card is disabled. */
  private boolean writing_new_id_mode;
  private CardDeckActivity activity;
  String word_player_card;
  String deck_card_name;
  //private boolean wrote_new_id;
  private static final int reuse_id = 1;
    private static final int write_id = 2;
    private boolean write_new_id;
    private boolean reuse_selected;
    private boolean write_selected;
    private static final int id_group = 1;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) 
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_card_deck); 
    String method = "onCreate";
    String build = "87";
    activity = this;
    nfc_adapter = NfcAdapter.getDefaultAdapter(context);
    Log.i(DEBUG_TAG, method+": build "+build);
    getIntentInfo();
    Button button_add_reading = (Button)findViewById(R.id.button_add_reading);
    button_add_reading.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
              final String method = "button_add_reading.onClick";
              createNewCard(Constants.READING);
              //Log.i(DEBUG_TAG, method+": Hi there reading!");
            }
        });
    Button button_add_writing = (Button)findViewById(R.id.button_add_writing);
    button_add_writing.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
              final String method = "button_add_writing.onClick";
              //Log.i(DEBUG_TAG, method+": Hi there writing!");
              createNewCard(Constants.WRITING);
            }
        });
    createCardsList();
    setupPendingIntent();
  }
  
  /*
   * We create a card with the name *type**index*, like R1 or W1.
   * Then we add it to the deck and save the deck.
   * Then we re create the cards list.
   * Then we save the house deck with the new card.
   * 
   */
  private void createNewCard(String type)
  {
    String method = "createNewCard";
    DeckCard new_card = new DeckCard();
    String card_name = "R";
    int card_index = 0;
    if (type.equals(Constants.READING))
    {
       card_name = "R";
       card_index = house_deck.getNumberOfReadingCards();
       new_card.setType(Constants.READING);
    } else if (type.equals(Constants.WRITING))
    {
       card_name = "W";
       card_index = house_deck.getNumberOfWritingCards();
       new_card.setType(Constants.WRITING);
    }
    card_index++;
    String new_card_name = card_name+card_index;
    new_card.setIndex(card_index);
    new_card.setCardName(new_card_name);
    new_card.setStatus(Constants.BLANK);
    long new_id = UtilityTo.getNewID();
    new_card.setCardId(new_id+"");
    id_deck_cards.put(new_id+"", new_card);
    house_deck.setCards(new_id+"", new_card);
    deck_card_name_ids.put(new_card_name, Long.toString(new_id));
    Log.i(DEBUG_TAG, method+": created new card and put "+new_card_name+" id "+new_id+" into deck_card_name_ids.");
    if (table != null)
    {
      //Log.i(DEBUG_TAG, method+": table is null");
      table.removeAllViews();
    }
      createCardsList();
      loadAndSaveModifiedDecks();
  }
  
  private void loadAndSaveModifiedDecks()
  {
    String method = "loadAndSaveModifiedDecks";
    IWantTo i_want_to = new IWantTo(context);
      Hashtable <String,HouseDeck> house_decks = i_want_to.loadTheHouseDecks();
      Log.i(DEBUG_TAG, method+": got "+house_decks.size()+" decks from file");
      Hashtable <String,HouseDeck> copy_house_decks = i_want_to.loadTheHouseDecks();
      Enumeration <String> e = house_decks.keys();
      while (e.hasMoreElements())
      {
        String key = (String)e.nextElement();
        HouseDeck this_house_deck = house_decks.get(key);
        String this_house_deck_id = this_house_deck.getDeckId();
        if (this_house_deck_id.equals(house_deck.getDeckId()))
        {
          copy_house_decks.put(this_house_deck_id, house_deck);
          Log.i(DEBUG_TAG, method+": game id "+house_deck.getGameId()+" player_id "+house_deck.getPlayerId());
          Log.i(DEBUG_TAG, method+": putting this deck "+house_deck.getDeckName());
        } else
        {
          copy_house_decks.put(this_house_deck_id, this_house_deck);
          //Log.i(DEBUG_TAG, method+": copied game id "+this_house_deck.getGameId()+" player_id "+this_house_deck.getPlayerId());
          //Log.i(DEBUG_TAG, method+": copy deck "+this_house_deck_id);
        }
      }
      i_want_to.saveTheHouseDecks(copy_house_decks);
  }
  
  /**
   * To create a sorted list of reading and a separate sorted list of writing cards
   * we have to call the sortCards row separately for each list type.  Then  we call
   * setupRow for each member of the hashtable returned by that method.
   */
  private void createCardsList()
  {
    String method = "createCardsList";
    card_row_ids = new Hashtable <String,String> ();
    Hashtable <String,DeckCard> reading_rows = sortCards(Constants.READING);
    Enumeration<String> reading = reading_rows.keys();
    while (reading.hasMoreElements())
    {
      String key = reading.nextElement();
      DeckCard card = reading_rows.get(key);
      try
      {
        setupRow(card);
      } catch (java.lang.NullPointerException npe)
      {
        Log.i(DEBUG_TAG, method+": setupRow reading npe");
        npe.printStackTrace();
      }
    }
    Hashtable <String,DeckCard> writing_rows = sortCards(Constants.WRITING);
    Enumeration<String> writing = writing_rows.keys();
    while (writing.hasMoreElements())
    {
      String key = writing.nextElement();
      DeckCard card = writing_rows.get(key);
      try
      {
        setupRow(card);
      } catch (java.lang.NullPointerException npe)
      {
        Log.i(DEBUG_TAG, method+": setupRow reading npe");
        npe.printStackTrace();
      }
    }
  }
  
  /**
   * This method is called for reading and again for writing words to create separate lists.
   * The cards names and type are put into a table row, and an on click listener is attached.
   * The listener gets the selected card, finds the DeckCard object then calls selectedCard.
   */
  private void setupRow(DeckCard deck_card)
  {
    final String method = "setupRow";
    table = (TableLayout) findViewById(R.id.deck_card_table_layout);
    table.setVerticalScrollBarEnabled(true);
    table.setColumnStretchable(2, true);
    TableRow row = new TableRow(this);
    String card_name = deck_card.getCardName();
    String card_id = deck_card.getCardName();
    String card_status = deck_card.getStatus();
    card_row_ids.put(row.toString(), card_id);
    TextView name = new TextView(this);
        TextView type = new TextView(this);   
        name.setText(card_name);
        type.setText(card_status);
        Log.i(DEBUG_TAG, method+": table row "+card_name+" status "+card_status);
        row.addView(name);
        row.addView(type);
        table.addView(row,new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        row.setClickable(true);
        row.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
              String inner_method = "onClick";
              final String method = "card_list.onClick";
              String selected_card_row_id = v.toString();
              Log.i(DEBUG_TAG, method+inner_method+" selected_card_row_id "+selected_card_row_id);
              String selected_card_name = card_row_ids.get(selected_card_row_id);
              Log.i(DEBUG_TAG, method+inner_method+" selected_card_name "+selected_card_name);
              String selected_card_id = deck_card_name_ids.get(selected_card_name);
              Log.i(DEBUG_TAG, method+inner_method+" selected_card_id "+selected_card_id);
              Log.i(DEBUG_TAG, method+inner_method+" selected "+selected_card_name+" selected_card_row_id "+selected_card_row_id+" selected_card_name "+selected_card_name+" selected_card_id "+selected_card_id);
              DeckCard selected_card = house_deck.getCard(selected_card_id);
              Log.i(DEBUG_TAG, method+inner_method+" selected "+selected_card_name+" (from card-"+selected_card.getCardName()+") "+selected_card_id);
              selectedCard(selected_card);
            }
        });
  }
  
  private void setupPendingIntent()
  {
    mfc_adapter = NfcAdapter.getDefaultAdapter(this);
    pending_intent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
        IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        try 
        {
          ndef.addDataType("*/*");
        } catch (MalformedMimeTypeException e) 
        {
          throw new RuntimeException("fail", e);
        }

        IntentFilter tech = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
        try 
        {
          tech.addDataType("*/*");
        } catch (MalformedMimeTypeException e) 
        {
          throw new RuntimeException("fail", e);
        }
        intentFiltersArray = new IntentFilter[] { tagDetected, ndef, tech };
        tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
        writeTagFilters = new IntentFilter[] { tagDetected };
        // tech_lists_array = new String [][] { new String[] {NfcF.class.getName()}}; // from CardPlayerWordsActivity
        tech_lists_array = new String[][] { new String[] { MifareClassic.class.getName() } }; // from GameReadingStonesActibity
        write_failed = false;
  }
  
  /**
   * Show a popup asking the user to set up the card.  When the user clicks the OK button
   * we check if the tag is OK to write, and get the id written to the tag like this:
   * String card_id = readWriteFormatReject(selected_card);
   * If it's being tested on a virtual device, then we emulate that behaviour.
   * @param selected_card
   */
  private void selectedCard(final DeckCard selected_card)
  {
    String method = "selectedCard";
    writing_new_id_mode = true; //set writing mode
    LayoutInflater layout_inflater = LayoutInflater.from(context);
    View popup_view = layout_inflater.inflate(R.layout.card_player_words_popup, null);
    final AlertDialog.Builder alert_dialog_builder = new AlertDialog.Builder(context);
    alert_dialog_builder.setView(popup_view);
    final TextView card_player_words_popup_text = (TextView) popup_view.findViewById(R.id.card_player_words_popup_text);
    //String message = R.string.scan_+selected_card.getCardName()+R.string.now;
    String message = (String)selected_card.getCardName();
    card_player_words_popup_text.setText(message);
    Log.i(DEBUG_TAG, method+" popup message "+message);
    alert_dialog_builder.setCancelable(false).setPositiveButton(R.string.ok,
        new DialogInterface.OnClickListener() 
          {
          public void onClick(DialogInterface dialog,int id) 
          {
            if(card_tag==null)
          {
                Toast.makeText(context, context.getString(R.string.error_detected), Toast.LENGTH_LONG ).show();
                Log.i(DEBUG_TAG, "onClick: error detected: card tag is null");
          } else
          {
              Log.i(DEBUG_TAG, "DialogInterface.onClick: writing");
              try
              {
                String card_id = readWriteFormatReject(selected_card.getCardId()); // this returns a new id now
                if (card_id == null || write_failed)
                {
                  Toast.makeText(context, R.string.cannot_use_card, Toast.LENGTH_LONG ).show();
                } else
                {
                  Toast.makeText(context, context.getString(R.string.dont_move_writing), Toast.LENGTH_LONG ).show();
                  Toast.makeText(context, context.getString(R.string.ok_writing), Toast.LENGTH_LONG ).show();
                  updateId(card_id, selected_card);
                  // change card id 
                  // copy decks and replace with the new deck
                  // load and save the deck
                  // set the list as set up.
                  testing = false;
                  writing_new_id_mode = false;
                }
              } catch (java.lang.NullPointerException npe)
              {
                // no tag to read
                Log.i(DEBUG_TAG, "DialogInterface.onClick: no tag to read");
                Toast.makeText(context, R.string.put_the_tag_under_the_phone, Toast.LENGTH_LONG ).show();
              }
          }
            if (testing)
            {
              Log.i(DEBUG_TAG, "DialogInterface.onClick: Emulation mode, no card written during testing");
            //Card card = itemSelected(selected_word);
            //Log.i(DEBUG_TAG, "DialogInterface.onClick: test writing");
            try
            {
              Log.i(DEBUG_TAG, "testing: no npe");
              //String card_id = readWriteFormatReject(selected_card);
              String new_id = UtilityTo.getNewID()+"";
              updateId(new_id, selected_card);
              writing_new_id_mode = false;
              //file_cards.add(card);
              //savedCardsFile();
              //checkIfSetupComplete();
            }
               catch (java.lang.NullPointerException npe)
            {
              // no tag to read
              Log.i(DEBUG_TAG, "DialogInterface.onClick: no tag to read");
              Toast.makeText(context, "Test mode: Put the tag under the phone and try again.", Toast.LENGTH_LONG ).show();
              Log.i(DEBUG_TAG, "testing: npeee!!!");
              npe.printStackTrace();
            }
            }
            dialog.cancel();
          }
        }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() 
        {
          public void onClick(DialogInterface dialog,int id) 
          {
            dialog.cancel();
            writing_new_id_mode = false;
          }
        });
      AlertDialog alert_dialog = alert_dialog_builder.create();
      alert_dialog.show();
  }
  
  /**
   * Put the new id into the card decks, and call updateCards to do the same thing with the cards file.
   * @param new_card_id
   * @param selected_card
   */
  private void updateId(String new_card_id, DeckCard selected_card)
  {
    String method = "updateId";
    selected_card.setCardId(new_card_id);
    selected_card.setStatus(Constants.READY);
    boolean found = false;
    Log.i(DEBUG_TAG, method+" new card id "+new_card_id);
    Hashtable<String, DeckCard> deck_cards = house_deck.getCards();
    Hashtable<String, DeckCard> deck_cards_copy = new Hashtable<String, DeckCard> ();
    Enumeration <String> e = deck_cards.keys();
    while (e.hasMoreElements())
    {
      String key = (String)e.nextElement();
      DeckCard this_card = deck_cards.get(key);
       if (this_card.getCardId().equals(selected_card.getCardId()))
      {
        this_card.setCardId(new_card_id);
        deck_cards_copy.put(new_card_id, this_card);
        Log.i(DEBUG_TAG, method+" new card name match. set "+this_card.getCardName()+" id to "+new_card_id);
        Log.i(DEBUG_TAG, method+" Check game association ");
        found = true;
      } else
      {
        deck_cards_copy.put(this_card.getCardId(), this_card);
        //Log.i(DEBUG_TAG, method+" no match for "+this_card.getCardName()+" id to "+new_card_id);
      }
    }
    if (!found)
    {
      Log.i(DEBUG_TAG, method+" WARNING! Could not update card id!");
    }
    house_deck.setCards(deck_cards_copy);
    loadAndSaveModifiedDecks();
    updateCards(new_card_id, selected_card);
    table.removeAllViews();
    createCardsList();
  }
  
  /**
   * Copy the cards file with the new card id set in the appropriate card if it exists.
   * @param new_card_id
   * @param selected_card
   */
  private void updateCards(final String new_card_id, DeckCard selected_card)
  {
    final String method = "updateCards";
      new Thread()
        {
            public void run()
            {   
              // we have the house_deck which has the deck cards and their ids-deck card.
              Hashtable <String,DeckCard> deck_cards = house_deck.getCards();
              boolean file_change = false;
              IWantTo i_want_to = new IWantTo(context);
              Vector <Card> file_cards = i_want_to.loadCardsFile();
              Log.i(DEBUG_TAG, method+" Update Cards File.  file_cards size "+file_cards.size());
              Vector <Card> file_cards_copy = new Vector <Card> ();
              for (int i = 0; i < file_cards.size(); i++)
              {
                Card this_card = file_cards.get(i);
                if (this_card.getCardId().equals(new_card_id))
                {
                  Log.i(DEBUG_TAG, method+" new card name match. set "+this_card.getCardId()+" id to "+new_card_id);
                  this_card.setCardId(new_card_id);
                  file_cards_copy.add(this_card);
                  file_change = true;
                } else
                {
                  //Log.i(DEBUG_TAG, method+" no match for "+this_card.getCardId()+" id to "+new_card_id);
                  file_cards_copy.add(this_card);
                }
              }
              if (file_change)
              {
                Log.i(DEBUG_TAG, method+" save cards copy");
                i_want_to.saveCardsFile(file_cards_copy);
              } else
              {
                Log.i(DEBUG_TAG, method+" WARNING! Could not update card id!");
              }
            }
        }.start();
  }
  
  /**
     * From http://www.tapwise.com/svn/nfcwritetag/trunk/src/com/tapwise/nfcwritetag/MainActivity.java
     * @param selected_card
     * @return
     */
    private String readWriteFormatReject(String existing_deck_card_id)
    {
      String method = "readWriteFormatReject";
        Tag detectedTag = new_intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        Log.i(DEBUG_TAG, method+" existing_deck_card_id "+existing_deck_card_id);
        if(supportedTechs(card_tag.getTechList())) 
        {
          //Log.i(DEBUG_TAG, method+" supported techs");
            // check if tag is writable (to the extent that we can
            if(writableTag(card_tag)) 
            {
              //String existing_message = writeTag(getTagAsNdef(selected_card.getCardId()), detectedTag);
              String existing_message = null;
              if (write_new_id)
              {
                long new_id = UtilityTo.getNewID();
                existing_message = writeTag(getTagAsNdef(new_id+""), detectedTag);
                existing_message = new_id+"";
              } else
              {
                existing_message = writeTag(getTagAsNdef(existing_deck_card_id), detectedTag);
              }
              String message = "This tag can be written, new id is : "+existing_message;
              Log.i(DEBUG_TAG, method+" "+message);
              existing_deck_card_id = existing_message;
              //Toast.makeText(context,message,Toast.LENGTH_SHORT).show();
            } else 
            {
              String existing_message = getExistingTagID();
              String message = "This tag is not writable. existing_message "+existing_message;
              Log.i(DEBUG_TAG, method+" "+message);
              Log.i(DEBUG_TAG, method+" existing message "+existing_message);
              //Toast.makeText(context,message,Toast.LENGTH_SHORT).show();
              existing_deck_card_id = existing_message;
            }              
        } else 
        {
          String existing_message = getExistingTagID();
          Log.i(DEBUG_TAG, method+"un-supported techs "+existing_message);
          //Toast.makeText(context,"This tag type is not supported",Toast.LENGTH_SHORT).show();
          existing_deck_card_id = existing_message;
        }
        try
        {
          if (existing_deck_card_id.equals(""))
          {
            existing_deck_card_id = null;
            Log.i(DEBUG_TAG, method+" card_id set to null");
          }
        } catch (java.lang.NullPointerException npe)
        {
          Log.i(DEBUG_TAG, method+" card_id is null");
        }
        return existing_deck_card_id;
    }
    
    /**
     * Try and read a tag to get the first sector to use as an id if we can't write the tag.
     * @return
     */
    private String getExistingTagID()
  {
    String method = "getExistingTagID";
    Log.i(DEBUG_TAG, method+": called.");
    Parcelable[] raw_messages = new_intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
    NdefMessage[] ndef_messages = null;
    if (raw_messages != null) 
    {
      Log.i(DEBUG_TAG, method+" rawMsgs != null");
      ndef_messages = new NdefMessage[raw_messages.length];
        for (int i = 0; i < raw_messages.length; i++) 
        {
          NdefMessage ndef_message = (NdefMessage)raw_messages[i];
            Log.i(DEBUG_TAG, "i "+i+" ndef_message = "+ndef_message.toString());
            ndef_messages[i] = (NdefMessage) raw_messages[i];
        }
    } else
    {
      Log.i(DEBUG_TAG, method+" raw_messages == null");
    }
    try
    {
      NdefRecord[] records = ndef_messages[0].getRecords();
      final int size = records.length;
      for (int i = 0; i < size; i++) 
      {
        NdefRecord record = records[i];
        String message = new String(record.getPayload());
        Log.i(DEBUG_TAG, method+" "+i+" message "+message);
        if (i==0)
        {
          return message;
        }
      }
    } catch (java.lang.NullPointerException npe)
    {
      Log.i(DEBUG_TAG, method+" failed to write tag.");
      write_failed = true;
      npe.printStackTrace();
    }
    return null;
  }
    
    /**
     * From http://www.tapwise.com/svn/nfcwritetag/trunk/src/com/tapwise/nfcwritetag/MainActivity.java
     * @param message
     * @param tag
     * @return
     */
    public String writeTag(NdefMessage message, Tag tag) 
    {
      String method = "writeTag";
      int size = message.toByteArray().length;
        String mess = "";
        try 
        {
            Ndef ndef = Ndef.get(tag);
            if (ndef != null) 
            {
                ndef.connect();
                if (!ndef.isWritable()) 
                {
                  String existing_message = getExistingTagID();
                  String debug_message = "Tag is read-only. Exising message "+existing_message;
                  Log.i(DEBUG_TAG, method+" "+debug_message);
                  //Toast.makeText(context,debug_message,Toast.LENGTH_SHORT).show();
                  return existing_message;
                }
                if (ndef.getMaxSize() < size) 
                {
                  String existing_message = getExistingTagID();                    
                    String debug_message = "Tag capacity is " + ndef.getMaxSize() + " bytes, message is " + size
                            + " bytes.  Existing message "+existing_message;
                  Log.i(DEBUG_TAG, method+" "+debug_message);
                    //Toast.makeText(context, mess, Toast.LENGTH_SHORT).show();
                    return existing_message;
                }
                ndef.writeNdefMessage(message);
                //if(writeProtect)  ndef.makeReadOnly();
               // mess = "Wrote message to pre-formatted tag. Status 1";
                Log.i(DEBUG_TAG, method+" "+mess);
                //Toast.makeText(context, mess, Toast.LENGTH_SHORT).show();
                return "wrote card";
            } else 
            {
                NdefFormatable format = NdefFormatable.get(tag);
                if (format != null) 
                {
                    try 
                    {
                        format.connect();
                        format.format(message);
                        mess = "Formatted tag and wrote message.  status 1";
                        Log.i(DEBUG_TAG, method+" "+mess);
                        //Toast.makeText(context, mess, Toast.LENGTH_SHORT).show();
                        return "formatted and wrote";
                    } catch (IOException e) 
                    {
                      String existing_message = getExistingTagID();
                        mess = "Failed to format tag. status 0.  existing_message "+existing_message;
                       // Toast.makeText(context, mess, Toast.LENGTH_SHORT).show();
                        Log.i(DEBUG_TAG, method+" "+mess);
                        getExistingTagID();
                        return existing_message;
                    }
                } else 
                {
                  String existing_message = getExistingTagID();
                    mess = "Tag doesn't support NDEF. status 0. existing_message "+existing_message;
                    Log.i(DEBUG_TAG, method+" "+mess);
                    //Toast.makeText(context, mess, Toast.LENGTH_SHORT).show();
                    getExistingTagID(); // ???
                    return existing_message;
                }
            }
        } catch (Exception e) 
        {
          String existing_message = getExistingTagID();
            mess = "Failed to write tag.  existing_message "+existing_message;
            Log.i(DEBUG_TAG, method+" "+mess);
            return existing_message;
        }
    }
    
    /**
     * From http://www.tapwise.com/svn/nfcwritetag/trunk/src/com/tapwise/nfcwritetag/MainActivity.java
     * @return
     */
    private NdefMessage getTagAsNdef(String new_card_id) 
    {  
        byte[] bytes = new_card_id.getBytes(Charset.forName("UTF-8"));
        byte[] payload = new byte[bytes.length + 1]; 
        System.arraycopy(bytes, 0, payload, 1, bytes.length);  //appends URI to payload
        NdefRecord record = new NdefRecord(
        NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);
        //NdefRecord new_record = createRecord(new_card_id);
        NdefRecord new_record = createTextRecord(new_card_id);
        return new NdefMessage(new NdefRecord[] {record, new_record}); 
    }
    
    /**
     * Create the record with the message passed in in the payload.
     * The card id in sector 1.  THere will be an en and byte info there also.
     * @param payload
     * @return
     */
    public NdefRecord createTextRecord(String payload) 
    {
      String language = "en";
      boolean encodeInUtf8 = true;
        byte[] langBytes = language.getBytes(Charset.forName("US-ASCII"));
        Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
        byte[] textBytes = payload.getBytes(utfEncoding);
        int utfBit = encodeInUtf8 ? 0 : (1 << 7);
        char status = (char) (utfBit + langBytes.length);
        byte[] data = new byte[1 + langBytes.length + textBytes.length];
        data[0] = (byte) status;
        System.arraycopy(langBytes, 0, data, 1, langBytes.length);
        System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
        NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
        NdefRecord.RTD_TEXT, new byte[0], data);
        return record;
    }
    
    /**
     * From http://www.tapwise.com/svn/nfcwritetag/trunk/src/com/tapwise/nfcwritetag/MainActivity.java
     * @param tag
     * @return
     */
    private boolean writableTag(Tag tag) 
    {
        try
        {
            Ndef ndef = Ndef.get(tag);
            if (ndef != null) 
            {
                ndef.connect();
                if (!ndef.isWritable()) 
                {
                    //Toast.makeText(context,"Tag is read-only.",Toast.LENGTH_SHORT).show();
                    ndef.close(); 
                    return false;
                }
                ndef.close();
                return true;
            } 
        } catch (Exception e) 
        {
            //Toast.makeText(context,"Failed to read tag",Toast.LENGTH_SHORT).show();
        }
        return false;
    }
    
    /**
     * From http://www.tapwise.com/svn/nfcwritetag/trunk/src/com/tapwise/nfcwritetag/MainActivity.java
     * @param techs
     * @return
     */
    public static boolean supportedTechs(String[] techs) 
    {
      UtilityTo.printArray(techs, "tech list");
      boolean mifare_classic=false;
      boolean nfcA=false;
      boolean ndef=false;
      for(String tech:techs) 
      {
        if(tech.equals("android.nfc.tech.MifareClassic")) 
        {
          mifare_classic=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;
        }
      }
        if(mifare_classic && nfcA && ndef) 
        {
          return true;
        } else 
        {
          return false;
        }
  }
  
  /**
   * First create a list of just the type of cards needed.
   * Then create an ordered hash of index card pairs.
   * @param type
   * @return
   */
  private Hashtable <String,DeckCard> sortCards(String type)
  {
    String method = "sortCards";
    Vector <DeckCard> type_results = new Vector <DeckCard> ();
    Enumeration<String> e = id_deck_cards.keys();
    while (e.hasMoreElements())
    {
      String key = e.nextElement();
      DeckCard card = id_deck_cards.get(key);
      String this_type = card.getType();
      if (this_type.equals(type))
      {
        type_results.add(card);
      }
    }
    //Log.i(DEBUG_TAG, method+" type "+type+" cards "+type_results.size());
    Hashtable <String,DeckCard> results = new Hashtable <String,DeckCard> ();
    for (int i = 0; i < type_results.size(); i++)
    {
      DeckCard deck_card = (DeckCard)type_results.get(i);
      int index = deck_card.getIndex();
      results.put(Integer.toString(index), deck_card);
      //Log.i(DEBUG_TAG, method+" i "+i+" index "+index+" deck_card "+deck_card.getCardName());
    }
    return results;
  }
  
  /**
   * Starting at 1 for cards, we load the amount of cards we have set in the number_of_cards extra.
   * 
   */
  private void getIntentInfo()
  {
    String method = "getIntentInfo";
    Intent sender = getIntent();
    String deck_name = sender.getExtras().getString("deck_name");
    String deck_id = sender.getExtras().getString("deck_id");
    String player_id = sender.getExtras().getString("player_id");
    String game_id = sender.getExtras().getString("game_id");
    id_deck_cards = new Hashtable <String,DeckCard> ();
    deck_card_name_ids = new Hashtable <String,String> ();
    house_deck = new HouseDeck();
    house_deck.setDeckId(deck_id);
    house_deck.setDeckName(deck_name);
    house_deck.setPlayerId(player_id);
    house_deck.setGameId(game_id);
    int number_of_cards = Integer.parseInt(sender.getExtras().getString("number_of_cards"));
    for (int i = 1; i < number_of_cards; i++)
    {
      try
      {
        DeckCard card = new DeckCard();
        String card_id = sender.getExtras().getString(i+"card_id");
        String card_name = sender.getExtras().getString(i+"card_name");
        String status = sender.getExtras().getString(i+"status");
        card.setCardId(card_id);
        card.setCardName(card_name);
        card.setStatus(status);
        card.setIndex(Integer.parseInt(sender.getExtras().getString(i+"index")));
        card.setType(sender.getExtras().getString(i+"type"));
        id_deck_cards.put(card.getCardId(), card);
        house_deck.setCards(card.getCardId(), card);
        deck_card_name_ids.put(card_name, card_id);
        //Log.i(DEBUG_TAG, method+" got "+card.getCardName()+" id "+card.getCardId()+" indes "+card.getIndex()+" type "+card.getType());
      } catch (java.lang.NullPointerException npe)
      {
        Log.i(DEBUG_TAG, method+" npe for "+i);
      }
    }
    setTitle(deck_name);
    Log.i(DEBUG_TAG, method+" number of cards got from intent: "+house_deck.getCards().size());
  }
  
  /**
    * This is called each time a NFC tag is detected.  This is the GameReadingStonesActivity
    */
   //@Override
   public void onNewIntent2(Intent intent) 
   {
     String method = "resolveIntent3";
    Log.i(DEBUG_TAG, method+": called.");
    Parcelable[] raw_messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
    NdefMessage[] ndef_messages = null;
    if (raw_messages != null) 
    {
      Log.i(DEBUG_TAG, method+" rawMsgs != null");
      ndef_messages = new NdefMessage[raw_messages.length];
        for (int i = 0; i < raw_messages.length; i++) 
        {
          NdefMessage ndef_message = (NdefMessage)raw_messages[i];
            Log.i(DEBUG_TAG, "i "+i+" ndef_message = "+ndef_message.toString());
            ndef_messages[i] = (NdefMessage) raw_messages[i];
        }
    } else
    {
      Log.i(DEBUG_TAG, method+" raw_messages == null, or it's a virtual device");
      String test_card_type = (String)intent.getExtras().getString("test_card");
      //getTestCard(test_card_type);
    }
    try
    {
      NdefRecord[] records = ndef_messages[0].getRecords();
      final int size = records.length;
      for (int i = 0; i < size; i++) 
      {
        NdefRecord record = records[i];
        String message = new String(record.getPayload());
        Log.i(DEBUG_TAG, method+" "+i+" message "+message);
        if (i==0)
        {
          Log.i(DEBUG_TAG, method+" "+i+" message "+message);
          associateWithCardsFile(message);
        }
      }
    } catch (java.lang.NullPointerException npe)
    {
      Log.i(DEBUG_TAG, method+" Problemo!");
      npe.printStackTrace();
    }
   }
   
   /**
    * Check to see if the id scanned from the NFC tag is associated with a deck card.
    * Load the cards file and see if the id matches any cards in it.  
    * Then display found deck card name if any and the card word/player name if any.
    * @param maybe_card_id
    */
   private void associateWithCardsFile(final String raw_card_id)
   {
     final String maybe_card_id = UtilityTo.removeHiddenCharacters(raw_card_id);
     final String method = "associateWithCardsFile";
     new Thread()
       {
           public void run()
           {   
             deck_card_name = "No deck card, "; // needs a space cause it comes first
              Hashtable<String,DeckCard> deck_cards = house_deck.getCards();
              Log.i(DEBUG_TAG, method+" deck_cards "+deck_cards.size());
              Enumeration <String> e = deck_cards.keys();
            while (e.hasMoreElements())
            {
              String key = (String) e.nextElement();
              DeckCard this_deck_card = (DeckCard) deck_cards.get(key);
              if (this_deck_card.getCardId().equals(maybe_card_id))
              {
                Log.i(DEBUG_TAG, method+" association made for "+this_deck_card.getCardName());
                deck_card_name = this_deck_card.getCardName()+", ";
              } else
              {
                Log.i(DEBUG_TAG, method+" key "+key+" "+this_deck_card.getCardName()+" compared to "+maybe_card_id+" and failed.");
              }
            }
               IWantTo i_want_to = new IWantTo(context);
               Vector <Card> file_cards = i_want_to.loadCardsFile();
               word_player_card = "No file card";
               Card found_card = getIdFileCard(file_cards, maybe_card_id);
               if (found_card != null)
               {
                 word_player_card = UtilityTo.getWord(found_card);
                 Log.i(DEBUG_TAG, method+" found card for palyer "+found_card.getPlayerName()+" id "+found_card.getPlayerName());
               }
               Log.i(DEBUG_TAG, method+" looking at file cards "+file_cards.size());
               activity.runOnUiThread(new Runnable()
                {
                    public void run()
                    {
                        Toast.makeText(context, deck_card_name+" "+word_player_card, Toast.LENGTH_LONG ).show();
                    }
                });
           }
       }.start();
   }
   
   /**
    * Debugging.
    */
   private void printDeckCards()
   {
     String method = "printDeckCards";
     Hashtable <String,DeckCard> deck_cards = house_deck.getCards();
     Enumeration <String> e = deck_cards.keys();
     while (e.hasMoreElements())
     {
       String key = (String)e.nextElement();
       DeckCard this_deck_card = house_deck.getCard(key);
       Log.i(DEBUG_TAG, method+" "+this_deck_card.getCardName()+" "+this_deck_card.getCardId());
           
     }
   }
   
   /**
    * Search through all the file cards for a card with the search_id equal to the card id.
    * If nonr id found return a null card. 
    * @param file_cards
    * @param search_id
    * @return
    */
   private Card getIdFileCard(Vector <Card> file_cards, String search_id)
   {
     String method = "getIdFileCard";
     Card my_card = null;
     for (int i=0; i < file_cards.size(); i++)
     {
       Card this_card = file_cards.get(i);
       if (this_card.getCardId().equals(search_id))
       {
         Log.i(DEBUG_TAG, method+" found "+this_card.getCardId()+" "+UtilityTo.getWord(this_card));
         my_card = this_card;
       } else
       {
         Log.i(DEBUG_TAG, method+" search id "+search_id+" doesn't match "+this_card.getCardId()+" "+UtilityTo.getWord(this_card));
       }
     }
     return my_card;
   }
   
   /**
    * From CardPlayerWordsActivity
    */
   @Override
   protected void onNewIntent(Intent intent)
   {
     String action = intent.getAction();
     new_intent = intent;
     String nfc_action = NfcAdapter.ACTION_TAG_DISCOVERED;
     Log.i(DEBUG_TAG, "onNewIntent(intent) action "+intent.getAction());
     Log.i(DEBUG_TAG, "onNewIntent(intent) nfc_action "+intent.getAction());
       if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) 
       {
           // reag TagTechnology object...
         card_tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
         Log.i(DEBUG_TAG, "onNewIntent(intent) ACTION_TAG_DISCOVERED");
       } else if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) 
       {
           // read NDEF message...
         card_tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
         Log.i(DEBUG_TAG, "onNewIntent(intent) ACTION_NDEF_DISCOVERED");
       } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) 
       {
         card_tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
         Log.i(DEBUG_TAG, "onNewIntent(intent) ACTION_TECH_DISCOVERED");
         if (!writing_new_id_mode)
         {
           onNewIntent2(intent);   
         }
       } else
       {
         Log.i(DEBUG_TAG, "onNewIntent: ACTION (not) DISCOVERED");
       }
   }
   
   @Override
   public void onPause() 
   {
       super.onPause();
       try
       {
         mfc_adapter.disableForegroundDispatch(this);
       } catch (java.lang.NullPointerException npe)
       {
         Log.i(DEBUG_TAG, "unable to disable Foreground Dispatch");
         npe.printStackTrace();
       }
   }
  
   /**
   * This method captures the NFC adapter which will be used to scan tags.
   * This is part of the "Foreground Dispatch" system.
   */
   @Override
    public void onResume() 
   {
        super.onResume();
        try
        {
          mfc_adapter.enableForegroundDispatch(this, pending_intent, filters, tech_lists_array);
        } catch (java.lang.NullPointerException npe)
        {
            Log.i(DEBUG_TAG, "onResume:  npeee!");
            mfc_adapter = NfcAdapter.getDefaultAdapter(context);
            //nfc_adapter.enableForegroundDispatch(this,pendingIntent,writeTagFilters,techListsArray);
        }
    }
   
   /**
    *   @Override
  public boolean onCreateOptionsMenu(Menu menu) 
  {
    getMenuInflater().inflate(R.menu.card_deck, menu);
    return true;
  }
    */
   
   public boolean onCreateOptionsMenu(Menu menu) 
      {
        super.onCreateOptionsMenu(menu);
        writing_new_id_mode = false;
      write_new_id = false;
      reuse_selected = true;
        write_selected = false;
        //menu.add(0, reuse_id, 0, "Reuse Card ID").setCheckable(true);
        getMenuInflater().inflate(R.menu.card_decks, menu);
        SubMenu id_choice = menu.addSubMenu("Reuse or Write ID").setIcon(android.R.drawable.ic_menu_gallery);
        id_choice.add(id_group, reuse_id, 1, "Reuse Old Card ID").setChecked(reuse_selected);
        id_choice.add(id_group, write_id, 1, "Write New Card ID").setChecked(write_selected);
        return true;
      }
   
   public boolean onOptionsItemSelected(MenuItem item) 
      {
        String method = "onOptionsItemSelected(MenuItem)";
        if (item.getItemId() == reuse_id)
        {
          Log.i(DEBUG_TAG, method+" set reuse true");
          reuse_selected = true;
          write_selected = false;
          write_new_id = false;
            return true;
        } if (item.getItemId() == write_id)
        {
          Log.i(DEBUG_TAG, method+" set wrtie true");
          reuse_selected = false;
          write_selected = true;
          write_new_id = true;
            return true;
        } 
        return super.onOptionsItemSelected(item);
      }

}




Java Source Code List

com.curchod.domartin.AsyncLoadGameFile.java
com.curchod.domartin.Constants.java
com.curchod.domartin.Filer.java
com.curchod.domartin.HouseDeck.java
com.curchod.domartin.IWantTo.java
com.curchod.domartin.MockNdefMessages.java
com.curchod.domartin.NfcUtils.java
com.curchod.domartin.RemoteCall.java
com.curchod.domartin.Sarray.java
com.curchod.domartin.Scoring.java
com.curchod.domartin.TagDescription.java
com.curchod.domartin.UtilityTo.java
com.curchod.dto.Card.java
com.curchod.dto.DeckCard.java
com.curchod.dto.GameWord.java
com.curchod.dto.Game.java
com.curchod.dto.PlayerInfo.java
com.curchod.dto.SavedTest.java
com.curchod.dto.SingleWordTestResult.java
com.curchod.dto.SingleWord.java
com.curchod.json.VocabularyDefinition.java
com.curchod.json.VocabularyLearningObject.java
com.curchod.wherewithal.AddPlayerActivity.java
com.curchod.wherewithal.CardDeckActivity.java
com.curchod.wherewithal.CardDecksActivity.java
com.curchod.wherewithal.CardPlayerHouseDeckActivity.java
com.curchod.wherewithal.CardPlayerWordsActivity.java
com.curchod.wherewithal.CardPlayersListActivity.java
com.curchod.wherewithal.CardsActivity.java
com.curchod.wherewithal.GameConcentrationActivity.java
com.curchod.wherewithal.GameReadingStonesActivity.java
com.curchod.wherewithal.GameReadingStonesInstructionsActivity.java
com.curchod.wherewithal.GameSnazzyThumbworkActivity.java
com.curchod.wherewithal.GameWritingStonesActivity.java
com.curchod.wherewithal.GamesActivity.java
com.curchod.wherewithal.InstructionsActivity.java
com.curchod.wherewithal.MainActivity.java
com.curchod.wherewithal.PlayerActivity.java
com.curchod.wherewithal.PlayersActivity.java