Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
199 views
in Technique[技术] by (71.8m points)

tags - Android NFC Writing doesn't work with 2 activities but works with 1

I found a tutorial on how to read and write a NDEF NFC tag via a Toggle Button.

I wanted 2 separate buttons and after several days and some help (I am a newbie on Android), I have now managed to do that. I have 2 buttons, related to 2 activities. Clicking on read button will open the read activity and read my tag. Clicking on the write button will open the write activity, pop up the keyboard. I type the text I want to write but when I touch the tag, it sends me back to my main activity where my 2 buttons are. Puzzled...

  • If I create a new app with only the writing code, I can write perfectly (and then read from another app) so I know the code works.

  • I have tried to disable my read button, but it doesn't change anything.

It must be a small thing but after several hours on it, I still cant figure it out. Could somebody please help? The code is below. Cheers.

 public class MainActivity extends Activity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(this);
        Button button2 = (Button) findViewById(R.id.button2);
        button2.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button1:

               Intent detailIntent = new Intent(this, ReadActivity.class);
                startActivity(detailIntent);
                break;

            case R.id.button2:

                Intent detailIntent2 = new Intent(this, WriteActivity3.class);
                startActivity(detailIntent2);
                break;
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}




 public class ReadActivity extends Activity {


     public static final String MIME_TEXT_PLAIN = "text/plain";
     public static final String TAG = "NfcDemo";

     private TextView mTextView;
     private NfcAdapter mNfcAdapter;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_read);

         mTextView = (TextView) findViewById(R.id.textView_explanation);

         mNfcAdapter = NfcAdapter.getDefaultAdapter(this);

         if (mNfcAdapter == null) {
             // Stop here, we definitely need NFC
             Toast.makeText(this, "This device doesn't support NFC.",
                     Toast.LENGTH_LONG).show();
             finish();
             return;

         }

         if (!mNfcAdapter.isEnabled()) {
             mTextView.setText("NFC is disabled.");
         } else {
             mTextView.setText("Touch a Tag");
         }

         handleIntent(getIntent());
     }

     @Override
     protected void onResume() {
         super.onResume();

         /**
          * It's important, that the activity is in the foreground (resumed). Otherwise
          * an IllegalStateException is thrown.
          */
         setupForegroundDispatch(this, mNfcAdapter);
     }

     @Override
     protected void onPause() {
         /**
          * Call this before onPause, otherwise an IllegalArgumentException is thrown as well.
          */
         stopForegroundDispatch(this, mNfcAdapter);

         super.onPause();
     }

     @Override
     protected void onNewIntent(Intent intent) {
         /**
          * This method gets called, when a new Intent gets associated with the current activity instance.
          * Instead of creating a new activity, onNewIntent will be called. For more information have a look
          * at the documentation.
          *
          * In our case this method gets called, when the user attaches a Tag to the device.
          */
         handleIntent(intent);
     }


     private void handleIntent(Intent intent) {
         String action = intent.getAction();
         if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {

             String type = intent.getType();
             if (MIME_TEXT_PLAIN.equals(type)) {

                 Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
                 new NdefReaderTask().execute(tag);

             } else {
                 Log.d(TAG, "Wrong mime type: " + type);
             }
         } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {

             // In case we would still use the Tech Discovered Intent
             Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
             String[] techList = tag.getTechList();
             String searchedTech = Ndef.class.getName();

             for (String tech : techList) {
                 if (searchedTech.equals(tech)) {
                     new NdefReaderTask().execute(tag);
                     break;
                 }
             }
         }
     }




     public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
         final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
         intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

         final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);

         IntentFilter[] filters = new IntentFilter[1];
         String[][] techList = new String[][]{};

         // Notice that this is the same filter as in our manifest.
         filters[0] = new IntentFilter();
         filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
         filters[0].addCategory(Intent.CATEGORY_DEFAULT);
         try {
             filters[0].addDataType(MIME_TEXT_PLAIN);
         } catch (MalformedMimeTypeException e) {
             throw new RuntimeException("Check your mime type.");
         }

         adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
     }


     public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) {
         adapter.disableForegroundDispatch(activity);
     }

     /**
      * Background task for reading the data. Do not block the UI thread while reading.
      */

     private class NdefReaderTask extends AsyncTask<Tag, Void, String> {

         @Override
         protected String doInBackground(Tag... params) {
             Tag tag = params[0];

             Ndef ndef = Ndef.get(tag);
             if (ndef == null) {
                 // NDEF is not supported by this Tag.
                 return null;
             }

             NdefMessage ndefMessage = ndef.getCachedNdefMessage();

             NdefRecord[] records = ndefMessage.getRecords();
             for (NdefRecord ndefRecord : records) {
                 if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
                     try {
                         return readText(ndefRecord);
                     } catch (UnsupportedEncodingException e) {
                         Log.e(TAG, "Unsupported Encoding", e);
                     }
                 }
             }

             return null;
         }

         private String readText(NdefRecord record) throws UnsupportedEncodingException {
        /*
         * See NFC forum specification for "Text Record Type Definition" at 3.2.1
         *
         * http://www.nfc-forum.org/specs/
         *
         * bit_7 defines encoding
         * bit_6 reserved for future use, must be 0
         * bit_5..0 length of IANA language code
         */

             byte[] payload = record.getPayload();

             // Get the Text Encoding

             // String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";

             String textEncoding = new String ("");
             if ((payload[0] & 128) == 0) {
                 textEncoding = "UTF-8";
             } else {
                 textEncoding = "UTF-16";
             }



             // Get the Language Code
             int languageCodeLength = payload[0] & 63;


             // String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
             // e.g. "en"

             // Get the Text
             return new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
         }

         @Override
         protected void onPostExecute(String result) {
             if (result != null) {
                 mTextView.setText("The content of the tag is :  " + result);
             }
         }
     }

 }







   public class WriteActivity3 extends Activity {

    NfcAdapter nfcAdapter;
    EditText txtTagContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_write_activity3);

        nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        txtTagContent = (EditText)findViewById(R.id.txtTagContent);

    }

    @Override
    protected void onResume() {
        super.onResume();

        enableForegroundDispatchSystem();
    }

    @Override
    protected void onPause() {
        super.onPause();

        disableForegroundDispatchSystem();
    }


    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        if (intent.hasExtra(NfcAdapter.EXTRA_TAG)) {
            Toast.makeText(this, "Tag detected...", Toast.LENGTH_SHORT).show();


            Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

            // Adding the time
            Date now = new Date();
            //Convert current time to String using specified format
            String format = "  dd-MMM-yyyy HH:mm:ss";
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format, Locale.US);
            String formattedNow = simpleDateFormat.format(now);

            NdefMessage ndefMessage = createNdefMessage(txtTagContent.getText() + formattedNow);

            writeNdefMessage(tag, ndefMessage);
        }

    }

    private void enableForegroundDispatchSystem() {

        Intent intent = new Intent(this, MainActivity.class).addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

        IntentFilter[] intentFilters = new IntentFilter[]{};

        nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFilters, null);
    }

    private void disableForegroundDispatchSystem() {
        nfcAdapter.disableForegroundDispatch(this);
    }

    private void formatTag(Tag tag, NdefMessage ndefMessage) {
        try {

            NdefFormatable ndefFormatable = NdefFormatable.get(tag);

            if (ndefFormatable == null) {
                Toast.makeText(this, "Tag is not ndef formatable!", Toast.LENGTH_SHORT).

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

OK, I found it. In my WriteActivite3.java, inside the private void enableForegroundDispatchSystem() {} I call for MainActivity and not for WriteActivity3. All working now.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...