diff --git a/autonfc/build.properties b/autonfc/build.properties
index 1717c74..b843769 100644
--- a/autonfc/build.properties
+++ b/autonfc/build.properties
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
-#Sat Mar 14 06:09:03 GMT 2026
+#Mon Mar 16 02:31:00 GMT 2026
stageCount=0
libraryProject=
baseVersion=15.11
publishVersion=15.0.0
-buildCount=6
+buildCount=12
baseBetaVersion=15.0.1
diff --git a/autonfc/src/main/AndroidManifest.xml b/autonfc/src/main/AndroidManifest.xml
index 1f3327c..0c93ecd 100644
--- a/autonfc/src/main/AndroidManifest.xml
+++ b/autonfc/src/main/AndroidManifest.xml
@@ -8,6 +8,8 @@
+
+
+
+
+
+
+
+
+
+
-
diff --git a/autonfc/src/main/java/cc/winboll/studio/autonfc/MainActivity.java b/autonfc/src/main/java/cc/winboll/studio/autonfc/MainActivity.java
index 68e9fa2..077489c 100644
--- a/autonfc/src/main/java/cc/winboll/studio/autonfc/MainActivity.java
+++ b/autonfc/src/main/java/cc/winboll/studio/autonfc/MainActivity.java
@@ -1,38 +1,70 @@
package cc.winboll.studio.autonfc;
+import android.content.Intent;
import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
-import cc.winboll.studio.libappbase.LogView;
-import cc.winboll.studio.libappbase.ToastUtils;
-import android.view.View;
-import android.content.Intent;
+import cc.winboll.studio.autonfc.nfc.AutoNFCService;
import cc.winboll.studio.autonfc.nfc.NFCInterfaceActivity;
+import cc.winboll.studio.libappbase.LogActivity;
+import cc.winboll.studio.libappbase.ToastUtils;
public class MainActivity extends AppCompatActivity {
- LogView mLogView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
- Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- mLogView = findViewById(R.id.logview);
-
- ToastUtils.show("onCreate");
+
}
@Override
protected void onResume() {
super.onResume();
- mLogView.start();
}
-
- public void onNFCInterfaceActivity(View view) {
- startActivity(new Intent(this, NFCInterfaceActivity.class));
- }
+
+ // 加载菜单
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main_menu, menu);
+ return true;
+ }
+
+ // 菜单点击
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+
+ if (id == R.id.menu_start_service) {
+ startService(new Intent(this, AutoNFCService.class));
+ ToastUtils.show("NFC服务已启动");
+ return true;
+ }
+
+ if (id == R.id.menu_stop_service) {
+ stopService(new Intent(this, AutoNFCService.class));
+ ToastUtils.show("NFC服务已停止");
+ return true;
+ }
+
+ if (id == R.id.menu_log) {
+ LogActivity.startLogActivity(this);
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ public void onNFCInterfaceActivity(View view) {
+ startActivity(new Intent(this, NFCInterfaceActivity.class));
+ }
}
+
diff --git a/autonfc/src/main/java/cc/winboll/studio/autonfc/models/NfcTermuxCmd.java b/autonfc/src/main/java/cc/winboll/studio/autonfc/models/NfcTermuxCmd.java
new file mode 100644
index 0000000..92ccf8b
--- /dev/null
+++ b/autonfc/src/main/java/cc/winboll/studio/autonfc/models/NfcTermuxCmd.java
@@ -0,0 +1,14 @@
+package cc.winboll.studio.autonfc.models;
+
+/**
+ * @Author 豆包&ZhanGSKen
+ * @Date 2026/03/16 09:38
+ */
+public class NfcTermuxCmd {
+ public String script; // 要执行的预制脚本名(如 auth.sh)
+ public String[] args; // 脚本参数
+ public String workDir; // 工作目录
+ public boolean background; // 是否后台执行
+ public String resultDir; // 结果输出目录(可为 null)
+}
+
diff --git a/autonfc/src/main/java/cc/winboll/studio/autonfc/nfc/AutoNFCBootReceiver.java b/autonfc/src/main/java/cc/winboll/studio/autonfc/nfc/AutoNFCBootReceiver.java
new file mode 100644
index 0000000..3ea86c5
--- /dev/null
+++ b/autonfc/src/main/java/cc/winboll/studio/autonfc/nfc/AutoNFCBootReceiver.java
@@ -0,0 +1,28 @@
+package cc.winboll.studio.autonfc.nfc;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import cc.winboll.studio.libappbase.LogUtils;
+/*
+ * 源码说明与描述:
+ * 开机自启动广播接收器,用于开机自动启动 NFC 监听服务
+ *
+ * 作者:豆包&ZhanGSKen
+ * 创建时间:2026-03-16 16:10:00
+ * 最后编辑时间:2026-03-16 18:20:00
+ */
+public class AutoNFCBootReceiver extends BroadcastReceiver {
+
+ private static final String TAG = "AutoNFCBootReceiver";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+ LogUtils.d(TAG, "开机完成,启动 AutoNFC 监听服务");
+ Intent service = new Intent(context, AutoNFCService.class);
+ context.startService(service);
+ }
+ }
+}
+
diff --git a/autonfc/src/main/java/cc/winboll/studio/autonfc/nfc/AutoNFCService.java b/autonfc/src/main/java/cc/winboll/studio/autonfc/nfc/AutoNFCService.java
new file mode 100644
index 0000000..b84f43c
--- /dev/null
+++ b/autonfc/src/main/java/cc/winboll/studio/autonfc/nfc/AutoNFCService.java
@@ -0,0 +1,162 @@
+package cc.winboll.studio.autonfc.nfc;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.IBinder;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.nfc.tech.Ndef;
+import android.widget.Toast;
+import cc.winboll.studio.autonfc.R;
+import cc.winboll.studio.libappbase.LogUtils;
+import java.nio.charset.Charset;
+
+/*
+ * 源码说明与描述:
+ * NFC 后台监听服务(正规保活版)
+ * 保活方式:前台服务 + START_STICKY + 任务销毁重启 + 开机自启
+ *
+ * 作者:豆包&ZhanGSKen
+ * 创建时间:2026-03-16 16:10:00
+ * 最后编辑时间:2026-03-16 18:20:00
+ */
+
+public class AutoNFCService extends Service {
+
+ public static final String TAG = "AutoNFCService";
+ private static final int NOTIFICATION_ID = 0x1001;
+ private static final String CHANNEL_ID = "AUTO_NFC_SERVICE_CHANNEL";
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ LogUtils.d(TAG, "onCreate");
+ startForeground(NOTIFICATION_ID, buildNotification());
+ }
+
+ private Notification buildNotification() {
+ NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationChannel channel = new NotificationChannel(
+ CHANNEL_ID,
+ "AutoNFC 后台监听",
+ NotificationManager.IMPORTANCE_LOW
+ );
+ channel.setSound(null, null);
+ channel.setVibrationPattern(null);
+ nm.createNotificationChannel(channel);
+ }
+
+ Intent intent = new Intent(this, NFCInterfaceActivity.class);
+ PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ return new Notification.Builder(this)
+ .setChannelId(CHANNEL_ID)
+ .setSmallIcon(R.mipmap.ic_launcher)
+ .setContentTitle("AutoNFC 运行中")
+ .setContentText("NFC 卡片监听已启动")
+ .setContentIntent(pi)
+ .setSound(null)
+ .setVibrate(null)
+ .build();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ LogUtils.d(TAG, "onStartCommand");
+ if (intent != null) {
+ handleNfcIntent(intent);
+ }
+ return START_STICKY;
+ }
+
+ public void handleNfcIntent(Intent intent) {
+ String action = intent.getAction();
+ if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)
+ || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
+ || NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
+
+ LogUtils.d(TAG, "NFC 卡片已靠近");
+ Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
+ parseNdefData(tag);
+ }
+ }
+
+ private void parseNdefData(Tag tag) {
+ if (tag == null) {
+ showToast("标签为空");
+ return;
+ }
+
+ Ndef ndef = Ndef.get(tag);
+ if (ndef == null) {
+ showToast("不支持NDEF格式");
+ return;
+ }
+
+ try {
+ ndef.connect();
+ NdefMessage msg = ndef.getNdefMessage();
+ if (msg == null) {
+ ndef.close();
+ showToast("未读取到NDEF数据");
+ return;
+ }
+
+ NdefRecord[] records = msg.getRecords();
+ if (records != null && records.length > 0) {
+ byte[] payload = records[0].getPayload();
+ if (payload.length > 0) {
+ int langLen = payload[0] & 0x3F;
+ int start = 1 + langLen;
+ if (start < payload.length) {
+ String data = new String(payload, start, payload.length - start, Charset.forName("UTF-8"));
+ LogUtils.d(TAG, "读取数据:" + data);
+ // 只弹出Toast显示内容
+ showToast("NFC数据:" + data);
+ }
+ }
+ }
+ ndef.close();
+ } catch (Exception e) {
+ LogUtils.e(TAG, "解析失败", e);
+ showToast("读取失败:" + e.getMessage());
+ }
+ }
+
+ /**
+ * 弹出Toast
+ */
+ private void showToast(final String msg) {
+ Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void onTaskRemoved(Intent rootIntent) {
+ super.onTaskRemoved(rootIntent);
+ LogUtils.d(TAG, "任务被移除,重启服务");
+ Intent intent = new Intent(getApplicationContext(), AutoNFCService.class);
+ startService(intent);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ LogUtils.d(TAG, "onDestroy");
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+}
+
diff --git a/autonfc/src/main/java/cc/winboll/studio/autonfc/nfc/NFCInterfaceActivity.java b/autonfc/src/main/java/cc/winboll/studio/autonfc/nfc/NFCInterfaceActivity.java
index 274f35b..17a5959 100644
--- a/autonfc/src/main/java/cc/winboll/studio/autonfc/nfc/NFCInterfaceActivity.java
+++ b/autonfc/src/main/java/cc/winboll/studio/autonfc/nfc/NFCInterfaceActivity.java
@@ -1,3 +1,10 @@
+/*
+ - 源码说明与描述:
+ - NFC 调试界面,负责前台分发、UI 交互、写入控制
+ - 作者:豆包&ZhanGSKenzhangsken@qq.com
+ - 创建时间:2026-03-16 10:00:00
+ - 最后编辑时间:2026-03-16 18:59:00
+ */
package cc.winboll.studio.autonfc.nfc;
import android.app.Activity;
@@ -18,266 +25,209 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import cc.winboll.studio.autonfc.R;
+import cc.winboll.studio.libappbase.LogUtils;
import java.nio.charset.Charset;
-/**
- * @Author 豆包&ZhanGSKen
- * @Date 2026/03/14 13:35
- */
public class NFCInterfaceActivity extends Activity {
- private NfcAdapter mNfcAdapter;
- private PendingIntent mPendingIntent;
- private IntentFilter[] mIntentFilters;
- private String[][] mTechLists;
+// ========================= 常量定义 =========================
+ private static final String TAG = "NFCInterfaceActivity";
- private TextView tvStatus;
- private TextView tvData;
- private EditText etWriteContent;
- private Button btnReadNfc;
- private Button btnWriteNfc;
+// ========================= 成员属性 =========================
+ private NfcAdapter mNfcAdapter;
+ private PendingIntent mPendingIntent;
+ private IntentFilter[] mIntentFilters;
+ private String[][] mTechLists;
- private Tag mCurrentTag;
- private boolean mIsWaitForRead = false;
+ private TextView tvStatus;
+ private TextView tvData;
+ private EditText etWriteContent;
+ private Button btnReadNfc;
+ private Button btnWriteNfc;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_nfc_interface);
+ private Tag mCurrentTag;
- tvStatus = findViewById(R.id.tv_nfc_status);
- tvData = findViewById(R.id.tv_nfc_data);
- etWriteContent = findViewById(R.id.et_write_content);
- btnReadNfc = findViewById(R.id.btn_read_nfc);
- btnWriteNfc = findViewById(R.id.btn_write_nfc);
+// ========================= 生命周期 =========================
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ LogUtils.d(TAG, "onCreate() 调用,savedInstanceState: " + (savedInstanceState != null ? "非空" : "空"));
+ setContentView(R.layout.activity_nfc_interface);
- initNFC();
+ tvStatus = (TextView) findViewById(R.id.tv_nfc_status);
+ tvData = (TextView) findViewById(R.id.tv_nfc_data);
+ etWriteContent = (EditText) findViewById(R.id.et_write_content);
+ btnReadNfc = (Button) findViewById(R.id.btn_read_nfc);
+ btnWriteNfc = (Button) findViewById(R.id.btn_write_nfc);
- btnReadNfc.setOnClickListener(new View.OnClickListener() {
+ initNFC();
+ startAutoNFCService();
+
+ btnReadNfc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- startWaitForRead();
+ LogUtils.d(TAG, "btnReadNfc 点击,进入等待读卡模式");
+ updateStatus("等待卡片靠近...");
}
});
- btnWriteNfc.setOnClickListener(new View.OnClickListener() {
+ btnWriteNfc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = etWriteContent.getText().toString().trim();
+ LogUtils.d(TAG, "btnWriteNfc 点击,待写入内容: " + content);
writeNfc(content);
}
});
- }
+ }
- private void initNFC() {
- NfcManager manager = (NfcManager) getSystemService(NFC_SERVICE);
- mNfcAdapter = manager.getDefaultAdapter();
+// ========================= 初始化 =========================
+ private void initNFC() {
+ LogUtils.d(TAG, "initNFC() 开始初始化 NFC 配置");
+ NfcManager manager = (NfcManager) getSystemService(NFC_SERVICE);
+ mNfcAdapter = manager.getDefaultAdapter();
- if (mNfcAdapter == null) {
- updateStatus("设备不支持NFC");
- return;
- }
+ if (mNfcAdapter == null) {
+ LogUtils.e(TAG, "initNFC() 设备不支持 NFC");
+ updateStatus("设备不支持NFC");
+ return;
+ }
- Intent intent = new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
- mPendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
+ Intent intent = new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ mPendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
- IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
- try {
- filter.addDataType("*/*");
- } catch (IntentFilter.MalformedMimeTypeException e) {
- e.printStackTrace();
- }
+ IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
+ try {
+ filter.addDataType("/");
+ } catch (IntentFilter.MalformedMimeTypeException e) {
+ LogUtils.e(TAG, "initNFC() 过滤器异常: " + e.getMessage(), e);
+ }
- mIntentFilters = new IntentFilter[]{filter};
- mTechLists = new String[][]{{Ndef.class.getName()}, {NdefFormatable.class.getName()}};
- updateStatus("NFC初始化完成");
- }
+ mIntentFilters = new IntentFilter[] { filter };
+ mTechLists = new String[][] {
+ { Ndef.class.getName() },
+ { NdefFormatable.class.getName() }
+ };
+ LogUtils.d(TAG, "initNFC() 完成 NFC 前台分发配置");
+ updateStatus("NFC 初始化完成");
+ }
- public void startWaitForRead() {
- mIsWaitForRead = true;
- updateStatus("请靠近NFC卡片进行读取");
- showToast("请靠近卡片");
- }
+ private void startAutoNFCService() {
+ LogUtils.d(TAG, "startAutoNFCService() 启动后台监听服务");
+ Intent service = new Intent(this, AutoNFCService.class);
+ startService(service);
+ }
- @Override
- protected void onResume() {
- super.onResume();
- NfcStateMonitor.startMonitor();
- if (mNfcAdapter != null) {
- mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, mIntentFilters, mTechLists);
- }
- }
+// ========================= 生命周期回调 =========================
+ @Override
+ protected void onResume() {
+ super.onResume();
+ LogUtils.d(TAG, "onResume() 启用前台分发");
+ if (mNfcAdapter != null) {
+ mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, mIntentFilters, mTechLists);
+ }
+ }
- @Override
- protected void onPause() {
- super.onPause();
- NfcStateMonitor.stopMonitor();
- if (mNfcAdapter != null) {
- mNfcAdapter.disableForegroundDispatch(this);
- }
- }
+ @Override
+ protected void onPause() {
+ super.onPause();
+ LogUtils.d(TAG, "onPause() 关闭前台分发");
+ if (mNfcAdapter != null) {
+ mNfcAdapter.disableForegroundDispatch(this);
+ }
+ }
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- String action = intent.getAction();
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ LogUtils.d(TAG, "onNewIntent() 收到 NFC 卡片意图: " + intent.getAction());
+ mCurrentTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)
- || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
- || NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
+ Intent serviceIntent = new Intent(this, AutoNFCService.class);
+ serviceIntent.putExtras(intent);
+ startService(serviceIntent);
- NfcStateMonitor.notifyNfcConnected();
- updateStatus("卡片已靠近");
- mCurrentTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
+ updateStatus("卡片已靠近,数据解析中...");
+ }
- if (mIsWaitForRead) {
- mIsWaitForRead = false;
- readNfcData(intent);
- }
- }
- }
+// ========================= 写入逻辑 =========================
+ public boolean writeNfc(String text) {
+ LogUtils.d(TAG, "writeNfc() 写入文本: " + text);
+ if (mCurrentTag == null) {
+ LogUtils.w(TAG, "writeNfc() 未检测到卡片,无法写入");
+ updateStatus("请先靠近卡片");
+ return false;
+ }
+ if (text.isEmpty()) {
+ LogUtils.w(TAG, "writeNfc() 写入内容为空");
+ updateStatus("输入内容不能为空");
+ return false;
+ }
- public void readNfcData(Intent intent) {
- if (intent == null) {
- NfcStateMonitor.notifyReadFail("Intent为空");
- return;
- }
+ NdefRecord record = createTextRecord(text);
+ NdefMessage msg = new NdefMessage(new NdefRecord[] { record });
- Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- if (tag == null) {
- NfcStateMonitor.notifyReadFail("标签为空");
- return;
- }
-
- Ndef ndef = Ndef.get(tag);
- if (ndef == null) {
- NfcStateMonitor.notifyReadFail("不支持NDEF");
- return;
- }
-
- try {
- ndef.connect();
- NdefMessage msg = ndef.getNdefMessage();
- if (msg == null) {
- NfcStateMonitor.notifyReadFail("空标签");
- ndef.close();
- return;
- }
-
- NdefRecord[] records = msg.getRecords();
- if (records != null && records.length > 0) {
-// byte[] payload = records[0].getPayload();
-// String data = new String(payload, 1, payload.length - 1, Charset.forName("UTF-8"));
-// updateData(data);
-// updateStatus("读取成功");
-// NfcStateMonitor.notifyReadSuccess(data);
- byte[] payload = records[0].getPayload();
- if (payload.length > 0) {
- int langCodeLength = payload[0] & 0x3F; // 标准NDEF Text格式,语言码长度存在第0字节的低6位
- int textStartIndex = 1 + langCodeLength;
- if (textStartIndex < payload.length) {
- String data = new String(payload, textStartIndex, payload.length - textStartIndex, Charset.forName("UTF-8"));
- updateData(data);
- updateStatus("读取成功");
- NfcStateMonitor.notifyReadSuccess(data);
- } else {
- NfcStateMonitor.notifyReadFail("标签数据为空");
- updateStatus("标签数据为空");
- }
- } else {
- NfcStateMonitor.notifyReadFail("标签 payload 为空");
- updateStatus("标签 payload 为空");
+ try {
+ Ndef ndef = Ndef.get(mCurrentTag);
+ if (ndef != null) {
+ ndef.connect();
+ if (ndef.isWritable()) {
+ ndef.writeNdefMessage(msg);
+ ndef.close();
+ LogUtils.i(TAG, "writeNfc() 写入成功");
+ updateStatus("写入成功");
+ updateData(text);
+ NfcStateMonitor.notifyWriteSuccess();
+ return true;
}
-
- }
- ndef.close();
- } catch (Exception e) {
- NfcStateMonitor.notifyReadFail(e.getMessage());
- updateStatus("读取失败:" + e.getMessage());
- }
- }
+ } else {
+ NdefFormatable f = NdefFormatable.get(mCurrentTag);
+ if (f != null) {
+ f.connect();
+ f.format(msg);
+ f.close();
+ LogUtils.i(TAG, "writeNfc() 格式化并写入成功");
+ updateStatus("格式化并写入成功");
+ NfcStateMonitor.notifyWriteSuccess();
+ return true;
+ }
+ }
+ } catch (Exception e) {
+ LogUtils.e(TAG, "writeNfc() 写入异常: " + e.getMessage(), e);
+ updateStatus("写入失败:" + e.getMessage());
+ NfcStateMonitor.notifyWriteFail(e.getMessage());
+ }
+ return false;
+ }
- public boolean writeNfc(String text) {
- if (mCurrentTag == null) {
- NfcStateMonitor.notifyWriteFail("未检测到卡片");
- updateStatus("请先靠近卡片");
- return false;
- }
+// ========================= NDEF 构造 =========================
+ private NdefRecord createTextRecord(String text) {
+ LogUtils.d(TAG, "createTextRecord() 构造 NDEF 文本记录");
+ byte[] langBytes = "en".getBytes(Charset.forName("UTF-8"));
+ byte[] textBytes = text.getBytes(Charset.forName("UTF-8"));
+ byte[] payload = new byte[1 + langBytes.length + textBytes.length];
+ payload[0] = (byte) langBytes.length;
+ System.arraycopy(langBytes, 0, payload, 1, langBytes.length);
+ System.arraycopy(textBytes, 0, payload, 1 + langBytes.length, textBytes.length);
+ return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);
+ }
- if (text.isEmpty()) {
- NfcStateMonitor.notifyWriteFail("输入内容不能为空");
- updateStatus("请输入写入内容");
- return false;
- }
-
- NdefRecord record = createTextRecord(text);
- NdefMessage msg = new NdefMessage(new NdefRecord[]{record});
-
- try {
- Ndef ndef = Ndef.get(mCurrentTag);
- if (ndef != null) {
- ndef.connect();
- if (ndef.isWritable()) {
- ndef.writeNdefMessage(msg);
- ndef.close();
- updateStatus("写入成功");
- updateData(text);
- NfcStateMonitor.notifyWriteSuccess();
- return true;
- }
- } else {
- NdefFormatable formatable = NdefFormatable.get(mCurrentTag);
- if (formatable != null) {
- formatable.connect();
- formatable.format(msg);
- formatable.close();
- updateStatus("格式化并写入成功");
- NfcStateMonitor.notifyWriteSuccess();
- return true;
- }
- }
- } catch (Exception e) {
- NfcStateMonitor.notifyWriteFail(e.getMessage());
- updateStatus("写入失败:" + e.getMessage());
- }
- return false;
- }
-
- private NdefRecord createTextRecord(String text) {
- byte[] langBytes = "en".getBytes(Charset.forName("UTF-8"));
- byte[] textBytes = text.getBytes(Charset.forName("UTF-8"));
- byte[] payload = new byte[1 + langBytes.length + textBytes.length];
- payload[0] = (byte) langBytes.length;
- System.arraycopy(langBytes, 0, payload, 1, langBytes.length);
- System.arraycopy(textBytes, 0, payload, 1 + langBytes.length, textBytes.length);
- return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);
- }
-
- private void updateStatus(final String s) {
- runOnUiThread(new Runnable() {
+// ========================= UI 更新 =========================
+ private void updateStatus(final String s) {
+ runOnUiThread(new Runnable() {
@Override
public void run() {
tvStatus.setText("状态:" + s);
}
});
- }
+ }
- private void updateData(final String s) {
- runOnUiThread(new Runnable() {
+ private void updateData(final String s) {
+ runOnUiThread(new Runnable() {
@Override
public void run() {
- tvData.setText("读取/写入内容:\n" + s);
+ tvData.setText("内容:\n" + s);
}
});
- }
-
- private void showToast(final String s) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(NFCInterfaceActivity.this, s, Toast.LENGTH_SHORT).show();
- }
- });
- }
+ }
}
-
diff --git a/autonfc/src/main/res/layout/activity_main.xml b/autonfc/src/main/res/layout/activity_main.xml
index 772e6e4..a6032d0 100644
--- a/autonfc/src/main/res/layout/activity_main.xml
+++ b/autonfc/src/main/res/layout/activity_main.xml
@@ -34,18 +34,5 @@
-
-
-
-
-
-
diff --git a/autonfc/src/main/res/menu/main_menu.xml b/autonfc/src/main/res/menu/main_menu.xml
new file mode 100644
index 0000000..fb973c9
--- /dev/null
+++ b/autonfc/src/main/res/menu/main_menu.xml
@@ -0,0 +1,12 @@
+
+