1 import java.nio.charset.Charset;
2 import java.util.Locale;
3
4 import android.app.Activity;
5 import android.app.PendingIntent;
6 import android.content.Intent;
7 import android.nfc.NdefMessage;
8 import android.nfc.NdefRecord;
9 import android.nfc.NfcAdapter;
10 import android.nfc.NfcAdapter.CreateNdefMessageCallback;
11 import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
12 import android.nfc.NfcEvent;
13 import android.os.Bundle;
14 import android.os.Parcelable;
15 import android.util.Log;
16 import android.widget.EditText;
17 import android.widget.Toast;
18
19 /**
20 * 两部android手机,进行传入文本信息。
21 * @author dr
22 *
23 */
24 public class AndroidBeamMainActivity extends Activity implements
25 CreateNdefMessageCallback, OnNdefPushCompleteCallback {
26
27 private EditText mBeamText;
28
29 private NfcAdapter mNfcAdapter;
30 private PendingIntent mPendingIntent;
31
32 @Override
33 public void onCreate(Bundle savedInstanceState) {
34 super.onCreate(savedInstanceState);
35
36 setContentView(R.layout.activity_android_beam);
37 mBeamText = (EditText) findViewById(R.id.edittext_beam_text);
38
39 mNfcAdapter = mNfcAdapter.getDefaultAdapter(this);
40 mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
41 getClass()), 0);
42
43 mNfcAdapter.setNdefPushMessageCallback(this, this);
44 mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
45 }
46
47 @Override /** 窗口处理完成 */
48 public void onNdefPushComplete(NfcEvent event) {
49 Log.d("message", "complete");
50 }
51
52 @Override /** 如果另外一台手机,靠近当前这部手机 */
53 public NdefMessage createNdefMessage(NfcEvent event) {
54 String text = mBeamText.getText().toString().trim();
55 if ("".equals(text))
56 text = "默认文本";
57 /*
58 * "com.android.calculator2" 官方原生计算器包。
59 * 当另外一部手机靠近这部手机时,会启动计算器。
60 *
61 * NdefMessage ndefMessage = new NdefMessage( new NdefRecord[] {
62 * NdefRecord .createApplicationRecord("com.android.calculator2") });
63 */
64 NdefMessage ndefMessage = new NdefMessage(
65 new NdefRecord[] { createTextRecord(text) });
66
67 return ndefMessage;
68 }
69
70 @Override
71 public void onResume() {
72 super.onResume();
73 if (mNfcAdapter != null)
74 mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null,
75 null);
76 }
77
78 @Override
79 public void onPause() {
80 super.onPause();
81 if (mNfcAdapter != null)
82 mNfcAdapter.disableForegroundDispatch(this);
83 }
84
85 @Override
86 public void onNewIntent(Intent intent) {
87 // 用于显示接收手机的信息。如果接收手机没有打开,会默认调用系统的黑界面。
88 processIntent(intent);
89 }
90
91 /** 根据文本创建 NdefRecord 这个对象 */
92 public NdefRecord createTextRecord(String text) {
93 byte[] langBytes = Locale.CHINA.getLanguage().getBytes(
94 Charset.forName("US-ASCII"));
95 Charset utfEncoding = Charset.forName("UTF-8");
96 byte[] textBytes = text.getBytes(utfEncoding);
97 int utfBit = 0;
98 char status = (char) (utfBit + langBytes.length);
99 byte[] data = new byte[1 + langBytes.length + textBytes.length];
100 data[0] = (byte) status;
101 System.arraycopy(langBytes, 0, data, 1, langBytes.length);
102 System.arraycopy(textBytes, 0, data, 1 + langBytes.length,
103 textBytes.length);
104 NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
105 NdefRecord.RTD_TEXT, new byte[0], data);
106
107 return record;
108 }
109
110 void processIntent(Intent intent) {
111 Parcelable[] rawMsgs = intent
112 .getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
113
114 NdefMessage msg = (NdefMessage) rawMsgs[0];
115 String text = TextRecord.parse(msg.getRecords()[0]).getText();
116 Toast.makeText(this, text, Toast.LENGTH_LONG).show();
117 }
118 }
1 import java.io.UnsupportedEncodingException;
2 import java.util.Arrays;
3 import android.nfc.NdefRecord;
4
5 public class TextRecord {
6 private final String mText;
7
8 private TextRecord(String text) {
9 mText = text;
10 }
11
12 public String getText() {
13 return mText;
14 }
15
16 // 将纯文本内容从NdefRecord对象中解析出来
17 public static TextRecord parse(NdefRecord record) {
18
19 if (record.getTnf() != NdefRecord.TNF_WELL_KNOWN)
20 return null;
21 if (!Arrays.equals(record.getType(), NdefRecord.RTD_TEXT))
22 return null;
23
24 try {
25 byte[] payload = record.getPayload();
26 /*
27 * payload[0] contains the "Status Byte Encodings" field, per the
28 * NFC Forum "Text Record Type Definition" section 3.2.1.
29 *
30 * bit7 is the Text Encoding Field.
31 *
32 * if (Bit_7 == 0): The text is encoded in UTF-8 if (Bit_7 == 1):
33 * The text is encoded in UTF16
34 *
35 * Bit_6 is reserved for future use and must be set to zero.
36 *
37 * Bits 5 to 0 are the length of the IANA language code.
38 */
39 String textEncoding = ((payload[0] & 0x80) == 0) ? "UTF-8"
40 : "UTF-16";
41 int languageCodeLength = payload[0] & 0x3f;
42 String languageCode = new String(payload, 1, languageCodeLength,
43 "US-ASCII");
44 String text = new String(payload, languageCodeLength + 1,
45 payload.length - languageCodeLength - 1, textEncoding);
46 return new TextRecord(text);
47 } catch (UnsupportedEncodingException e) {
48 // should never happen unless we get a malformed tag.
49 throw new IllegalArgumentException(e);
50 }
51 }
52
53 }
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6
7 <EditText
8 android:id="@+id/edittext_beam_text"
9 android:layout_width="match_parent"
10 android:layout_height="wrap_content"
11 android:hint="请输入要传输的文本"/>
12
13 <TextView
14 android:layout_width="match_parent"
15 android:layout_height="wrap_content"
16 android:layout_marginBottom="5dp"
17 android:text="请将当前设备靠近其他NFC设备,别忘了触摸屏幕哦!"
18 android:textSize="16sp" />
19
20 <ImageView
21 android:layout_width="match_parent"
22 android:layout_height="match_parent"
23 android:layout_margin="10dp"
24 android:src="@drawable/read_nfc_tag" />
25
26 </LinearLayout>