一名合格的程序员在遇到问题时该怎么办?
- Bing/Google
- CV
- ERROR
- Bing/Google
NFC 前台调度
网络上很多文章都是把getActivity的第四个参数填0的
1 2 3 4 5 6
| pendingIntent = PendingIntent.getActivity( this, 0, Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0 )
|
然而当你真正CV到IDE中…
![]()
此时你肯定会毫不犹豫地点击那个诱人的 Add …
结果就是你在onNewIntent中接收到的intent有**200%**的概率是null
解决方案是填FLAG_MUTABLE而不是它给你推荐的FLAG_IMMUTABLE
Mifare Transceive failed
我们来看这段代码
1 2 3 4
| mfc!!.authenticateSectorWithKeyA(4, key) mfc!!.authenticateSectorWithKeyA(12, key2) val data = mfc!!.readBlock(17) val data2 = mfc!!.readBlock(49)
|
你是不是以为data和data2里都是你想要得到的数据
不,你只会得到java.io.IOException: Transceive failed,怎么样,惊不惊喜意不意外?
Mifare每次超出认证扇区范围的读取都要重新认证
所以你要这样写:
1 2 3 4
| mfc!!.authenticateSectorWithKeyA(4, key) val data = mfc!!.readBlock(17) mfc!!.authenticateSectorWithKeyA(12, key2) val data2 = mfc!!.readBlock(49)
|
才能得到你想要的数据
Mifare 值块操作无效
当你历经千辛万苦,终于要操作值块(Value Block)时
1 2 3
| mfc!!.increment(17, 100)
mfc!!.decrement(17, 100)
|
代码能跑,我重新读取卡片试试
嗯?怎么值块没变?
很显然,咕噜咕噜不会让你这么容易得逞,增减值只是将数据写入了一个临时(相当于缓冲区?)的地方
你还需要调用transfer来真正的写入到卡片中
附录
↓↓↓ 别忘了这个 ↓↓↓
1
| <uses-permission android:name="android.permission.NFC"/>
|
↑↑↑ 别忘了这个 ↑↑↑
前台 NFC 调度示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| class MainActivity : AppCompatActivity() { private var nfcAdapter: NfcAdapter? = null private var pendingIntent: PendingIntent? = null
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ... nfcAdapter = NfcAdapter.getDefaultAdapter(this) if (nfcAdapter != null) { if (!nfcAdapter!!.isEnabled) { Toast.makeText(this, "不打开NFC你让我怎么读取?", Toast.LENGTH_SHORT).show() finish() } } else { Toast.makeText(this, "你的垃圾手机不支持NFC", Toast.LENGTH_SHORT).show() finish() } pendingIntent = PendingIntent.getActivity( this, 0, Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE ) }
@Suppress("deprecation") override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) if (intent.action == NfcAdapter.ACTION_TAG_DISCOVERED) { val tag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { intent.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java) } else { intent.getParcelableExtra(NfcAdapter.EXTRA_TAG) } ... tag.XXX ... } }
override fun onResume() { super.onResume() nfcAdapter?.enableForegroundDispatch(this, this.pendingIntent, null, null) } override fun onPause() { super.onPause() nfcAdapter?.disableForegroundDispatch(this) } }
|