簡體   English   中英

如何讀取多個 nfc 標簽有效負載並將其存儲到數組列表中?

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

我在編碼方面還是新手。 現在我有兩個 nfc 標簽,每個標簽存儲不同的坐標:緯度、經度,我想要的是當設備檢測到 nfc 標簽時,它會讀取有效負載並將其存儲到數組列表中。 目前,我能夠讀取第一個 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之類的東西在幻燈片中顯示多個片段,每個片段都有一個坐標。

但是有許多解決方案取決於您在做什么,並且有太多無法詳細列出,但通常屬於類別。

  1. 只在 Activity 的onCreate創建一個 Fragment,然后從 FragmentManager 后面獲取FragmentManager一個實例(例如,使用findFragmentById類的findFragmentById ),然后在其上調用一個方法,將數據添加到此 Fragment 中的現有 Arraylist。

  2. 可能更好的解決方案是將來自每個 NFC 卡的數據存儲到 Fragment 生命周期之外的結構中,這可以作為帶有接口的活動、共享視圖模型或 Room 或 SQLite 數據庫中的 Arraylist 變量來完成。 因此,當您addreplace或執行任何其他FragmentTransaction您不太可能破壞現有的 Arraylist 或創建 Arraylist 的新實例,並且多個 Fragment 可以訪問存儲在自身外部的數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM