Android NFC Writing不适用于2个活动,但适用于1

时间:2015-05-26 15:11:30

标签: android tags nfc writing

我找到了一个关于如何通过切换按钮读取和写入NDEF NFC标签的教程。

我想要2个单独的按钮,经过几天和一些帮助(我是Android上的新手),我现在设法做到了。我有2个按钮,与2个活动有关。单击“读取”按钮将打开读取活动并读取我的标签。单击写入按钮将打开写入活动,弹出键盘。我输入了我要写的文字但是当我触摸标签时,它会将我发回我的主要活动,我的2个按钮就在那里。不解...

  • 如果我创建一个只有编写代码的新应用程序,我可以完美地编写(然后从另一个应用程序中读取),所以我知道代码有效。

  • 我试图禁用我的阅读按钮,但它不会改变任何内容。

它必须是一件小事,但经过几个小时之后,我仍然无法理解 想办法。有人可以帮忙吗?代码如下。欢呼声。

 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).show();
                return;
            }


            ndefFormatable.connect();
            ndefFormatable.format(ndefMessage);
            ndefFormatable.close();

            Toast.makeText(this, "Message writen !", Toast.LENGTH_SHORT).show();

        } catch (Exception e) {
            Log.e("formatTag", e.getMessage());
        }

    }

    private void writeNdefMessage(Tag tag, NdefMessage ndefMessage) {

        try {

            if (tag == null) {
                Toast.makeText(this, "Tag object cannot be null", Toast.LENGTH_SHORT).show();
                return;
            }

            Ndef ndef = Ndef.get(tag);

            if (ndef == null) {
                // format tag with the ndef format and writes the message.
                formatTag(tag, ndefMessage);
            } else {
                ndef.connect();

                if (!ndef.isWritable()) {
                    Toast.makeText(this, "Tag is not writable!", Toast.LENGTH_SHORT).show();

                    ndef.close();
                    return;
                }

                ndef.writeNdefMessage(ndefMessage);
                ndef.close();

                Toast.makeText(this, "Tag writen!", Toast.LENGTH_SHORT).show();

            }

        } catch (Exception e) {
            Log.e("writeNdefMessage", e.getMessage());
        }

    }


    private NdefRecord createTextRecord(String content) {
        try {
            byte[] language;
            language = Locale.getDefault().getLanguage().getBytes("UTF-8");

            final byte[] text = content.getBytes("UTF-8");
            final int languageSize = language.length;
            final int textLength = text.length;
            final ByteArrayOutputStream payload = new ByteArrayOutputStream(1 + languageSize + textLength);

            payload.write((byte) (languageSize & 0x1F));
            payload.write(language, 0, languageSize);
            payload.write(text, 0, textLength);

            return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload.toByteArray());

        } catch (UnsupportedEncodingException e) {
            Log.e("createTextRecord", e.getMessage());
        }
        return null;
    }


    private NdefMessage createNdefMessage(String content) {

        NdefRecord ndefRecord = createTextRecord(content);

        NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]{ndefRecord});

        return ndefMessage;
    }


    public void tglReadWriteOnClick(View view){
        txtTagContent.setText("");
    }


    @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_write_activity3, 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);
    }
}


    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="uk.co.masystems.tagreader" >

    <uses-permission android:name="android.permission.NFC" />

    <uses-feature
        android:name="android.hardware.nfc"
        android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".ReadActivity"
            android:label="@string/app_name" >


            // only for NDEF alone
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="text/plain" />
            </intent-filter>
-->
        </activity>
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".WriteActivity"
            android:label="@string/title_activity_write" >
        </activity>
        <activity
            android:name=".WriteActivity2"
            android:label="@string/title_activity_write_activity2" >
        </activity>
        <activity
            android:name=".WriteActivity3"
            android:label="@string/title_activity_write_activity3" >
        </activity>
    </application>

</manifest>

1 个答案:

答案 0 :(得分:-1)

好的,我找到了。在我的WriteActivite3.java中,在private void enableForegroundDispatchSystem(){}中 我呼吁MainActivity而不是WriteActivity3。 一切正常。