简体   繁体   English

如何读取多个 nfc 标签有效负载并将其存储到数组列表中?

[英]How to read multiple nfc tags payload and store into an arraylist?

I still new in coding.我在编码方面还是新手。 Now I have two nfc tags and each tag is storing different coordinate:latitude, longitude and what I want is when the device detect nfc tags it will read the payload and store it into arraylist.现在我有两个 nfc 标签,每个标签存储不同的坐标:纬度、经度,我想要的是当设备检测到 nfc 标签时,它会读取有效负载并将其存储到数组列表中。 Currently, I able to read the first nfc tag and store the payload into arraylist.目前,我能够读取第一个 nfc 标签并将有效负载存储到 arraylist 中。 But the problem I face is that when I read the second nfc tag the previous data in arraylist is overwritten.但我面临的问题是,当我读取第二个 nfc 标签时,arraylist 中的先前数据被覆盖。 How can I achieve both nfc tags payload are able to store into an arraylist?如何实现两个 nfc 标签有效负载都能够存储到数组列表中?

Android Manifest:安卓清单:

<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>

Mainactivity:主要活动:

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;
    }
};

FragmentMessage:片段消息:

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;
}

} }

Because with each NFC card reading you add a newInstance of the Fragment, so you get a new copy of the Arraylist to which you only copy in 1 payload String.因为每个NFC卡读你add一个newInstance的片段,让您得到的ArrayList到你只在1个载荷字符串复制的新副本。

So you have multiple copies of the Fragment which contain each contain a different new Arraylist所以你有多个 Fragment 副本,每个副本都包含一个不同的new Arraylist

I'm not sure why you want a new Fragment each with one latitude, longitude value unless you want to have something like viewpager show the multiple Fragments in a slideshow each with one coordinate on each.我不知道为什么你想要一个新的片段,每个片段都有一个纬度,经度值,除非你想让viewpager之类的东西在幻灯片中显示多个片段,每个片段都有一个坐标。

But there a number of solutions depending on what you are doing, and there is too many to list in detail, but generally the fall in to to categories.但是有许多解决方案取决于您在做什么,并且有太多无法详细列出,但通常属于类别。

  1. Only create one Fragment in the Activity's onCreate and then get your one instance of the Fragment from back from the FragmentManager (eg by using something like findFragmentById ) and then call a method on it that add's the data to the existing Arraylist in this Fragment.只在 Activity 的onCreate创建一个 Fragment,然后从 FragmentManager 后面获取FragmentManager一个实例(例如,使用findFragmentById类的findFragmentById ),然后在其上调用一个方法,将数据添加到此 Fragment 中的现有 Arraylist。

  2. Possibly better solution is to store the data from each NFC card to a structure outside of a Fragment's lifecycle, this can be done as a Arraylist variable in the Activity with Interfaces or in Shared ViewModel or in a Room or SQLite Database.可能更好的解决方案是将来自每个 NFC 卡的数据存储到 Fragment 生命周期之外的结构中,这可以作为带有接口的活动、共享视图模型或 Room 或 SQLite 数据库中的 Arraylist 变量来完成。 Therefore when you add , replace or do any other FragmentTransaction you won't be likely to destroy the existing Arraylist or create a new instance of the Arraylist and multiple Fragments can access the data stored outside themselves.因此,当您addreplace或执行任何其他FragmentTransaction您不太可能破坏现有的 Arraylist 或创建 Arraylist 的新实例,并且多个 Fragment 可以访问存储在自身外部的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM