android nfc中Ndef格式的读写

2023-11-11

原文地址

检测到标签后在Activity中的处理流程

1. 在onCreate()中获取NfcAdapter对象;

NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);

2.在onNewIntent()中获取Tag对象或者NdefMessage信息;

获取Tag对象:

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

获取NdefMessage信息:

Parcelable[] rawMsgs = getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)

3.也可以通过Tag创建Ndef对象等,以实现标签的属性和I/O操作。

Ndef ndef = Ndef.get(tag);


NDEF格式标签的读取流程

1. 在onCreate()中获取NfcAdapter对象;

2.在onNewIntent()中判断是否为NDEF格式标签(ACTION_NDEF_DISCOVERED),若是则获取NdefMessage

信息;(需要强制转换成NdefMessage对象)

Parcelable[] rawMsgs = getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)

3.对NdefMessage对象进行解析,获取相关的文本信息或Uri等。


NDEF格式标签的写入流程

1. 在onCreate()中获取NfcAdapter对象;

2.在onNewIntent()中获取Tag对象;

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

3.通过Tag创建Ndef对象;

Ndef ndef = Ndef.get(tag);

4.将文本等数据封装成NdefMessage;

5.判断是否为NDEF格式标签,

若是NDEF格式:

(1)允许进行标签操作:ndef.connect();

(2) 调用ndef.writeNdefMessage(NdefMessage)方法写入。

若非NDEF格式:

(1)NdefFromatable format = NdefFromatable.get();

(2)允许进行标签操作:format.connect();

(3)调用format.format(NdefMessage)方法写入。


NdefMessage信息结构


 Supported TNFs and their mappings:

Type Name Format (TNF) Mapping
TNF_ABSOLUTE_URI URI based on the type field.
TNF_EMPTY Falls back to ACTION_TECH_DISCOVERED.
TNF_EXTERNAL_TYPE URI based on the URN in the type field. The URN is encoded into the NDEF type field in a shortened form: <domain_name>:<service_name>. Android maps this to a URI in the form: vnd.android.nfc://ext/<domain_name>:<service_name>.
TNF_MIME_MEDIA MIME type based on the type field.
TNF_UNCHANGED Invalid in the first record, so falls back to ACTION_TECH_DISCOVERED.
TNF_UNKNOWN Falls back to ACTION_TECH_DISCOVERED.
TNF_WELL_KNOWN MIME type or URI depending on the Record Type Definition (RTD), which you set in the type field. See Table 2. for more information on available RTDs and their mappings.
Supported RTDs for TNF_WELL_KNOWN and their mappings:

Record Type Definition (RTD) Mapping
RTD_ALTERNATIVE_CARRIER Falls back to ACTION_TECH_DISCOVERED.
RTD_HANDOVER_CARRIER Falls back to ACTION_TECH_DISCOVERED.
RTD_HANDOVER_REQUEST Falls back to ACTION_TECH_DISCOVERED.
RTD_HANDOVER_SELECT Falls back to ACTION_TECH_DISCOVERED.
RTD_SMART_POSTER URI based on parsing the payload.
RTD_TEXT MIME type of text/plain.
RTD_URI URI based on payload.

说明:读取TNF的类型后(可以是上面第一张表中的类型),如果是TNF_WELL_KNOWN时,就可以获取RTD(对应格式良好的

{TNF_WELL_KNOWN}的标签的类型,可以是第二张表中的类型)


NdefRecord中的常用方法

1.可通过NdefRecord.getTnf()方法来获得TNF字段;

对应上图中Header中的Length

2.通过NdefRecord.getType()方法来获得RTD字段,当TNF为TNF_WELL_KNOWN时的RTD。

对应上图中Header中的Type

3.通过NdefRecord.getPayload()方法来获得实际读写的数据。

对应上图中的Payload

Header中的Identifier对应每个Record唯一的Id



NDEF文本格式

NdefMessage中的paylaod就是实际的数据,其中NDEF文本格式为:



NDEF Uri格式

1、NdefMessage中的paylaod就是实际的数据,其中NDEF文本格式为:


2、前缀需要查表解析


Android应用程序记录Android Application Records(AAR)

1、在Android4.0中引入应用程序记录(AAR),当扫描到写入AAR的NFC标签时,启动相应的应用程序。

2、AAR有嵌入到NdefRecord内部的应用程序包名。Android会针对AAR来搜索整个NdefMessage,如果找到一个AAR,就会基于AAR内部的包名来启动应用程序。

3、NFC标签调度系统对包含AAR标签的调度:

1.若跟Intent匹配的Activity也跟AAR匹配,则启动该Activity;

2.若跟Intent匹配,而跟AAR不匹配,则启动AAR指定的应用程序;

3.如果没有跟AAR对应的应用程序,则启动各种市场来下载对应基于AAR的应用程序。


Android应用程序记录创建方法

1、调用NdefRecord类的creatApplicationRecord()方法来创建应用程序记录。

2、将所创建的AAR嵌入到NdefMessage中。
NdefMessage msg = new NdefMessage(new Ndefrecord[]{…,NdefRecord. creatApplicationRecord(“com.example.android.beam”)})

3、除非AAR是你NdefMessage中的唯一记录,否则不要将AAR嵌入到NdefMessage的第一条记录。



NDEF for Text 读写,例子程序:

ReadWriteTextMainActivity:

[java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. package mobile.android.read.write.text;  
  2.   
  3. import java.nio.charset.Charset;  
  4. import java.util.Locale;  
  5. import android.app.Activity;  
  6. import android.content.Intent;  
  7. import android.nfc.NdefMessage;  
  8. import android.nfc.NdefRecord;  
  9. import android.nfc.NfcAdapter;  
  10. import android.nfc.Tag;  
  11. import android.nfc.tech.Ndef;  
  12. import android.nfc.tech.NdefFormatable;  
  13. import android.os.Bundle;  
  14. import android.view.View;  
  15. import android.widget.TextView;  
  16. import android.widget.Toast;  
  17.   
  18. public class ReadWriteTextMainActivity extends Activity {  
  19.     private TextView mInputText;  
  20.   
  21.     private String   mText;  
  22.   
  23.     @Override  
  24.     public void onCreate(Bundle savedInstanceState) {  
  25.         super.onCreate(savedInstanceState);  
  26.         setContentView(R.layout.activity_read_write_text_main);  
  27.         mInputText = (TextView) findViewById(R.id.textview_input_text);  
  28.   
  29.     }  
  30.   
  31.     //单击“输入要写入文本”按钮执行的方法  
  32.     public void onClick_InputText(View view) {  
  33.         Intent intent = new Intent(this, InputTextActivity.class);  
  34.         //显示输入文本的界面  
  35.         startActivityForResult(intent, 1);  
  36.   
  37.     }  
  38.   
  39.     @Override  
  40.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  41.         if (requestCode == 1 && resultCode == 1) {  
  42.             //获取要写入标签的文本  
  43.             mText = data.getStringExtra("text");  
  44.             //在主界面显示要写入标签的文本  
  45.             mInputText.setText(mText);  
  46.         }  
  47.     }  
  48.   
  49.     //当窗口的创建模式是singleTop或singleTask时调用,用于取代onCreate方法  
  50.     //当NFC标签靠近手机,建立连接后调用  
  51.     @Override  
  52.     public void onNewIntent(Intent intent) {  
  53.         //如果未设置要写入的文本,则读取标签上的文本数据  
  54.         if (mText == null) {  
  55.             Intent myIntent = new Intent(this, ShowNFCTagContentActivity.class);  
  56.             //将intent传入另一个窗口,显示界面窗口   
  57.             myIntent.putExtras(intent);  
  58.             //需要指定这个Action,传递Intent对象时,Action不会传递  
  59.             myIntent.setAction(NfcAdapter.ACTION_NDEF_DISCOVERED);  
  60.             startActivity(myIntent);  
  61.         }  
  62.         //将指定的文本写入NFC标签  
  63.         else {  
  64.             //获取Tag对象  
  65.             Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  
  66.             //创建NdefMessage对象和NdefRecord对象  
  67.             NdefMessage ndefMessage = new NdefMessage(  
  68.                     new NdefRecord[] {createTextRecord(mText)});  
  69.   
  70.             //开始向标签写入文本  
  71.             if (writeTag(ndefMessage, tag)) {  
  72.                 //如果成功写入文本,将mtext设为null  
  73.                 mText = null;  
  74.                 //将主窗口显示的要写入的文本清空,文本只能写入一次  
  75.                 //如要继续写入,需要再次指定新的文本,否则只会读取标签中的文本  
  76.                 mInputText.setText("");  
  77.             }  
  78.   
  79.         }  
  80.   
  81.     }  
  82.   
  83.     //创建一个封装要写入的文本的NdefRecord对象  
  84.     public NdefRecord createTextRecord(String text) {  
  85.         //生成语言编码的字节数组,中文编码  
  86.         byte[] langBytes = Locale.CHINA.getLanguage().getBytes(  
  87.                 Charset.forName("US-ASCII"));  
  88.         //将要写入的文本以UTF_8格式进行编码  
  89.         Charset utfEncoding = Charset.forName("UTF-8");  
  90.         //由于已经确定文本的格式编码为UTF_8,所以直接将payload的第1个字节的第7位设为0  
  91.         byte[] textBytes = text.getBytes(utfEncoding);  
  92.         int utfBit = 0;  
  93.         //定义和初始化状态字节  
  94.         char status = (char) (utfBit + langBytes.length);  
  95.         //创建存储payload的字节数组  
  96.         byte[] data = new byte[1 + langBytes.length + textBytes.length];  
  97.         //设置状态字节  
  98.         data[0] = (byte) status;  
  99.         //设置语言编码  
  100.         System.arraycopy(langBytes, 0, data, 1, langBytes.length);  
  101.         //设置实际要写入的文本  
  102.         System.arraycopy(textBytes, 0, data, 1 + langBytes.length,  
  103.                 textBytes.length);  
  104.         //根据前面设置的payload创建NdefRecord对象  
  105.         NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,  
  106.                 NdefRecord.RTD_TEXT, new byte[0], data);  
  107.         return record;  
  108.     }  
  109.   
  110.     //将NdefMessage对象写入标签,成功写入返回ture,否则返回false  
  111.     boolean writeTag(NdefMessage message, Tag tag) {  
  112.         int size = message.toByteArray().length;  
  113.   
  114.         try {  
  115.             //获取Ndef对象  
  116.             Ndef ndef = Ndef.get(tag);  
  117.             if (ndef != null) {  
  118.                 //允许对标签进行IO操作  
  119.                 ndef.connect();  
  120.   
  121.                 if (!ndef.isWritable()) {  
  122.                     Toast.makeText(this"NFC Tag是只读的!", Toast.LENGTH_LONG)  
  123.                             .show();  
  124.                     return false;  
  125.   
  126.                 }  
  127.                 if (ndef.getMaxSize() < size) {  
  128.                     Toast.makeText(this"NFC Tag的空间不足!", Toast.LENGTH_LONG)  
  129.                             .show();  
  130.                     return false;  
  131.                 }  
  132.   
  133.                 //向标签写入数据  
  134.                 ndef.writeNdefMessage(message);  
  135.                 Toast.makeText(this"已成功写入数据!", Toast.LENGTH_LONG).show();  
  136.                 return true;  
  137.   
  138.             } else {  
  139.                 //获取可以格式化和向标签写入数据NdefFormatable对象  
  140.                 NdefFormatable format = NdefFormatable.get(tag);  
  141.                 //向非NDEF格式或未格式化的标签写入NDEF格式数据  
  142.                 if (format != null) {  
  143.                     try {  
  144.                         //允许对标签进行IO操作  
  145.                         format.connect();  
  146.                         format.format(message);  
  147.                         Toast.makeText(this"已成功写入数据!", Toast.LENGTH_LONG)  
  148.                                 .show();  
  149.                         return true;  
  150.   
  151.                     } catch (Exception e) {  
  152.                         Toast.makeText(this"写入NDEF格式数据失败!", Toast.LENGTH_LONG)  
  153.                                 .show();  
  154.                         return false;  
  155.                     }  
  156.                 } else {  
  157.                     Toast.makeText(this"NFC标签不支持NDEF格式!", Toast.LENGTH_LONG)  
  158.                             .show();  
  159.                     return false;  
  160.   
  161.                 }  
  162.             }  
  163.         } catch (Exception e) {  
  164.             Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();  
  165.             return false;  
  166.         }  
  167.   
  168.     }  
  169. }  
InputTextActivity:
[java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. package mobile.android.read.write.text;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.widget.EditText;  
  8.   
  9. public class InputTextActivity extends Activity {  
  10.     private EditText mTextTag;  
  11.   
  12.     @Override  
  13.     public void onCreate(Bundle savedInstanceState) {  
  14.         super.onCreate(savedInstanceState);  
  15.         setContentView(R.layout.activity_input_text);  
  16.         mTextTag = (EditText) findViewById(R.id.edittext_text_tag);  
  17.     }  
  18.   
  19.     public void onClick_OK(View view) {  
  20.         Intent intent = new Intent();  
  21.         intent.putExtra("text", mTextTag.getText().toString());  
  22.         setResult(1, intent);  
  23.         finish();  
  24.     }  
  25.   
  26. }  
ShowNFCTagContentActivity:
[java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. package mobile.android.read.write.text;  
  2.   
  3. import mobile.android.read.write.text.library.TextRecord;  
  4. import android.app.Activity;  
  5. import android.content.Intent;  
  6. import android.nfc.NdefMessage;  
  7. import android.nfc.NdefRecord;  
  8. import android.nfc.NfcAdapter;  
  9. import android.nfc.Tag;  
  10. import android.nfc.tech.Ndef;  
  11. import android.os.Bundle;  
  12. import android.os.Parcelable;  
  13. import android.widget.TextView;  
  14. import android.widget.Toast;  
  15.   
  16. public class ShowNFCTagContentActivity extends Activity {  
  17.     private TextView mTagContent;  
  18.   
  19.     private Tag      mDetectedTag;  
  20.   
  21.     private String   mTagText;  
  22.   
  23.     private void readAndShowData(Intent intent) {  
  24.         mDetectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  
  25.         Ndef ndef = Ndef.get(mDetectedTag);  
  26.         mTagText = ndef.getType() + "\n最大数据容量:" + ndef.getMaxSize()  
  27.                 + " bytes\n\n";  
  28.         readNFCTag();  
  29.         mTagContent.setText(mTagText);  
  30.     }  
  31.   
  32.     @Override  
  33.     public void onCreate(Bundle savedInstanceState) {  
  34.         super.onCreate(savedInstanceState);  
  35.         setContentView(R.layout.activity_show_nfctag_content);  
  36.         mTagContent = (TextView) findViewById(R.id.textview_tag_content);  
  37.         //获取Tag对象         
  38.         mDetectedTag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);  
  39.         //创建Ndef对象    
  40.         Ndef ndef = Ndef.get(mDetectedTag);  
  41.         //获取标签的类型和最大容量  
  42.         mTagText = ndef.getType() + "\n最大数据容量:" + ndef.getMaxSize()  
  43.                 + " bytes\n\n";  
  44.         //读取NFC标签的数据并解析  
  45.         readNFCTag();  
  46.         //将标签的相关信息显示在界面上  
  47.         mTagContent.setText(mTagText);  
  48.   
  49.     }  
  50.   
  51.     private void readNFCTag() {  
  52.         //判断是否为ACTION_NDEF_DISCOVERED  
  53.         if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {  
  54.             //从标签读取数据(Parcelable对象)  
  55.             Parcelable[] rawMsgs = getIntent().getParcelableArrayExtra(  
  56.                     NfcAdapter.EXTRA_NDEF_MESSAGES);  
  57.   
  58.             NdefMessage msgs[] = null;  
  59.             int contentSize = 0;  
  60.             if (rawMsgs != null) {  
  61.                 msgs = new NdefMessage[rawMsgs.length];  
  62.                 //标签可能存储了多个NdefMessage对象,一般情况下只有一个NdefMessage对象  
  63.                 for (int i = 0; i < rawMsgs.length; i++) {  
  64.                     //转换成NdefMessage对象                
  65.                     msgs[i] = (NdefMessage) rawMsgs[i];  
  66.                     //计算数据的总长度  
  67.                     contentSize += msgs[i].toByteArray().length;  
  68.   
  69.                 }  
  70.             }  
  71.             try {  
  72.   
  73.                 if (msgs != null) {  
  74.                     //程序中只考虑了1个NdefRecord对象,若是通用软件应该考虑所有的NdefRecord对象  
  75.                     NdefRecord record = msgs[0].getRecords()[0];  
  76.                     //分析第1个NdefRecorder,并创建TextRecord对象  
  77.                     TextRecord textRecord = TextRecord.parse(msgs[0]  
  78.                             .getRecords()[0]);  
  79.                     //获取实际的数据占用的大小,并显示在窗口上  
  80.                     mTagText += textRecord.getText() + "\n\n纯文本\n"  
  81.                             + contentSize + " bytes";  
  82.   
  83.                 }  
  84.   
  85.             } catch (Exception e) {  
  86.                 mTagContent.setText(e.getMessage());  
  87.             }  
  88.         }  
  89.     }  
  90. }  
TextRecord:
[java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. package mobile.android.read.write.text.library;  
  2.   
  3. import java.io.UnsupportedEncodingException;  
  4. import java.util.Arrays;  
  5. import android.nfc.NdefRecord;  
  6.   
  7. public class TextRecord {  
  8.     //存储解析出来的文本  
  9.     private final String mText;  
  10.   
  11.     //不允许直接创建TextRecord对象,所以将构造方法声明为private  
  12.     private TextRecord(String text) {  
  13.   
  14.         mText = text;  
  15.     }  
  16.   
  17.     //通过该方法可以获取解析出来的文本  
  18.     public String getText() {  
  19.         return mText;  
  20.     }  
  21.   
  22.     //  将纯文本内容从NdefRecord对象(payload)中解析出来  
  23.     public static TextRecord parse(NdefRecord record) {  
  24.         //验证TNF是否为NdefRecord.TNF_WELL_KNOWN  
  25.         if (record.getTnf() != NdefRecord.TNF_WELL_KNOWN)  
  26.             return null;  
  27.         //验证可变长度类型是否为RTD_TEXT  
  28.         if (!Arrays.equals(record.getType(), NdefRecord.RTD_TEXT))  
  29.             return null;  
  30.   
  31.         try {  
  32.             //获取payload  
  33.             byte[] payload = record.getPayload();  
  34.             //下面代码分析payload:状态字节+ISO语言编码(ASCLL)+文本数据(UTF_8/UTF_16)  
  35.             //其中payload[0]放置状态字节:如果bit7为0,文本数据以UTF_8格式编码,如果为1则以UTF_16编码  
  36.             //bit6是保留位,默认为0  
  37.             /* 
  38.              * payload[0] contains the "Status Byte Encodings" field, per the 
  39.              * NFC Forum "Text Record Type Definition" section 3.2.1. 
  40.              *  
  41.              * bit7 is the Text Encoding Field. 
  42.              *  
  43.              * if (Bit_7 == 0): The text is encoded in UTF-8 if (Bit_7 == 1): 
  44.              * The text is encoded in UTF16 
  45.              *  
  46.              * Bit_6 is reserved for future use and must be set to zero. 
  47.              *  
  48.              * Bits 5 to 0 are the length of the IANA language code. 
  49.              */  
  50.             String textEncoding = ((payload[0] & 0x80) == 0) ? "UTF-8"  
  51.                     : "UTF-16";  
  52.             //处理bit5-0。bit5-0表示语言编码长度(字节数)  
  53.             int languageCodeLength = payload[0] & 0x3f;  
  54.             //获取语言编码(从payload的第2个字节读取languageCodeLength个字节作为语言编码)  
  55.             String languageCode = new String(payload, 1, languageCodeLength,  
  56.                     "US-ASCII");  
  57.             //解析出实际的文本数据  
  58.             String text = new String(payload, languageCodeLength + 1,  
  59.                     payload.length - languageCodeLength - 1, textEncoding);  
  60.             //创建一个TextRecord对象,并返回该对象  
  61.             return new TextRecord(text);  
  62.         } catch (UnsupportedEncodingException e) {  
  63.             // should never happen unless we get a malformed tag.  
  64.             throw new IllegalArgumentException(e);  
  65.         }  
  66.     }  
  67. }  
AndroidManifest.xml:
[html]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     package="mobile.android.read.write.text"  
  3.     android:versionCode="1"  
  4.     android:versionName="1.0" >  
  5.   
  6.     <uses-sdk  
  7.         android:minSdkVersion="15"  
  8.         android:targetSdkVersion="15" />  
  9.   
  10.     <uses-permission android:name="android.permission.NFC" />  
  11.   
  12.     <application  
  13.         android:icon="@drawable/ic_launcher"  
  14.         android:label="@string/app_name"  
  15.         android:theme="@style/AppTheme" >  
  16.         <activity  
  17.             android:name=".ReadWriteTextMainActivity"  
  18.             android:label="读写NFC标签的纯文本数据"  
  19.             android:launchMode="singleTask" >  
  20.             <intent-filter>  
  21.                 <action android:name="android.intent.action.MAIN" />  
  22.                 <category android:name="android.intent.category.LAUNCHER" />  
  23.             </intent-filter>  
  24.             <intent-filter>  
  25.                 <action android:name="android.nfc.action.NDEF_DISCOVERED" />  
  26.                 <category android:name="android.intent.category.DEFAULT" />  
  27.                 <data android:mimeType="text/plain" />  
  28.             </intent-filter>  
  29.         </activity>  
  30.         <activity  
  31.             android:name=".ShowNFCTagContentActivity"  
  32.             android:label="显示NFC标签内容"  
  33.             android:launchMode="singleTask" />  
  34.         <activity  
  35.             android:name=".InputTextActivity"  
  36.             android:label="向NFC标签写入文本" />  
  37.     </application>  
  38. </manifest>  

NDEF for URL 读写,例子程序:

ReadWriteUriMainActivity:

[java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. package mobile.android.read.write.uri;  
  2.   
  3. import mobile.android.read.write.uri.library.UriRecord;  
  4. import android.app.Activity;  
  5. import android.content.Intent;  
  6. import android.nfc.NdefMessage;  
  7. import android.nfc.NdefRecord;  
  8. import android.nfc.NfcAdapter;  
  9. import android.nfc.Tag;  
  10. import android.nfc.tech.Ndef;  
  11. import android.nfc.tech.NdefFormatable;  
  12. import android.os.Bundle;  
  13. import android.view.View;  
  14. import android.widget.TextView;  
  15. import android.widget.Toast;  
  16.   
  17. public class ReadWriteUriMainActivity extends Activity {  
  18.     private TextView mSelectUri;  
  19.   
  20.     private String   mUri;  
  21.   
  22.     @Override  
  23.     public void onCreate(Bundle savedInstanceState) {  
  24.         super.onCreate(savedInstanceState);  
  25.         setContentView(R.layout.activity_read_write_uri_main);  
  26.         mSelectUri = (TextView) findViewById(R.id.textview_uri);  
  27.   
  28.     }  
  29.   
  30.     public void onClick_SelectUri(View view) {  
  31.         Intent intent = new Intent(this, UriListActivity.class);  
  32.         startActivityForResult(intent, 1);  
  33.   
  34.     }  
  35.   
  36.     @Override  
  37.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  38.         if (requestCode == 1 && resultCode == 1) {  
  39.             mUri = data.getStringExtra("uri");  
  40.             mSelectUri.setText(mUri);  
  41.         }  
  42.     }  
  43.   
  44.     @Override  
  45.     public void onNewIntent(Intent intent) {  
  46.         if (mUri == null) {  
  47.             Intent myIntent = new Intent(this, ShowNFCTagContentActivity.class);  
  48.             myIntent.putExtras(intent);  
  49.             myIntent.setAction(NfcAdapter.ACTION_NDEF_DISCOVERED);  
  50.             startActivity(myIntent);  
  51.         } else {  
  52.             Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  
  53.             NdefMessage ndefMessage = new NdefMessage(  
  54.                     new NdefRecord[] {createUriRecord(mUri)});  
  55.   
  56.             if (writeTag(ndefMessage, tag)) {  
  57.                 mUri = null;  
  58.                 mSelectUri.setText("");  
  59.             }  
  60.   
  61.         }  
  62.   
  63.     }  
  64.   
  65.     public NdefRecord createUriRecord(String uriStr) {  
  66.   
  67.         byte prefix = 0;  
  68.         //从uri前缀集合中找到匹配的前缀,并获得相应的标识代码  
  69.         for (Byte b : UriRecord.URI_PREFIX_MAP.keySet()) {  
  70.             //将Uri前缀转换成小写  
  71.             String prefixStr = UriRecord.URI_PREFIX_MAP.get(b).toLowerCase();  
  72.             //前缀不为空串  
  73.             if ("".equals(prefixStr))  
  74.                 continue;  
  75.             //比较Uri前缀  
  76.             if (uriStr.toLowerCase().startsWith(prefixStr)) {  
  77.                 //用字节表示的Uri前缀  
  78.                 prefix = b;  
  79.                 //截取完整Uri中除了Uri前缀外的其他部分  
  80.                 uriStr = uriStr.substring(prefixStr.length());  
  81.                 break;  
  82.             }  
  83.         }  
  84.         //为存储在标签中的Uri创建一个Byte数组  
  85.         byte[] data = new byte[1 + uriStr.length()];  
  86.         //指定第1字节为Uri前缀的标识代码  
  87.         data[0] = prefix;  
  88.         //将剩余的部分复制到data字节数组中  
  89.         System.arraycopy(uriStr.getBytes(), 0, data, 1, uriStr.length());  
  90.         //创建封装uri的NdefRecord对象  
  91.         NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,  
  92.                 NdefRecord.RTD_URI, new byte[0], data);  
  93.         //返回NdefRecord对象  
  94.         return record;  
  95.     }  
  96.   
  97.     boolean writeTag(NdefMessage message, Tag tag) {  
  98.         int size = message.toByteArray().length;  
  99.   
  100.         try {  
  101.   
  102.             Ndef ndef = Ndef.get(tag);  
  103.             if (ndef != null) {  
  104.                 ndef.connect();  
  105.   
  106.                 if (!ndef.isWritable()) {  
  107.                     Toast.makeText(this"NFC Tag是只读的!", Toast.LENGTH_LONG)  
  108.                             .show();  
  109.                     return false;  
  110.   
  111.                 }  
  112.                 if (ndef.getMaxSize() < size) {  
  113.                     Toast.makeText(this"NFC Tag的空间不足!", Toast.LENGTH_LONG)  
  114.                             .show();  
  115.                     return false;  
  116.                 }  
  117.   
  118.                 ndef.writeNdefMessage(message);  
  119.                 Toast.makeText(this"已成功写入数据!", Toast.LENGTH_LONG).show();  
  120.                 return true;  
  121.   
  122.             } else {  
  123.                 NdefFormatable format = NdefFormatable.get(tag);  
  124.                 if (format != null) {  
  125.                     try {  
  126.                         format.connect();  
  127.                         format.format(message);  
  128.                         Toast.makeText(this"已成功写入数据!", Toast.LENGTH_LONG)  
  129.                                 .show();  
  130.                         return true;  
  131.   
  132.                     } catch (Exception e) {  
  133.                         Toast.makeText(this"写入NDEF格式数据失败!", Toast.LENGTH_LONG)  
  134.                                 .show();  
  135.                         return false;  
  136.                     }  
  137.                 } else {  
  138.                     Toast.makeText(this"NFC标签不支持NDEF格式!", Toast.LENGTH_LONG)  
  139.                             .show();  
  140.                     return false;  
  141.   
  142.                 }  
  143.             }  
  144.         } catch (Exception e) {  
  145.             Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();  
  146.             return false;  
  147.         }  
  148.   
  149.     }  
  150. }  
UriListActivity:
[java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. package mobile.android.read.write.uri;  
  2.   
  3. import android.app.ListActivity;  
  4. import android.content.Intent;  
  5. import android.graphics.Camera;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.widget.AdapterView;  
  9. import android.widget.AdapterView.OnItemClickListener;  
  10. import android.widget.ArrayAdapter;  
  11. import android.widget.SimpleAdapter;  
  12.   
  13. public class UriListActivity extends ListActivity implements  
  14.         OnItemClickListener {  
  15.     private String uris[] = new String[] {"http://www.google.com",  
  16.             "http://www.apple.com""http://developer.apple.com",  
  17.             "http://www.126.com""ftp://192.168.17.160",  
  18.             "https://192.168.17.120""smb://192.168.17.100"};  
  19.   
  20.     @Override  
  21.     public void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,  
  24.                 android.R.layout.simple_list_item_1, android.R.id.text1, uris);  
  25.         setListAdapter(arrayAdapter);  
  26.         getListView().setOnItemClickListener(this);  
  27.     }  
  28.   
  29.     @Override  
  30.     public void onItemClick(AdapterView<?> parent, View view, int position,  
  31.             long id) {  
  32.         Intent intent = new Intent();  
  33.         intent.putExtra("uri", uris[position]);  
  34.         setResult(1, intent);  
  35.         finish();  
  36.   
  37.     }  
  38.   
  39. }  
ShowNFCTagContentActivity:
[java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. package mobile.android.read.write.uri;  
  2.   
  3. import mobile.android.read.write.uri.library.UriRecord;  
  4. import android.app.Activity;  
  5. import android.nfc.NdefMessage;  
  6. import android.nfc.NdefRecord;  
  7. import android.nfc.NfcAdapter;  
  8. import android.nfc.Tag;  
  9. import android.nfc.tech.Ndef;  
  10. import android.os.Bundle;  
  11. import android.os.Parcelable;  
  12. import android.widget.TextView;  
  13.   
  14. public class ShowNFCTagContentActivity extends Activity {  
  15.     private TextView mTagContent;  
  16.   
  17.     private Tag      mDetectedTag;  
  18.   
  19.     private String   mTagText;  
  20.   
  21.     @Override  
  22.     public void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.activity_show_nfctag_content);  
  25.         mTagContent = (TextView) findViewById(R.id.textview_tag_content);  
  26.         mDetectedTag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);  
  27.         Ndef ndef = Ndef.get(mDetectedTag);  
  28.         mTagText = ndef.getType() + "\n最大数据容量:" + ndef.getMaxSize()  
  29.                 + " bytes\n\n";  
  30.         readNFCTag();  
  31.         mTagContent.setText(mTagText);  
  32.     }  
  33.   
  34.     private void readNFCTag() {  
  35.   
  36.         if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {  
  37.   
  38.             Parcelable[] rawMsgs = getIntent().getParcelableArrayExtra(  
  39.                     NfcAdapter.EXTRA_NDEF_MESSAGES);  
  40.   
  41.             NdefMessage ndefMessage = null;  
  42.             int contentSize = 0;  
  43.             if (rawMsgs != null) {  
  44.   
  45.                 if (rawMsgs.length > 0) {  
  46.                     ndefMessage = (NdefMessage) rawMsgs[0];  
  47.                     contentSize = ndefMessage.toByteArray().length;  
  48.                 } else {  
  49.                     return;  
  50.                 }  
  51.             }  
  52.             try {  
  53.   
  54.                 NdefRecord record = ndefMessage.getRecords()[0];  
  55.   
  56.                 UriRecord uriRecord = UriRecord  
  57.                         .parse(ndefMessage.getRecords()[0]);  
  58.   
  59.                 mTagText += uriRecord.getUri().toString() + "\n\nUri\n"  
  60.                         + contentSize + " bytes";  
  61.   
  62.             } catch (Exception e) {  
  63.                 mTagContent.setText(e.getMessage());  
  64.             }  
  65.         }  
  66.   
  67.     }  
  68. }  
UriRecord.java
[java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. package mobile.android.read.write.uri.library;  
  2.   
  3. import java.nio.charset.Charset;  
  4. import java.util.Arrays;  
  5. import java.util.HashMap;  
  6. import java.util.Map;  
  7. import android.net.Uri;  
  8. import android.nfc.NdefRecord;  
  9.   
  10. public class UriRecord {  
  11.     //映射Uri前缀和对应的值  
  12.     public static final Map<Byte, String> URI_PREFIX_MAP = new HashMap<Byte, String>();  
  13.     static {  
  14.         //设置NDEF Uri规范支持的Uri前缀,在解析payload时,需要根据payload的第1个字节定位相应的uri前缀  
  15.         URI_PREFIX_MAP.put((byte0x00"");  
  16.         URI_PREFIX_MAP.put((byte0x01"http://www.");  
  17.         URI_PREFIX_MAP.put((byte0x02"https://www.");  
  18.         URI_PREFIX_MAP.put((byte0x03"http://");  
  19.         URI_PREFIX_MAP.put((byte0x04"https://");  
  20.         URI_PREFIX_MAP.put((byte0x05"tel:");  
  21.         URI_PREFIX_MAP.put((byte0x06"mailto:");  
  22.         URI_PREFIX_MAP.put((byte0x07"ftp://anonymous:anonymous@");  
  23.         URI_PREFIX_MAP.put((byte0x08"ftp://ftp.");  
  24.         URI_PREFIX_MAP.put((byte0x09"ftps://");  
  25.         URI_PREFIX_MAP.put((byte0x0A"sftp://");  
  26.         URI_PREFIX_MAP.put((byte0x0B"smb://");  
  27.         URI_PREFIX_MAP.put((byte0x0C"nfs://");  
  28.         URI_PREFIX_MAP.put((byte0x0D"ftp://");  
  29.         URI_PREFIX_MAP.put((byte0x0E"dav://");  
  30.         URI_PREFIX_MAP.put((byte0x0F"news:");  
  31.         URI_PREFIX_MAP.put((byte0x10"telnet://");  
  32.         URI_PREFIX_MAP.put((byte0x11"imap:");  
  33.         URI_PREFIX_MAP.put((byte0x12"rtsp://");  
  34.         URI_PREFIX_MAP.put((byte0x13"urn:");  
  35.         URI_PREFIX_MAP.put((byte0x14"pop:");  
  36.         URI_PREFIX_MAP.put((byte0x15"sip:");  
  37.         URI_PREFIX_MAP.put((byte0x16"sips:");  
  38.         URI_PREFIX_MAP.put((byte0x17"tftp:");  
  39.         URI_PREFIX_MAP.put((byte0x18"btspp://");  
  40.         URI_PREFIX_MAP.put((byte0x19"btl2cap://");  
  41.         URI_PREFIX_MAP.put((byte0x1A"btgoep://");  
  42.         URI_PREFIX_MAP.put((byte0x1B"tcpobex://");  
  43.         URI_PREFIX_MAP.put((byte0x1C"irdaobex://");  
  44.         URI_PREFIX_MAP.put((byte0x1D"file://");  
  45.         URI_PREFIX_MAP.put((byte0x1E"urn:epc:id:");  
  46.         URI_PREFIX_MAP.put((byte0x1F"urn:epc:tag:");  
  47.         URI_PREFIX_MAP.put((byte0x20"urn:epc:pat:");  
  48.         URI_PREFIX_MAP.put((byte0x21"urn:epc:raw:");  
  49.         URI_PREFIX_MAP.put((byte0x22"urn:epc:");  
  50.         URI_PREFIX_MAP.put((byte0x23"urn:nfc:");  
  51.     }  
  52.   
  53.     private final Uri                     mUri;  
  54.   
  55.     private UriRecord(Uri uri) {  
  56.         this.mUri = uri;  
  57.     }  
  58.   
  59.     //获取已经解析的Uri  
  60.     public Uri getUri() {  
  61.         return mUri;  
  62.     }  
  63.   
  64.     public static UriRecord parse(NdefRecord record) {  
  65.         //获取TNF  
  66.         short tnf = record.getTnf();  
  67.         //TNF是TNF_WELL_KNOWN,使用了前缀的Uri  
  68.         if (tnf == NdefRecord.TNF_WELL_KNOWN) {  
  69.             return parseWellKnown(record);  
  70.         }  
  71.         //TNF是TNF_ABSOLUTE_URI,即绝对Uri,不使用前缀  
  72.         else if (tnf == NdefRecord.TNF_ABSOLUTE_URI) {  
  73.             return parseAbsolute(record);  
  74.         }  
  75.         throw new IllegalArgumentException("Unknown TNF " + tnf);  
  76.     }  
  77.   
  78.     /** Parse and absolute URI record */  
  79.     private static UriRecord parseAbsolute(NdefRecord record) {  
  80.         //直接将payload转成uri  
  81.         byte[] payload = record.getPayload();  
  82.         Uri uri = Uri.parse(new String(payload, Charset.forName("UTF-8")));  
  83.         return new UriRecord(uri);  
  84.     }  
  85.   
  86.     /** Parse an well known URI record */  
  87.     private static UriRecord parseWellKnown(NdefRecord record) {  
  88.         //判断RTD是否为RTD_URI  
  89.         if (!Arrays.equals(record.getType(), NdefRecord.RTD_URI))  
  90.             return null;  
  91.         byte[] payload = record.getPayload();  
  92.         /* 
  93.          * payload[0] contains the URI Identifier Code, per the NFC Forum 
  94.          * "URI Record Type Definition" section 3.2.2. 
  95.          *  
  96.          * payload[1]...payload[payload.length - 1] contains the rest of the 
  97.          * URI. 
  98.          */  
  99.         //payload[0]中包括URI标识代码,也就是URI_PREFIX_MAP中的key  
  100.         //根据Uri标识代码获取Uri前缀  
  101.         String prefix = URI_PREFIX_MAP.get(payload[0]);  
  102.         //获取Uri前缀占用的字节数  
  103.         byte[] prefixBytes = prefix.getBytes(Charset.forName("UTF-8"));  
  104.         //为容纳完整的Uri创建一个byte数组  
  105.         byte[] fullUri = new byte[prefixBytes.length + payload.length - 1];  
  106.         //将Uri前缀和其余部分组合,形成一个完整的Uri  
  107.         System.arraycopy(prefixBytes, 0, fullUri, 0, prefixBytes.length);  
  108.         System.arraycopy(payload, 1, fullUri, prefixBytes.length,  
  109.                 payload.length - 1);  
  110.         //根据解析出来的Uri创建Uri对象  
  111.         Uri uri = Uri.parse(new String(fullUri, Charset.forName("UTF-8")));  
  112.         //创建UriRecord对象并返回  
  113.         return new UriRecord(uri);  
  114.     }  
  115.   
  116. }  
清单文件:
[html]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     package="mobile.android.read.write.uri"  
  3.     android:versionCode="1"  
  4.     android:versionName="1.0" >  
  5.   
  6.     <uses-sdk  
  7.         android:minSdkVersion="15"  
  8.         android:targetSdkVersion="15" />  
  9.   
  10.     <uses-permission android:name="android.permission.NFC" />  
  11.   
  12.     <application  
  13.         android:icon="@drawable/ic_launcher"  
  14.         android:label="@string/app_name"  
  15.         android:theme="@style/AppTheme" >  
  16.         <activity  
  17.             android:name=".ReadWriteUriMainActivity"  
  18.             android:label="读写NFC标签的Uri"  
  19.             android:launchMode="singleTask" >  
  20.             <intent-filter>  
  21.                 <action android:name="android.intent.action.MAIN" />  
  22.   
  23.                 <category android:name="android.intent.category.LAUNCHER" />  
  24.             </intent-filter>  
  25.             <intent-filter>  
  26.                 <action android:name="android.nfc.action.NDEF_DISCOVERED" />  
  27.   
  28.                 <category android:name="android.intent.category.DEFAULT" />  
  29.   
  30.                 <data android:scheme="http" />  
  31.                 <data android:scheme="https" />  
  32.                 <data android:scheme="ftp" />  
  33.             </intent-filter>  
  34.         </activity>  
  35.         <activity  
  36.             android:name=".ShowNFCTagContentActivity"  
  37.             android:label="显示NFC标签内容" />  
  38.         <activity  
  39.             android:name=".UriListActivity"  
  40.             android:label="选择Uri" />  
  41.     </application>  
  42.   
  43. </manifest>  

AAR例子程序:

AutoRunApplicationActivity:

[java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. package mobile.android.auto.run.application;  
  2.   
  3. import java.net.URI;  
  4.   
  5. import android.app.Activity;  
  6. import android.app.PendingIntent;  
  7. import android.content.Intent;  
  8. import android.net.Uri;  
  9. import android.nfc.NdefMessage;  
  10. import android.nfc.NdefRecord;  
  11. import android.nfc.NfcAdapter;  
  12. import android.nfc.Tag;  
  13. import android.nfc.tech.Ndef;  
  14. import android.nfc.tech.NdefFormatable;  
  15. import android.os.Bundle;  
  16. import android.view.View;  
  17. import android.widget.Button;  
  18. import android.widget.Toast;  
  19.   
  20. public class AutoRunApplicationActivity extends Activity {  
  21.     private Button        mSelectAutoRunApplication;  
  22.   
  23.     private String        mPackageName;  
  24.   
  25.     private NfcAdapter    mNfcAdapter;  
  26.   
  27.     private PendingIntent mPendingIntent;  
  28.   
  29.     @Override  
  30.     public void onCreate(Bundle savedInstanceState) {  
  31.         super.onCreate(savedInstanceState);  
  32.   
  33.         setContentView(R.layout.activity_auto_run_application);  
  34.         mSelectAutoRunApplication = (Button) findViewById(R.id.button_select_auto_run_application);  
  35.         //获得默认的NfcAdapter对象  
  36.         mNfcAdapter = mNfcAdapter.getDefaultAdapter(this);  
  37.         //创建与当前Activity关联的PendingIntent对象  
  38.         mPendingIntent = PendingIntent.getActivity(this0new Intent(this,  
  39.                 getClass()), 0);  
  40.   
  41.     }  
  42.   
  43.     //当窗口获得焦点时会提升当前窗口处理NFC标签的优先级  
  44.     @Override  
  45.     public void onResume() {  
  46.         super.onResume();  
  47.         //提升当前处理NFC标签的优先级  
  48.         if (mNfcAdapter != null)  
  49.             mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null,  
  50.                     null);  
  51.     }  
  52.   
  53.     //当窗口的launchMode被设为singleTop时调用方法(不再调用onCreat方法)  
  54.     @Override  
  55.     public void onNewIntent(Intent intent) {  
  56.         //必须先选择一个Package  
  57.         if (mPackageName == null)  
  58.             return;  
  59.         //获取表示当前标签的对象  
  60.         Tag detectedTag = intent.getParcelableExtra(mNfcAdapter.EXTRA_TAG);  
  61.         //向标签写入Package  
  62.         writeNFCTag(detectedTag);  
  63.     }  
  64.   
  65.     //当窗口失去焦点后,应恢复Android系统处理NFC标签的默认状态  
  66.     @Override  
  67.     public void onPause() {  
  68.         super.onPause();  
  69.         //恢复处理NFC标签的窗口的默认优先级(禁止当前窗口的优先处理NFC标签)  
  70.         if (mNfcAdapter != null)  
  71.             mNfcAdapter.disableForegroundDispatch(this);  
  72.   
  73.     }  
  74.   
  75.     //"选择已安装的应用程序"按钮的单击事件方法  
  76.     public void onClick_SelectAutoRunApplication(View view) {  
  77.         Intent intent = new Intent(this, InstalledApplicationListActivity.class);  
  78.         //显示“已安装应用程序”窗口  
  79.         startActivityForResult(intent, 0);  
  80.     }  
  81.   
  82.     //向标签写入数据  
  83.     public void writeNFCTag(Tag tag) {  
  84.         //必须要指定一个Tag对象  
  85.         if (tag == null) {  
  86.             Toast.makeText(this"NFC Tag未建立连接", Toast.LENGTH_LONG).show();  
  87.             return;  
  88.         }  
  89.         //创建NdefMessage对象  
  90.         //NdefRecord.creatApplicationRecord方法创建一个封装Package的NdefRecord对象  
  91.         NdefMessage ndefMessage = new NdefMessage(  
  92.                 new NdefRecord[] {NdefRecord  
  93.                         .createApplicationRecord(mPackageName)});  
  94.         //获取NdefMessage对象的尺寸  
  95.         int size = ndefMessage.toByteArray().length;  
  96.   
  97.         try {  
  98.             //获取Ndef对象  
  99.             Ndef ndef = Ndef.get(tag);  
  100.             //处理NDEF格式的数据  
  101.             if (ndef != null) {  
  102.                 //允许对标签进行IO操作,连接  
  103.                 ndef.connect();  
  104.                 //NFC标签不是可写的(只读的)  
  105.                 if (!ndef.isWritable()) {  
  106.                     Toast.makeText(this"NFC Tag是只读的!", Toast.LENGTH_LONG)  
  107.                             .show();  
  108.                     return;  
  109.                 }  
  110.                 //NFC标签的空间不足  
  111.                 if (ndef.getMaxSize() < size) {  
  112.                     Toast.makeText(this"NFC Tag的空间不足!", Toast.LENGTH_LONG)  
  113.                             .show();  
  114.                     return;  
  115.                 }  
  116.                 //向NFC标签写入数据  
  117.                 ndef.writeNdefMessage(ndefMessage);  
  118.                 Toast.makeText(this"已成功写入数据!", Toast.LENGTH_LONG).show();  
  119.             } else {  
  120.                 //创建NdefFormatable对象  
  121.                 NdefFormatable format = NdefFormatable.get(tag);  
  122.                 if (format != null) {  
  123.                     try {  
  124.                         //允许标签IO操作,进行连接  
  125.                         format.connect();  
  126.                         //重新格式化NFC标签,并写入数据  
  127.                         format.format(ndefMessage);  
  128.                         Toast.makeText(this"已成功写入数据!", Toast.LENGTH_LONG)  
  129.                                 .show();  
  130.                     } catch (Exception e) {  
  131.                         Toast.makeText(this"写入NDEF格式数据失败!", Toast.LENGTH_LONG)  
  132.                                 .show();  
  133.   
  134.                     }  
  135.                 } else {  
  136.                     Toast.makeText(this"NFC标签不支持NDEF格式!", Toast.LENGTH_LONG)  
  137.                             .show();  
  138.                 }  
  139.             }  
  140.         } catch (Exception e) {  
  141.             Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();  
  142.         }  
  143.   
  144.     }  
  145.   
  146.     @Override  
  147.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  148.         if (resultCode == 1) {  
  149.             //更新“选择已安装的应用程序”按钮的显示文本(Package name和label)  
  150.             mSelectAutoRunApplication.setText(data.getExtras().getString(  
  151.                     "package_name"));  
  152.             //下面的代码用于提取Package Name  
  153.             String temp = mSelectAutoRunApplication.getText().toString();  
  154.             mPackageName = temp.substring(temp.indexOf("\n") + 1);  
  155.   
  156.         }  
  157.   
  158.     }  
  159.   
  160. }  
InstalledApplicationListActivity:
[java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. package mobile.android.auto.run.application;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import android.app.ListActivity;  
  6. import android.content.Intent;  
  7. import android.content.pm.PackageInfo;  
  8. import android.content.pm.PackageManager;  
  9. import android.os.Bundle;  
  10. import android.view.View;  
  11. import android.widget.AdapterView;  
  12. import android.widget.AdapterView.OnItemClickListener;  
  13. import android.widget.ArrayAdapter;  
  14.   
  15. public class InstalledApplicationListActivity extends ListActivity implements  
  16.         OnItemClickListener {  
  17.     //用于保存已安装应用程序的Package和Label  
  18.     private List<String> mPackages = new ArrayList<String>();  
  19.   
  20.     @Override  
  21.     public void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         //获得PackageManager对象  
  24.         PackageManager packageManager = getPackageManager();  
  25.         //获取系统中已安装的所有应用程序的信息,每一个PackageInfo对象表示一个应用程序  
  26.         List<PackageInfo> packageInfos = packageManager  
  27.                 .getInstalledPackages(PackageManager.GET_ACTIVITIES);  
  28.         //枚举所有的应用程序信息,从中取出Package和应用程序的Label,中间用“\n”分离  
  29.         for (PackageInfo packageInfo : packageInfos) {  
  30.             //LoadLabel方法返回的值就是定义Activity时的android:label属性值  
  31.             mPackages.add(packageInfo.applicationInfo.loadLabel(packageManager)  
  32.                     + "\n" + packageInfo.packageName);  
  33.         }  
  34.         //创建一个用于操作Package集合的ArrayAdapter对象  
  35.         ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,  
  36.                 android.R.layout.simple_list_item_1, android.R.id.text1,  
  37.                 mPackages);  
  38.         //在ListView控件中显示所有的Package和程序名  
  39.         setListAdapter(arrayAdapter);  
  40.         //指定列表项的单击事件方法  
  41.         getListView().setOnItemClickListener(this);  
  42.     }  
  43.   
  44.     @Override  
  45.     public void onItemClick(AdapterView<?> parent, View view, int position,  
  46.             long id) {  
  47.         Intent intent = new Intent();  
  48.         //当单击列表项时,会通过package_name传回Package和Label  
  49.         intent.putExtra("package_name", mPackages.get(position));  
  50.         setResult(1, intent);  
  51.         finish();  
  52.   
  53.     }  
  54.   
  55. }  
清单文件:
[html]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     package="mobile.android.auto.run.application"  
  3.     android:versionCode="1"  
  4.     android:versionName="1.0" >  
  5.   
  6.     <uses-sdk  
  7.         android:minSdkVersion="15"  
  8.         android:targetSdkVersion="15" />  
  9.   
  10.     <uses-permission android:name="android.permission.NFC" />  
  11.   
  12.     <application  
  13.         android:icon="@drawable/ic_launcher"  
  14.         android:label="@string/app_name"  
  15.         android:theme="@style/AppTheme" >  
  16.         <activity  
  17.             android:name=".AutoRunApplicationActivity"  
  18.             android:label="@string/title_activity_auto_run_application"  
  19.             android:launchMode="singleTop"  
  20.             android:screenOrientation="portrait" >  
  21.             <intent-filter>  
  22.                 <action android:name="android.intent.action.MAIN" />  
  23.   
  24.                 <category android:name="android.intent.category.LAUNCHER" />  
  25.             </intent-filter>  
  26.         </activity>  
  27.         <activity  
  28.             android:name=".InstalledApplicationListActivity"  
  29.             android:label="@string/title_activity_installed_application_list"  
  30.             android:screenOrientation="portrait" />  
  31.     </application>  
  32.   
  33. </manifest>  

通过浏览器自动打开一个网站:

[java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
  1. package mobile.android.auto.open.uri;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.PendingIntent;  
  5. import android.content.Intent;  
  6. import android.net.Uri;  
  7. import android.nfc.NdefMessage;  
  8. import android.nfc.NdefRecord;  
  9. import android.nfc.NfcAdapter;  
  10. import android.nfc.Tag;  
  11. import android.nfc.tech.Ndef;  
  12. import android.nfc.tech.NdefFormatable;  
  13. import android.os.Bundle;  
  14. import android.widget.Toast;  
  15.   
  16. public class AutoOpenUriActivity extends Activity {  
  17.     private NfcAdapter    nfcAdapter;  
  18.   
  19.     private PendingIntent pendingIntent;  
  20.   
  21.     @Override  
  22.     public void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.   
  25.         setContentView(R.layout.activity_auto_open_uri);  
  26.         nfcAdapter = NfcAdapter.getDefaultAdapter(this);  
  27.         pendingIntent = PendingIntent.getActivity(this0new Intent(this,  
  28.                 getClass()), 0);  
  29.   
  30.     }  
  31.   
  32.     @Override  
  33.     public void onResume() {  
  34.         super.onResume();  
  35.         if (nfcAdapter != null)  
  36.             nfcAdapter  
  37.                     .enableForegroundDispatch(this, pendingIntent, nullnull);  
  38.     }  
  39.   
  40.     @Override  
  41.     public void onNewIntent(Intent intent) {  
  42.         Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  
  43.         writeNFCTag(detectedTag);  
  44.     }  
  45.   
  46.     @Override  
  47.     public void onPause() {  
  48.         super.onPause();  
  49.         if (nfcAdapter != null)  
  50.             nfcAdapter.disableForegroundDispatch(this);  
  51.   
  52.     }  
  53.   
  54.     public void writeNFCTag(Tag tag) {  
  55.         if (tag == null) {  
  56.             Toast.makeText(this"NFC Tag未建立连接", Toast.LENGTH_LONG).show();  
  57.             return;  
  58.         }  
  59.   
  60.         // NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]  
  61.         // { NdefRecord.createUri("http://blog.csdn.net/nokiaguy")});  
  62.   
  63.         NdefMessage ndefMessage = new NdefMessage(  
  64.                 new NdefRecord[] {NdefRecord.createUri(Uri  
  65.                         .parse("http://www.baidu.com"))});  
  66.   
  67.         int size = ndefMessage.toByteArray().length;  
  68.   
  69.         try {  
  70.   
  71.             Ndef ndef = Ndef.get(tag);  
  72.             if (ndef != null) {  
  73.                 ndef.connect();  
  74.   
  75.                 if (!ndef.isWritable()) {  
  76.                     Toast.makeText(this"NFC Tag是只读的!", Toast.LENGTH_LONG)  
  77.                             .show();  
  78.                     return;  
  79.                 }  
  80.                 if (ndef.getMaxSize() < size) {  
  81.                     Toast.makeText(this"NFC Tag的空间不足!", Toast.LENGTH_LONG)  
  82.                             .show();  
  83.                     return;  
  84.                 }  
  85.   
  86.                 ndef.writeNdefMessage(ndefMessage);  
  87.                 Toast.makeText(this"已成功写入数据!", Toast.LENGTH_LONG).show();  
  88.             } else {  
  89.                 NdefFormatable format = NdefFormatable.get(tag);  
  90.                 if (format != null) {  
  91.                     try {  
  92.                         format.connect();  
  93.                         format.format(ndefMessage);  
  94.                         Toast.makeText(this"已成功写入数据!", Toast.LENGTH_LONG)  
  95.                                 .show();  
  96.                     } catch (Exception e) {  
  97.                         Toast.makeText(this"写入NDEF格式数据失败!", Toast.LENGTH_LONG)  
  98.                                 .show();  
  99.   
  100.                     }  
  101.                 } else {  
  102.                     Toast.makeText(this"NFC标签不支持NDEF格式!", Toast.LENGTH_LONG)  
  103.                             .show();  
  104.                 }  
  105.             }  
  106.         } catch (Exception e) {  
  107.             Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();  
  108.         }  
  109.   
  110.     }  
  111.   
  112. }  



附上官方教程:http://developer.android.com/guide/topics/connectivity/nfc/nfc.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android nfc中Ndef格式的读写 的相关文章

  • 检测正在插入的设备

    我希望能够检测设备是否已插入 我希望能够像查询连接状态一样进行查询 这可能吗 或者我是否需要创建一个监听电池事件的广播接收器 显然是ACTION BATTERY CHANGED http developer android com refe
  • 是否仍然建议使用 AsyncTask 在后台加载 listView 项目?

    背景 我听说有一些在后台加载数据的新解决方案比 AsyncTask 更值得推荐 例如loaders http developer android com reference android content Loader html 问题 As
  • 如何增加 Gradle 守护进程的最大堆大小?

    签署 apk 时 我收到以下消息 To run dex in process the Gradle daemon needs a larger heap It currently has 1024 MB For faster builds
  • 在运行时绘制HSV圆

    我想在我的应用程序中有一个颜色选择器 如下所示 我尝试过逐像素填充位图 尝试使用画布drawArc 方法 这两种方式都不利于性能 有任何想法吗 它可能不完全是它应该的样子 与颜色 饱和度等有关 但是这是一些东西 http i1272 pho
  • Android 测试 java.lang.NoClassDefFoundError 由于 Fest-Android 出现错误

    我目前正在我的项目中实现 Android 版 Fest 但我似乎遇到了依赖问题 如果我在不包含 Fest 库的情况下运行测试 测试将正常运行 一旦我添加了 Fest 库 测试就不再运行 相反 会抛出异常 我的项目使用以下依赖项 compil
  • Android异步服务调用策略

    这是场景 客户端对服务进行远程调用 返回 void 并提供 回调对象 服务在后台线程上执行一些长时间运行的逻辑 然后使用回调对象来触发以太成功或失败 因为这些操作视觉元素 执行 Activity runOnUiThread 块 该场景运行良
  • android新手需要了解“?android:attr/actionBarSize”

    我正在经历拉尔斯 沃格尔的教程 http www vogella com articles AndroidFragments article html在使用 Fragments 时 我遇到了以下代码 android layout margi
  • Android 和 iOS 中的应用程序文件大小差异

    通过使用两个应用程序分发服务 Android 市场和 Apple 应用程序商店 我发现了一个谜团 Apple 应用程序的文件大小通常大于 Android 应用程序 我似乎找不到任何对这些差异的解释 而且这似乎是一个未触及的主题 我尝试过分配
  • Android 上 Java 库中的代码出现 NoClassDefFoundError

    我的用户经常遇到错误 应用程序在启动期间崩溃 当应该加载 MainActivity 时 VM 显然找不到该类 我不明白为什么 该应用程序的架构是 我的免费版和专业版都使用一个通用项目 不知道是否相关 请参阅下面的堆栈跟踪 有什么想法吗 ja
  • 如何将您的终端与 Android 模拟器连接

    我尝试导航到 android 工具文件夹并输入 adb shell 命令 但它似乎不起作用 我的终端似乎只能识别命令的 adb 部分 并给我一条错误消息 我究竟做错了什么 通过键入列出所有连接的设备adb devices 检查是否列出了任何
  • 具有多个字符串的列表视图

    我正在尝试创建一个包含多个字符串的列表视图 现在我有一个可以实现的功能 while i lt 10 GETS DATA FROM WEBPAGE ETC a DATAFROMWEBPAGE1 b DATAFROMWEBPAGE2 c DAT
  • Android/三星 Galaxy S 模拟器

    有没有办法在三星银河模拟器或类似的东西上尝试我的项目 我的项目在 HTC Legend 上运行 但在该设备上崩溃了 我如何在 android eclipse 上设置三星 Galaxy s 我设置了 W800 854 2 2 AVD 但它可以
  • Eclipse Android 模拟器 - 键盘不工作

    我刚刚更新到最新的 SDK 版本 16 使用最新版本的 API 16 创建了新版本的 AVD 并且我的硬件键盘在模拟器上不再工作 甚至我的其他 avd 使用旧版本的 sdk 任何想法如何解决这一问题 您的 AVD 的 键盘支持 硬件属性是否
  • 如何更改蜂窝中儿童偏好屏幕的背景颜色

    过去几天我一直在寻找解决方案 但找不到 我需要更改右窗格的背景颜色 我知道如何更改左父首选项的颜色 我在清单文件中创建了一个新主题
  • 应用程序运行时相对布局中的元素显示不同

    我有一个ListView在片段内创建 并且它有一个搜索过滤器 问题是 XML 布局在 android studio 中显示正常 但在模拟器或手机中运行时 它显示不同 与我对齐时不正确 并且当我单击SearchView它位于选项卡导航下方 谁
  • 安卓独立包

    我有一个很大的 UI 大约 20 25 个屏幕 我应该如何组织我的代码 我应该按功能分成不同的包吗 我是否应该为所有 UI 类创建一个包 然后创建子包进行组织 或者我不应该创建单独的包并组织到文件夹中 任何帮助将不胜感激 当您创建文件夹时
  • 如何根据受保护的 String doInBackground 方法中 AsyncTask 的结果调用 Toast.makeText() ?

    我从 AsyncTask 中的数据库中获取数据 如果它为空 我想吐司一个警告文本 我在 AsyncTask 中尝试过 但我了解到它不是在工作线程中调用的 这是我的 doInBackground 方法 protected String doI
  • 使用Android Camera API,拍摄照片的方向始终未定义

    我使用相机API 拍摄的照片总是旋转90度 我想旋转它 所以首先我想知道图片的方向 这一点我被卡住了 我总是以两种方式得到未定义的方向 这是代码 Override public void onPictureTaken byte data C
  • 不幸的是 Project_Name 已停止

    我有一个简单的应用程序 您可以在文本视图中输入文本并按提交 它会在另一个活动中显示文本 然而 当我按下提交时 给我消息 不幸的是 发送已停止 我查看了SO上的其他线程 但是不幸的是 myfirstproject 在 java 中停止工作错误
  • 在自定义对话框中设置文本视图

    我创建了一个自定义对话框 但无法将文本设置到 java 对话框布局中的文本视图中 并且我的程序崩溃了 我的错误是什么 public class Total CBC extends Activity Override protected vo

随机推荐

  • PyTorch中实现数据集的自定义读取

    一 创作缘由 数据集呈现的方式有很多种 今天和大家仔细谈一谈当我们要读取的数据集信息存储在文本文件时 我们如何读取数据集 最近在实现一个垃圾分类的任务 数据集中每张图片的名称和数据标签都记录在了文本文件中 垃圾分类数据集介绍 一共有6种不同
  • mybatis3 mysql自动生成主键_mybatis自动生成主键

    mysql 使用useGeneratedKey属性 INSERT INTO STUDENTS NAME EMAIL PHONE VALUES name email phone 其他的方式 使用selectKey子标签 属性 order be
  • [优化篇]OpenStack的Cinder后端存储技术——GlusterFS(1)

    题记 上一篇已经介绍了OpenStack的Cinder后端使用NFS存储技术 为什么要使用NFS呢 一般情况下 如果你的网络是千兆网络 在如果你考虑性能的要求 存储设置到宿主机本地硬盘效率会更好 例如我们可以在计算节点上安装cinder v
  • Javascript里有个C:Part 3 - 深入对象

    http cnodejs org topic 4f16442ccae1f4aa270010bd em Javascript里有个C em 系列文章 br ol br li a title 编辑 Javascript里有个C Part hre
  • 利用轨迹拼接分析实时可达区域

    如何快速得知从你的位置开始出发 在当前的交通状况下 5分钟之内能够抵达的空间区域范围 当你掏出手机打车时 出租车调度平台应该通知哪些范围的车主进行接单 前言 本篇介绍的是被国际著名数据库和数据挖掘会议DASFAA 2020 CCF B类 成
  • 基于ssm的高校学生课堂考勤系统的设计与实现

    研究的背景 目的和意义 1 研究背景 信息技术的迅猛发展 已经引起社会的深刻变革 信息时代的到来 迫切要求我们的学校管理进行变革 因此 信息化的考勤系统就在这种情况下变的越来越受欢迎 它给教师带来了更加高效处理考勤的方法 使得教学能够比较顺
  • 第三方软件测试z5x电池,三款手游开黑一天不充电 vivo Z5x续航测试

    随着全面屏手机的全面流行 手机的屏幕尺寸越来越大 屏幕尺寸和性能的提高 让续航问题逐渐成为消费者心中的疙瘩 从之前非智能机的两天一充 三天一充 到如今的一天一充 甚至一天两充 如何保持手机随时有电 成了一个难题 全面屏设计的vivo Z5x
  • link标签的其他作用

    在html中link标签的最常用 主要作用是进行css外部样式的引用 还有其他功能是引入icon 也就是可以用来设置这个网站的图标 另一条平时不太容易接触的功能 就是DNS预解析 属于前端优化的范畴 可以加快网页打开 响应的速度 因为每一次
  • apex您所在的地区目前不提供此物品_apex混合精度加速

    Pytorch 简介 Nvidia提供了一个混合精度工具apex 可以加速pytorch的训练效率 空间和时间上 号称可以这不降低模型性能的情况下 将训练速度提升2 4倍 训练显存开销减少为原来的一半 开源地址如下 https github
  • (一)低功耗设计目的与功耗的类型

    一 低功耗设计的目的 1 便携性设备等需求 电子产品在我们生活中扮演了极其重要的作用 便携性的电子设备便是其中一种 便携性设备需要电池供电 需要消耗电池的能量 在同等电能提供下 低功耗设计的产品就能够工作更长的时间 时间的就是生命 因此低功
  • Java怎样写优秀的代码_写优质Java代码的4个技巧

    咱们平时的编程使命不外乎便是将相同的技能套件应用到不同的项目中去 关于大多数状况来说 这些技能都是能够满意方针的 然而 有的项目或许需求用到一些特别的技能 因而工程师们得深入研究 去寻觅那些最简略但最有用的办法 在前一篇文章中 咱们讨论了必
  • springmvc项目搭建

    第3天 Spring SpringMVC MyBatis集成 学习目标 SSM集成 集成流程理解 集成SpringMVC 集成Spring 集成MyBatis 事务测试 第1章 搭建环境 1 1 整合流程 整合说明 SSM整合可以使用多种方
  • 【论文精读】Hierarchical Text-Conditional Image Generation with CLIP Latents

    Hierarchical Text Conditional Image Generation with CLIP Latents 前言 Abstract 1 Introduction 2 Method 2 1 Decoder 2 2 Pri
  • 怎样将自己的电脑变成一个服务器(本地服务器)

    你想将自己的电脑变成一个服务器吗 或许你还不知道我们自己的电脑也可摇身一变成为服务器 现在我分享一下把我们的电脑变为服务器的方法 工具 原料 电脑 步骤1 打开 修改电脑相关服务功能 1 1 点击 开始 打开 控制面板 2 2 打开 程序
  • 登录工程一:传统 Web 应用中的身份验证技术

    标题中的 传统Web应用 这一说法并没有什么官方定义 只是为了与 现代化Web应用 做比较而自拟的一个概念 所谓 现代化Web应用 指的是那些基于分布式架构思想设计的 面向多个端提供稳定可靠的高可用服务 并且在需要时能够横向扩展的Web应用
  • 华为OD机试 - 比较两个版本号的大小(Java)

    题目描述 输入两个版本号 version1 和 version2 每个版本号由多个子版本号组成 子版本号之间由 隔开 由大小写字母 数字组成 并且至少有一个字符 按从左到右的顺序比较子版本号 比较规则如下 子版本号前面的0不参与比较 比如
  • 使用gSOAP与WebService - 第二部分 开发第一个WebService客户端(C++)

    CurrencyConvertor How use gSOAP and WebServices Part 2 Doing the first WS client Download Demo Project 42 1 KB Download
  • JSON空格转义(php、javascript)

    用input控件 存储json数据时 字符串有空格时报错 解决方法 进行空格转义 js文件 javascript var jsonData JSON stringify data replace s g nbsp var rowData
  • python读取图像并相加_python给图像加上mask,并提取mask区域实例

    python对图像提取mask部分 代码 coding utf 8 import os import cv2 import numpy as np def add mask2image binary images path masks pa
  • android nfc中Ndef格式的读写

    原文地址 检测到标签后在Activity中的处理流程 1 在onCreate 中获取NfcAdapter对象 NfcAdapter nfcAdapter NfcAdapter getDefaultAdapter this 2 在onNewI