android - 如何读取多个 nfc 标签有效负载并存储到数组列表中?
问题描述
我还是编码新手。现在我有两个 nfc 标签,每个标签都存储不同的坐标:纬度、经度,我想要的是当设备检测到 nfc 标签时,它将读取有效负载并将其存储到 arraylist 中。目前,我能够读取第一个 nfc 标签并将有效负载存储到 arraylist 中。但我面临的问题是,当我读取第二个 nfc 标签时,arraylist 中的先前数据被覆盖。如何实现两个 nfc 标签有效负载都能够存储到数组列表中?
安卓清单:
<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:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="geo" android:host="*" />
</intent-filter>
</activity>
</application>
主要活动:
private NfcAdapter nfcAdapter;
private TextView textView;
PendingIntent mPendingIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);
bottomNav.setOnNavigationItemSelectedListener(navListener);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new FragmentMessage()).commit();
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "nfc not supported", Toast.LENGTH_SHORT).show();
finish();
return;
}
if (!nfcAdapter.isEnabled()) {
startActivity(new Intent("android.settings.NFC_SETTINGS"));
Toast.makeText(this, "nfc not yet open", Toast.LENGTH_SHORT).show();
}
mPendingIntent = PendingIntent.getActivity(this,0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0 );
}
private void readIntent(Intent intent){
Parcelable[] parcelables = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
for(int i=0; i<parcelables.length; i ++){
NdefMessage message =(NdefMessage)parcelables[i];
NdefRecord[] records = message.getRecords();
for(int j=0; j<records.length; j++){
NdefRecord record = records[j];
byte[] original = record.getPayload();
byte[] value = Arrays.copyOfRange(original,0,original.length);
String payload = new String(value);
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, FragmentMessage.newInstance(payload), "FragmentMessage").commit();
}
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
readIntent(intent);
}
@Override
protected void onResume() {
super.onResume();
nfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
}
@Override
protected void onPause() {
super.onPause();
nfcAdapter.disableForegroundDispatch(this);
}
private BottomNavigationView.OnNavigationItemSelectedListener navListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
Fragment selectedFragment = null;
switch (menuItem.getItemId()) {
case R.id.homeFragment:
selectedFragment = new FragmentHome();
break;
case R.id.homeFragment1:
selectedFragment = new FragmentMessage();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, selectedFragment).commit();
return true;
}
};
片段消息:
private String text;
ArrayList<String> list;
public static Fragment newInstance(String tv1) {
FragmentMessage fragment = new FragmentMessage();
Bundle args = new Bundle();
args.putString("TEXT",tv1);
fragment.setArguments(args);
return fragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_message, container, false);
TextView textView = v.findViewById(R.id.text_view_fragment);
list= new ArrayList<>();
if(getArguments() != null){
text = getArguments().getString("TEXT");
if(list != null){
list.add(text);
}
System.out.println(list);
}
return v;
}
}
解决方案
因为每张 NFC 卡都会读取add
一个newInstance
片段,所以你会得到一个新的 Arraylist 副本,你只需要在 1 个有效负载字符串中复制它。
所以你有 Fragment 的多个副本,每个副本都包含一个不同的new
Arraylist
我不确定为什么你想要一个新的片段,每个片段都有一个纬度,经度值,除非你想要viewpager
在幻灯片中显示多个片段,每个片段都有一个坐标。
但是有许多解决方案取决于您在做什么,并且有太多无法详细列出的解决方案,但通常属于分类。
仅在 Activity 中创建一个 Fragment,然后从(例如,通过使用类似的东西)
onCreate
从后面获取 Fragment 的一个实例,然后在其上调用一个方法,将数据添加到此 Fragment 中的现有 Arraylist。FragmentManager
findFragmentById
可能更好的解决方案是将来自每个 NFC 卡的数据存储到 Fragment 生命周期之外的结构中,这可以作为 Arraylist 变量在带有接口的 Activity 或 Shared ViewModel 或 Room 或 SQLite 数据库中完成。因此,当您或执行任何其他操作时
add
,您不太可能破坏现有的 Arraylist 或创建 Arraylist 的新实例,并且多个 Fragment 可以访问存储在自身外部的数据。replace
FragmentTransaction
推荐阅读
- json - Dask 如何使用字典列表打开 json
- kubernetes - minikube 启动失败
- visual-studio-app-center - VS AppCenter - XCUI - 无法分析 MachO 文件错误
- powershell - Powershell比较两个文件夹并显示文件不在两者中都显示文件?
- javascript - React/API/Chart.js:期望一个赋值或函数调用,而是看到一个表达式
- c++ - 类模板参数默认值
- amazon-web-services - 向在 AWS Cognito 控制台中创建的用户添加自定义属性
- r - 基于类似重复出现的条件列创建
- r - 使用 R 匹配数据框中的复杂字符串名称
- linux - newlib:编译器在构建 32 位兼容性时会感到困惑