android - AndroidでMifareUltralight NFCタグのページアクセス条件を確認する

原文 android tags nfc mifare lockbits

MifareUltralightタグに一度書き込んだ後、すでに特定のページをロックしています。次回writePage()を呼び出すときは、まずそのページのアクセス条件を確認したいと思います。ページがロックされている場合、writeメソッドを呼び出したくありません。 Androidでこれを実現するにはどうすればよいですか?
答え
特定のページが読み取り専用としてマークされているかどうかを確認するには、ロックビットを読み取って分析する必要があります。

boolean isPageLocked(MifareUltralight tag, int page) {
    if (page < 2) {
        // UID pages
        return true; // pages 0..1 are always read-only
    } else if (page < 3) {
        // static lock bytes page
        final byte[] data = tag.readPages(page);
        final int lockBits = ((data[2] & 0x0ff) << 8) | (data[3] & 0x0ff);
        if ((lockBits & 0x007) == 0x007) {
            return true;
        } else {
            // page is partially writable
            return false;
        }
    } else if (page < 16) {
        // OTP and user data (lockable through lockbits in page 2)
        final byte[] data = tag.readPages(page);
        final int lockBits = ((data[2] & 0x0ff) << 8) | (data[3] & 0x0ff);
        return (lockBits & (1<<page)) != 0;
    } else if (page < 40) {
        // extended user data (lockable through lockbits in page 40)
        // valid for MIFARE Ultralight C and NTAG203 (not applicable for EV1 products!)
        final byte[] data = tag.readPages(40);
        final int lockBits = ((data[0] & 0x0ff) << 8) | (data[1] & 0x0ff);

        final int relPage = (page - 16) / 4;

        if (relPage < 3) {
            return (lockBits & (1<<(relPage+9))) != 0;
        } else {
            return (lockBits & (1<<(relPage+10))) != 0;
        }
    } else {
        return false;  // unknown
    }
}


タグに書き込む前に、このメソッドを使用できます。

int pageNumber = ...
byte[] pageData = ...
if (!isPageLocked(tag, pageNumber)) {
    tag.writePage(pageNumber, pageData);
}


上記の方法(isPageLocked())は、MIFARE UltralightおよびNTAG製品ラインのEV1製品(Ultralight EV1またはNTAG21xなど)では機能しません。拡張ロックバイトのレイアウトが異なるためです。
関連記事

android - リスト経由で共有をカスタマイズするにはどうすればよいですか?Androidスタジオでwhatsappとsmsのみが含まれていますか?

android - 通知を受信するときにsetSmallIcon()を動的に使用しますか?

java - タブ付きアクティビティのフラグメントを右から左に設定する方法

android - 子の高さを拡張するときに親の高さを拡張する

android - AndroidおよびiOSでアプリを開くためのディープリンクを含むメタデータが機能しない

java - Javaコードから追加されたドキュメントがcouchbase liteと同期しない

android - Androidを使用してparse.comで日付データ型の日付を配置するにはどうすればよいですか?

android - クラスandroid.support.design.widget.CollapsingToolbarLayoutの膨張エラー

android - getRecyclerViewはnullオブジェクトを返します

android - ngcordova androidファイルを選択してサーバーにアップロード