Android开发实现NFC刷卡读取的两种方式
<h1 class="title">Android开发实现NFC刷卡读取的两种方式</h1><div class="info"> 更新时间:2021年09月18日 11:54:13 作者:TheFlashArrow </div>
<div class="lbd clearfix"> </div>
<div class="summary">这篇文章主要为大家详细介绍了Android开发中实现NFC刷卡读取的两种方式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下</div>
<div class="lbd clearfix"> </div>
<p><strong>场景:</strong>NFC是目前Android手机一个主流的配置硬件项,本文主要讲解一下Android开发中,NFC刷卡的两种实现方式以及相关方法源码解析。</p>
<p><strong>①:Manifest注册方式:</strong>这种方式主要是在Manifest文件对应的activity下,配置过滤器,以响应不同类型NFC Action。使用这种方式,在刷卡时,如果手机中有多个应用都存在该NFC实现方案,系统会弹出能响应NFC事件的应用列表供用户选择,用户需要点击目标应用来响应本次NFC刷卡事件。目前我公司这边项目中使用了该逻辑,比较简便,这里先贴一下该方式的实现逻辑。</p>
<p>Manifest配置:</p>
<div class="jb51code">
<div>
<div id="highlighter_41437" class="syntaxhighlighterxhtml">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
<div class="line number8 index7 alt1">8</div>
<div class="line number9 index8 alt2">9</div>
<div class="line number10 index9 alt1">10</div>
<div class="line number11 index10 alt2">11</div>
<div class="line number12 index11 alt1">12</div>
<div class="line number13 index12 alt2">13</div>
<div class="line number14 index13 alt1">14</div>
<div class="line number15 index14 alt2">15</div>
<div class="line number16 index15 alt1">16</div>
<div class="line number17 index16 alt2">17</div>
<div class="line number18 index17 alt1">18</div>
<div class="line number19 index18 alt2">19</div>
<div class="line number20 index19 alt1">20</div>
<div class="line number21 index20 alt2">21</div>
<div class="line number22 index21 alt1">22</div>
<div class="line number23 index22 alt2">23</div>
<div class="line number24 index23 alt1">24</div>
<div class="line number25 index24 alt2">25</div>
<div class="line number26 index25 alt1">26</div>
<div class="line number27 index26 alt2">27</div>
<div class="line number28 index27 alt1">28</div>
<div class="line number29 index28 alt2">29</div>
<div class="line number30 index29 alt1">30</div>
<div class="line number31 index30 alt2">31</div>
<div class="line number32 index31 alt1">32</div>
<div class="line number33 index32 alt2">33</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="xhtml comments"><!--权限要加,这是一个普通权限,不需要动态申请,但是在小米手机里需要动态申请--></code></div>
<div class="line number2 index1 alt1"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">uses-permission</code> <code class="xhtml color1">android:name</code><code class="xhtml plain">=</code><code class="xhtml string">"android.permission.NFC"</code> <code class="xhtml plain">/></code></div>
<div class="line number3 index2 alt2"><code class="xhtml spaces"> </code> </div>
<div class="line number4 index3 alt1"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">uses-feature</code></div>
<div class="line number5 index4 alt2"><code class="xhtml spaces"> </code><code class="xhtml color1">android:name</code><code class="xhtml plain">=</code><code class="xhtml string">"android.hardware.nfc"</code></div>
<div class="line number6 index5 alt1"><code class="xhtml spaces"> </code><code class="xhtml color1">android:required</code><code class="xhtml plain">=</code><code class="xhtml string">"false"</code> <code class="xhtml plain">/></code></div>
<div class="line number7 index6 alt2"><code class="xhtml spaces"> </code> </div>
<div class="line number8 index7 alt1"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">application</code><code class="xhtml plain">> </code></div>
<div class="line number9 index8 alt2"><code class="xhtml spaces"> </code><code class="xhtml plain">... </code></div>
<div class="line number10 index9 alt1"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">activity</code></div>
<div class="line number11 index10 alt2"><code class="xhtml spaces"> </code><code class="xhtml color1">android:name</code><code class="xhtml plain">=</code><code class="xhtml string">".NfcActivity"</code></div>
<div class="line number12 index11 alt1"><code class="xhtml spaces"> </code><code class="xhtml color1">android:launchMode</code><code class="xhtml plain">=</code><code class="xhtml string">"singleTask"</code></div>
<div class="line number13 index12 alt2"><code class="xhtml spaces"> </code><code class="xhtml color1">android:screenOrientation</code><code class="xhtml plain">=</code><code class="xhtml string">"portrait"</code></div>
<div class="line number14 index13 alt1"><code class="xhtml spaces"> </code><code class="xhtml color1">android:theme</code><code class="xhtml plain">=</code><code class="xhtml string">"@android:style/Theme.Translucent"</code><code class="xhtml plain">></code></div>
<div class="line number15 index14 alt2"><code class="xhtml spaces"> </code><code class="xhtml comments"><!--透明主题,把刷卡变成一个无感知的过程--></code></div>
<div class="line number16 index15 alt1"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">intent-filter</code><code class="xhtml plain">></code></div>
<div class="line number17 index16 alt2"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">action</code> <code class="xhtml color1">android:name</code><code class="xhtml plain">=</code><code class="xhtml string">"android.nfc.action.NDEF_DISCOVERED"</code> <code class="xhtml plain">/></code></div>
<div class="line number18 index17 alt1"><code class="xhtml spaces"> </code><code class="xhtml plain"></</code><code class="xhtml keyword">intent-filter</code><code class="xhtml plain">></code></div>
<div class="line number19 index18 alt2"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">intent-filter</code><code class="xhtml plain">></code></div>
<div class="line number20 index19 alt1"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">action</code> <code class="xhtml color1">android:name</code><code class="xhtml plain">=</code><code class="xhtml string">"android.nfc.action.TAG_DISCOVERED"</code> <code class="xhtml plain">/></code></div>
<div class="line number21 index20 alt2"><code class="xhtml spaces"> </code> </div>
<div class="line number22 index21 alt1"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">category</code> <code class="xhtml color1">android:name</code><code class="xhtml plain">=</code><code class="xhtml string">"android.intent.category.DEFAULT"</code> <code class="xhtml plain">/></code></div>
<div class="line number23 index22 alt2"><code class="xhtml spaces"> </code><code class="xhtml plain"></</code><code class="xhtml keyword">intent-filter</code><code class="xhtml plain">></code></div>
<div class="line number24 index23 alt1"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">intent-filter</code><code class="xhtml plain">></code></div>
<div class="line number25 index24 alt2"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">action</code> <code class="xhtml color1">android:name</code><code class="xhtml plain">=</code><code class="xhtml string">"android.nfc.action.TECH_DISCOVERED"</code> <code class="xhtml plain">/></code></div>
<div class="line number26 index25 alt1"><code class="xhtml spaces"> </code><code class="xhtml comments"><!--使用这个过滤器 这里其实还要用 meta-data 配置一下标签过滤,--></code></div>
<div class="line number27 index26 alt2"><code class="xhtml spaces"> </code><code class="xhtml comments"><!--我项目中是 NDEF_DISCOVERED 这个TECH_DISCOVERED形同虚设--></code></div>
<div class="line number28 index27 alt1"><code class="xhtml spaces"> </code><code class="xhtml plain"></</code><code class="xhtml keyword">intent-filter</code><code class="xhtml plain">></code></div>
<div class="line number29 index28 alt2"><code class="xhtml spaces"> </code><code class="xhtml plain"><</code><code class="xhtml keyword">meta-data</code></div>
<div class="line number30 index29 alt1"><code class="xhtml spaces"> </code><code class="xhtml color1">android:name</code><code class="xhtml plain">=</code><code class="xhtml string">"android.nfc.action.TECH_DISCOVERED"</code></div>
<div class="line number31 index30 alt2"><code class="xhtml spaces"> </code><code class="xhtml color1">android:resource</code><code class="xhtml plain">=</code><code class="xhtml string">"@xml/nfc_tech"</code> <code class="xhtml plain">/></code></div>
<div class="line number32 index31 alt1"><code class="xhtml spaces"> </code><code class="xhtml plain"></</code><code class="xhtml keyword">activity</code><code class="xhtml plain">></code></div>
<div class="line number33 index32 alt2"><code class="xhtml plain"></</code><code class="xhtml keyword">application</code><code class="xhtml plain">></code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>nfc_tech.xml:这个文件就是TECH_DISCOVERED需要配置的,其中,tech-list之间是逻辑或关系,tech之间是逻辑与关系,与方案②中的techLists原理以及用途是类似的。</p>
<div class="jb51code">
<div>
<div id="highlighter_508348" class="syntaxhighlighterxml">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
<div class="line number8 index7 alt1">8</div>
<div class="line number9 index8 alt2">9</div>
<div class="line number10 index9 alt1">10</div>
<div class="line number11 index10 alt2">11</div>
<div class="line number12 index11 alt1">12</div>
<div class="line number13 index12 alt2">13</div>
<div class="line number14 index13 alt1">14</div>
<div class="line number15 index14 alt2">15</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="xml plain"><?</code><code class="xml keyword">xml</code> <code class="xml color1">version</code><code class="xml plain">=</code><code class="xml string">"1.0"</code> <code class="xml color1">encoding</code><code class="xml plain">=</code><code class="xml string">"utf-8"</code><code class="xml plain">?></code></div>
<div class="line number2 index1 alt1"><code class="xml plain"><</code><code class="xml keyword">resources</code> <code class="xml color1">xmlns:android</code><code class="xml plain">=</code><code class="xml string">"http://schemas.android.com/apk/res/android"</code><code class="xml plain">></code></div>
<div class="line number3 index2 alt2"><code class="xml spaces"> </code> </div>
<div class="line number4 index3 alt1"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">tech-list</code><code class="xml plain">></code></div>
<div class="line number5 index4 alt2"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">tech</code><code class="xml plain">>android.nfc.tech.Ndef</</code><code class="xml keyword">tech</code><code class="xml plain">></code></div>
<div class="line number6 index5 alt1"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">tech</code><code class="xml plain">>android.nfc.tech.NfcA</</code><code class="xml keyword">tech</code><code class="xml plain">></code></div>
<div class="line number7 index6 alt2"><code class="xml spaces"> </code><code class="xml plain"></</code><code class="xml keyword">tech-list</code><code class="xml plain">></code></div>
<div class="line number8 index7 alt1"><code class="xml spaces"> </code> </div>
<div class="line number9 index8 alt2"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">tech-list</code><code class="xml plain">></code></div>
<div class="line number10 index9 alt1"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">tech</code><code class="xml plain">>android.nfc.tech.NfcB</</code><code class="xml keyword">tech</code><code class="xml plain">></code></div>
<div class="line number11 index10 alt2"><code class="xml spaces"> </code><code class="xml plain"></</code><code class="xml keyword">tech-list</code><code class="xml plain">></code></div>
<div class="line number12 index11 alt1"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">tech-list</code><code class="xml plain">></code></div>
<div class="line number13 index12 alt2"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">tech</code><code class="xml plain">>android.nfc.tech.NfcF</</code><code class="xml keyword">tech</code><code class="xml plain">></code></div>
<div class="line number14 index13 alt1"><code class="xml spaces"> </code><code class="xml plain"></</code><code class="xml keyword">tech-list</code><code class="xml plain">></code></div>
<div class="line number15 index14 alt2"><code class="xml plain"></</code><code class="xml keyword">resources</code><code class="xml plain">></code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>NfcActivity:</p>
<div class="jb51code">
<div>
<div id="highlighter_315933" class="syntaxhighlighterjava">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
<div class="line number8 index7 alt1">8</div>
<div class="line number9 index8 alt2">9</div>
<div class="line number10 index9 alt1">10</div>
<div class="line number11 index10 alt2">11</div>
<div class="line number12 index11 alt1">12</div>
<div class="line number13 index12 alt2">13</div>
<div class="line number14 index13 alt1">14</div>
<div class="line number15 index14 alt2">15</div>
<div class="line number16 index15 alt1">16</div>
<div class="line number17 index16 alt2">17</div>
<div class="line number18 index17 alt1">18</div>
<div class="line number19 index18 alt2">19</div>
<div class="line number20 index19 alt1">20</div>
<div class="line number21 index20 alt2">21</div>
<div class="line number22 index21 alt1">22</div>
<div class="line number23 index22 alt2">23</div>
<div class="line number24 index23 alt1">24</div>
<div class="line number25 index24 alt2">25</div>
<div class="line number26 index25 alt1">26</div>
<div class="line number27 index26 alt2">27</div>
<div class="line number28 index27 alt1">28</div>
<div class="line number29 index28 alt2">29</div>
<div class="line number30 index29 alt1">30</div>
<div class="line number31 index30 alt2">31</div>
<div class="line number32 index31 alt1">32</div>
<div class="line number33 index32 alt2">33</div>
<div class="line number34 index33 alt1">34</div>
<div class="line number35 index34 alt2">35</div>
<div class="line number36 index35 alt1">36</div>
<div class="line number37 index36 alt2">37</div>
<div class="line number38 index37 alt1">38</div>
<div class="line number39 index38 alt2">39</div>
<div class="line number40 index39 alt1">40</div>
<div class="line number41 index40 alt2">41</div>
<div class="line number42 index41 alt1">42</div>
<div class="line number43 index42 alt2">43</div>
<div class="line number44 index43 alt1">44</div>
<div class="line number45 index44 alt2">45</div>
<div class="line number46 index45 alt1">46</div>
<div class="line number47 index46 alt2">47</div>
<div class="line number48 index47 alt1">48</div>
<div class="line number49 index48 alt2">49</div>
<div class="line number50 index49 alt1">50</div>
<div class="line number51 index50 alt2">51</div>
<div class="line number52 index51 alt1">52</div>
<div class="line number53 index52 alt2">53</div>
<div class="line number54 index53 alt1">54</div>
<div class="line number55 index54 alt2">55</div>
<div class="line number56 index55 alt1">56</div>
<div class="line number57 index56 alt2">57</div>
<div class="line number58 index57 alt1">58</div>
<div class="line number59 index58 alt2">59</div>
<div class="line number60 index59 alt1">60</div>
<div class="line number61 index60 alt2">61</div>
<div class="line number62 index61 alt1">62</div>
<div class="line number63 index62 alt2">63</div>
<div class="line number64 index63 alt1">64</div>
<div class="line number65 index64 alt2">65</div>
<div class="line number66 index65 alt1">66</div>
<div class="line number67 index66 alt2">67</div>
<div class="line number68 index67 alt1">68</div>
<div class="line number69 index68 alt2">69</div>
<div class="line number70 index69 alt1">70</div>
<div class="line number71 index70 alt2">71</div>
<div class="line number72 index71 alt1">72</div>
<div class="line number73 index72 alt2">73</div>
<div class="line number74 index73 alt1">74</div>
<div class="line number75 index74 alt2">75</div>
<div class="line number76 index75 alt1">76</div>
<div class="line number77 index76 alt2">77</div>
<div class="line number78 index77 alt1">78</div>
<div class="line number79 index78 alt2">79</div>
<div class="line number80 index79 alt1">80</div>
<div class="line number81 index80 alt2">81</div>
<div class="line number82 index81 alt1">82</div>
<div class="line number83 index82 alt2">83</div>
<div class="line number84 index83 alt1">84</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="java keyword">public</code> <code class="java keyword">class</code> <code class="java plain">NfcActivity </code><code class="java keyword">extends</code> <code class="java plain">Activity {</code></div>
<div class="line number2 index1 alt1"><code class="java spaces"> </code> </div>
<div class="line number3 index2 alt2"><code class="java spaces"> </code><code class="java color1">@Override</code></div>
<div class="line number4 index3 alt1"><code class="java spaces"> </code><code class="java keyword">protected</code> <code class="java keyword">void</code> <code class="java plain">onCreate(</code><code class="java color1">@Nullable</code> <code class="java plain">Bundle savedInstanceState) {</code></div>
<div class="line number5 index4 alt2"><code class="java spaces"> </code><code class="java keyword">super</code><code class="java plain">.onCreate(savedInstanceState);</code></div>
<div class="line number6 index5 alt1"><code class="java spaces"> </code><code class="java plain">setContentView(R.layout.activity_nfc);</code></div>
<div class="line number7 index6 alt2"><code class="java spaces"> </code><code class="java plain">initData();</code></div>
<div class="line number8 index7 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number9 index8 alt2"><code class="java spaces"> </code> </div>
<div class="line number10 index9 alt1"><code class="java spaces"> </code><code class="java preprocessor">/**</code></div>
<div class="line number11 index10 alt2"><code class="java spaces"> </code><code class="java preprocessor">* 初始化数据</code></div>
<div class="line number12 index11 alt1"><code class="java spaces"> </code><code class="java preprocessor">*/</code></div>
<div class="line number13 index12 alt2"><code class="java spaces"> </code><code class="java keyword">private</code> <code class="java keyword">void</code> <code class="java plain">initData() {</code></div>
<div class="line number14 index13 alt1"><code class="java spaces"> </code><code class="java plain">NfcAdapter adapter = NfcAdapter.getDefaultAdapter(</code><code class="java keyword">this</code><code class="java plain">);</code></div>
<div class="line number15 index14 alt2"><code class="java spaces"> </code><code class="java keyword">if</code> <code class="java plain">(</code><code class="java keyword">null</code> <code class="java plain">== adapter) {</code></div>
<div class="line number16 index15 alt1"><code class="java spaces"> </code><code class="java plain">Toast.makeText(</code><code class="java keyword">this</code><code class="java plain">, </code><code class="java string">"不支持NFC功能"</code><code class="java plain">, Toast.LENGTH_SHORT).show();</code></div>
<div class="line number17 index16 alt2"><code class="java spaces"> </code><code class="java plain">} </code><code class="java keyword">else</code> <code class="java keyword">if</code> <code class="java plain">(!adapter.isEnabled()) {</code></div>
<div class="line number18 index17 alt1"><code class="java spaces"> </code><code class="java plain">Intent intent = </code><code class="java keyword">new</code> <code class="java plain">Intent(Settings.ACTION_NFC_SETTINGS);</code></div>
<div class="line number19 index18 alt2"><code class="java spaces"> </code><code class="java comments">// 根据包名打开对应的设置界面</code></div>
<div class="line number20 index19 alt1"><code class="java spaces"> </code><code class="java plain">startActivity(intent);</code></div>
<div class="line number21 index20 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number22 index21 alt1"><code class="java spaces"> </code> </div>
<div class="line number23 index22 alt2"><code class="java spaces"> </code><code class="java comments">//我项目中是拿了NFC卡的tag中的id数据,这根据具体情况来;</code></div>
<div class="line number24 index23 alt1"><code class="java spaces"> </code><code class="java comments">// 可以在NfcAdapter源码中查看,具体能拿到哪些数据</code></div>
<div class="line number25 index24 alt2"><code class="java spaces"> </code><code class="java plain">Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);</code></div>
<div class="line number26 index25 alt1"><code class="java spaces"> </code><code class="java plain">String id = bytesToHex(tag.getId());</code></div>
<div class="line number27 index26 alt2"><code class="java spaces"> </code> </div>
<div class="line number28 index27 alt1"><code class="java spaces"> </code><code class="java comments">//TODO 目前我这边项目中,拿到数据后,通过EventBus分发到对应的activity,当然也能使用其他分发响应方式,</code></div>
<div class="line number29 index28 alt2"><code class="java spaces"> </code> </div>
<div class="line number30 index29 alt1"><code class="java spaces"> </code><code class="java comments">//关闭动画,毕竟对用户来说,刷卡应当是一个无感知的过程</code></div>
<div class="line number31 index30 alt2"><code class="java spaces"> </code><code class="java plain">overridePendingTransition(</code><code class="java value">0</code><code class="java plain">, </code><code class="java value">0</code><code class="java plain">);</code></div>
<div class="line number32 index31 alt1"><code class="java spaces"> </code><code class="java plain">finish();</code></div>
<div class="line number33 index32 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number34 index33 alt1"><code class="java spaces"> </code> </div>
<div class="line number35 index34 alt2"><code class="java spaces"> </code><code class="java color1">@Override</code></div>
<div class="line number36 index35 alt1"><code class="java spaces"> </code><code class="java keyword">protected</code> <code class="java keyword">void</code> <code class="java plain">onNewIntent(Intent intent) {</code></div>
<div class="line number37 index36 alt2"><code class="java spaces"> </code><code class="java keyword">super</code><code class="java plain">.onNewIntent(intent);</code></div>
<div class="line number38 index37 alt1"><code class="java spaces"> </code><code class="java plain">initData();</code></div>
<div class="line number39 index38 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number40 index39 alt1"><code class="java spaces"> </code> </div>
<div class="line number41 index40 alt2"><code class="java spaces"> </code><code class="java preprocessor">/**</code></div>
<div class="line number42 index41 alt1"><code class="java spaces"> </code><code class="java preprocessor">* 2转10</code></div>
<div class="line number43 index42 alt2"><code class="java spaces"> </code><code class="java preprocessor">* @param src</code></div>
<div class="line number44 index43 alt1"><code class="java spaces"> </code><code class="java preprocessor">* @return</code></div>
<div class="line number45 index44 alt2"><code class="java spaces"> </code><code class="java preprocessor">*/</code></div>
<div class="line number46 index45 alt1"><code class="java spaces"> </code><code class="java keyword">private</code> <code class="java keyword">static</code> <code class="java plain">String bytesToTenNum(</code><code class="java keyword">byte</code><code class="java plain">[] src) {</code></div>
<div class="line number47 index46 alt2"><code class="java spaces"> </code><code class="java plain">StringBuilder stringBuilder = </code><code class="java keyword">new</code> <code class="java plain">StringBuilder();</code></div>
<div class="line number48 index47 alt1"><code class="java spaces"> </code><code class="java keyword">if</code> <code class="java plain">(src == </code><code class="java keyword">null</code> <code class="java plain">|| src.length <= </code><code class="java value">0</code><code class="java plain">) {</code></div>
<div class="line number49 index48 alt2"><code class="java spaces"> </code><code class="java keyword">return</code> <code class="java keyword">null</code><code class="java plain">;</code></div>
<div class="line number50 index49 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number51 index50 alt2"><code class="java spaces"> </code><code class="java keyword">char</code><code class="java plain">[] buffer = </code><code class="java keyword">new</code> <code class="java keyword">char</code><code class="java plain">[</code><code class="java value">2</code><code class="java plain">];</code></div>
<div class="line number52 index51 alt1"><code class="java spaces"> </code><code class="java keyword">for</code> <code class="java plain">(</code><code class="java keyword">int</code> <code class="java plain">i = </code><code class="java value">0</code><code class="java plain">; i < src.length; i++) {</code></div>
<div class="line number53 index52 alt2"><code class="java spaces"> </code><code class="java plain">buffer[</code><code class="java value">1</code><code class="java plain">] = Character.toUpperCase(Character.forDigit(</code></div>
<div class="line number54 index53 alt1"><code class="java spaces"> </code><code class="java plain">(src >>> </code><code class="java value">4</code><code class="java plain">) & </code><code class="java value">0x0F</code><code class="java plain">, </code><code class="java value">16</code><code class="java plain">));</code></div>
<div class="line number55 index54 alt2"><code class="java spaces"> </code><code class="java plain">buffer[</code><code class="java value">0</code><code class="java plain">] = Character.toUpperCase(Character.forDigit(src & </code><code class="java value">0x0F</code><code class="java plain">,</code></div>
<div class="line number56 index55 alt1"><code class="java spaces"> </code><code class="java value">16</code><code class="java plain">));</code></div>
<div class="line number57 index56 alt2"><code class="java spaces"> </code><code class="java plain">stringBuilder.append(buffer);</code></div>
<div class="line number58 index57 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number59 index58 alt2"><code class="java spaces"> </code><code class="java plain">stringBuilder.reverse();</code></div>
<div class="line number60 index59 alt1"><code class="java spaces"> </code><code class="java plain">BigInteger bigi = </code><code class="java keyword">new</code> <code class="java plain">BigInteger(stringBuilder.toString(), </code><code class="java value">16</code><code class="java plain">);</code></div>
<div class="line number61 index60 alt2"><code class="java spaces"> </code><code class="java keyword">return</code> <code class="java plain">bigi.toString();</code></div>
<div class="line number62 index61 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number63 index62 alt2"><code class="java spaces"> </code> </div>
<div class="line number64 index63 alt1"><code class="java spaces"> </code><code class="java preprocessor">/**</code></div>
<div class="line number65 index64 alt2"><code class="java spaces"> </code><code class="java preprocessor">* 2转16</code></div>
<div class="line number66 index65 alt1"><code class="java spaces"> </code><code class="java preprocessor">* @param src</code></div>
<div class="line number67 index66 alt2"><code class="java spaces"> </code><code class="java preprocessor">* @return</code></div>
<div class="line number68 index67 alt1"><code class="java spaces"> </code><code class="java preprocessor">*/</code></div>
<div class="line number69 index68 alt2"><code class="java spaces"> </code><code class="java keyword">private</code> <code class="java keyword">static</code> <code class="java plain">String bytesToHex(</code><code class="java keyword">byte</code><code class="java plain">[] src){</code></div>
<div class="line number70 index69 alt1"><code class="java spaces"> </code><code class="java plain">StringBuffer sb = </code><code class="java keyword">new</code> <code class="java plain">StringBuffer();</code></div>
<div class="line number71 index70 alt2"><code class="java spaces"> </code><code class="java keyword">if</code> <code class="java plain">(src == </code><code class="java keyword">null</code> <code class="java plain">|| src.length <= </code><code class="java value">0</code><code class="java plain">) {</code></div>
<div class="line number72 index71 alt1"><code class="java spaces"> </code><code class="java keyword">return</code> <code class="java keyword">null</code><code class="java plain">;</code></div>
<div class="line number73 index72 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number74 index73 alt1"><code class="java spaces"> </code><code class="java plain">String sTemp;</code></div>
<div class="line number75 index74 alt2"><code class="java spaces"> </code><code class="java keyword">for</code> <code class="java plain">(</code><code class="java keyword">int</code> <code class="java plain">i = </code><code class="java value">0</code><code class="java plain">; i < src.length; i++) {</code></div>
<div class="line number76 index75 alt1"><code class="java spaces"> </code><code class="java plain">sTemp = Integer.toHexString(</code><code class="java value">0xFF</code> <code class="java plain">& src);</code></div>
<div class="line number77 index76 alt2"><code class="java spaces"> </code><code class="java keyword">if</code> <code class="java plain">(sTemp.length() < </code><code class="java value">2</code><code class="java plain">){</code></div>
<div class="line number78 index77 alt1"><code class="java spaces"> </code><code class="java plain">sb.append(</code><code class="java value">0</code><code class="java plain">);</code></div>
<div class="line number79 index78 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number80 index79 alt1"><code class="java spaces"> </code><code class="java plain">sb.append(sTemp.toUpperCase());</code></div>
<div class="line number81 index80 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number82 index81 alt1"><code class="java spaces"> </code><code class="java keyword">return</code> <code class="java plain">sb.toString();</code></div>
<div class="line number83 index82 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number84 index83 alt1"><code class="java plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p><strong>②:前台响应机制:</strong>这种方式与第一种的区别如下:方法一中,NFC事件由系统分发,需要选择应用去响应事件;而方法二,直接使用前台activity来捕获NFC事件进行响应,并且优先级高于方案一。</p>
<p>下面对该方案进行解析,直接怼上代码。这里我新建了一个NfcTestActivity进行测试,布局文件就补贴了,随便丢一个就行。</p>
<p>NfcTestActivity:</p>
<div class="jb51code">
<div>
<div id="highlighter_976542" class="syntaxhighlighterjava">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
<div class="line number8 index7 alt1">8</div>
<div class="line number9 index8 alt2">9</div>
<div class="line number10 index9 alt1">10</div>
<div class="line number11 index10 alt2">11</div>
<div class="line number12 index11 alt1">12</div>
<div class="line number13 index12 alt2">13</div>
<div class="line number14 index13 alt1">14</div>
<div class="line number15 index14 alt2">15</div>
<div class="line number16 index15 alt1">16</div>
<div class="line number17 index16 alt2">17</div>
<div class="line number18 index17 alt1">18</div>
<div class="line number19 index18 alt2">19</div>
<div class="line number20 index19 alt1">20</div>
<div class="line number21 index20 alt2">21</div>
<div class="line number22 index21 alt1">22</div>
<div class="line number23 index22 alt2">23</div>
<div class="line number24 index23 alt1">24</div>
<div class="line number25 index24 alt2">25</div>
<div class="line number26 index25 alt1">26</div>
<div class="line number27 index26 alt2">27</div>
<div class="line number28 index27 alt1">28</div>
<div class="line number29 index28 alt2">29</div>
<div class="line number30 index29 alt1">30</div>
<div class="line number31 index30 alt2">31</div>
<div class="line number32 index31 alt1">32</div>
<div class="line number33 index32 alt2">33</div>
<div class="line number34 index33 alt1">34</div>
<div class="line number35 index34 alt2">35</div>
<div class="line number36 index35 alt1">36</div>
<div class="line number37 index36 alt2">37</div>
<div class="line number38 index37 alt1">38</div>
<div class="line number39 index38 alt2">39</div>
<div class="line number40 index39 alt1">40</div>
<div class="line number41 index40 alt2">41</div>
<div class="line number42 index41 alt1">42</div>
<div class="line number43 index42 alt2">43</div>
<div class="line number44 index43 alt1">44</div>
<div class="line number45 index44 alt2">45</div>
<div class="line number46 index45 alt1">46</div>
<div class="line number47 index46 alt2">47</div>
<div class="line number48 index47 alt1">48</div>
<div class="line number49 index48 alt2">49</div>
<div class="line number50 index49 alt1">50</div>
<div class="line number51 index50 alt2">51</div>
<div class="line number52 index51 alt1">52</div>
<div class="line number53 index52 alt2">53</div>
<div class="line number54 index53 alt1">54</div>
<div class="line number55 index54 alt2">55</div>
<div class="line number56 index55 alt1">56</div>
<div class="line number57 index56 alt2">57</div>
<div class="line number58 index57 alt1">58</div>
<div class="line number59 index58 alt2">59</div>
<div class="line number60 index59 alt1">60</div>
<div class="line number61 index60 alt2">61</div>
<div class="line number62 index61 alt1">62</div>
<div class="line number63 index62 alt2">63</div>
<div class="line number64 index63 alt1">64</div>
<div class="line number65 index64 alt2">65</div>
<div class="line number66 index65 alt1">66</div>
<div class="line number67 index66 alt2">67</div>
<div class="line number68 index67 alt1">68</div>
<div class="line number69 index68 alt2">69</div>
<div class="line number70 index69 alt1">70</div>
<div class="line number71 index70 alt2">71</div>
<div class="line number72 index71 alt1">72</div>
<div class="line number73 index72 alt2">73</div>
<div class="line number74 index73 alt1">74</div>
<div class="line number75 index74 alt2">75</div>
<div class="line number76 index75 alt1">76</div>
<div class="line number77 index76 alt2">77</div>
<div class="line number78 index77 alt1">78</div>
<div class="line number79 index78 alt2">79</div>
<div class="line number80 index79 alt1">80</div>
<div class="line number81 index80 alt2">81</div>
<div class="line number82 index81 alt1">82</div>
<div class="line number83 index82 alt2">83</div>
<div class="line number84 index83 alt1">84</div>
<div class="line number85 index84 alt2">85</div>
<div class="line number86 index85 alt1">86</div>
<div class="line number87 index86 alt2">87</div>
<div class="line number88 index87 alt1">88</div>
<div class="line number89 index88 alt2">89</div>
<div class="line number90 index89 alt1">90</div>
<div class="line number91 index90 alt2">91</div>
<div class="line number92 index91 alt1">92</div>
<div class="line number93 index92 alt2">93</div>
<div class="line number94 index93 alt1">94</div>
<div class="line number95 index94 alt2">95</div>
<div class="line number96 index95 alt1">96</div>
<div class="line number97 index96 alt2">97</div>
<div class="line number98 index97 alt1">98</div>
<div class="line number99 index98 alt2">99</div>
<div class="line number100 index99 alt1">100</div>
<div class="line number101 index100 alt2">101</div>
<div class="line number102 index101 alt1">102</div>
<div class="line number103 index102 alt2">103</div>
<div class="line number104 index103 alt1">104</div>
<div class="line number105 index104 alt2">105</div>
<div class="line number106 index105 alt1">106</div>
<div class="line number107 index106 alt2">107</div>
<div class="line number108 index107 alt1">108</div>
<div class="line number109 index108 alt2">109</div>
<div class="line number110 index109 alt1">110</div>
<div class="line number111 index110 alt2">111</div>
<div class="line number112 index111 alt1">112</div>
<div class="line number113 index112 alt2">113</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="java preprocessor">/**</code></div>
<div class="line number2 index1 alt1"><code class="java spaces"> </code><code class="java preprocessor">* @author Flash</code></div>
<div class="line number3 index2 alt2"><code class="java spaces"> </code><code class="java preprocessor">* 创建时间:2021-07-30 11:14</code></div>
<div class="line number4 index3 alt1"><code class="java spaces"> </code><code class="java preprocessor">*/</code></div>
<div class="line number5 index4 alt2"><code class="java keyword">public</code> <code class="java keyword">class</code> <code class="java plain">NfcTestActivity </code><code class="java keyword">extends</code> <code class="java plain">AppCompatActivity {</code></div>
<div class="line number6 index5 alt1"><code class="java spaces"> </code> </div>
<div class="line number7 index6 alt2"><code class="java spaces"> </code><code class="java plain">NfcAdapter mNfcAdapter;</code></div>
<div class="line number8 index7 alt1"><code class="java spaces"> </code><code class="java plain">PendingIntent pIntent;</code></div>
<div class="line number9 index8 alt2"><code class="java spaces"> </code> </div>
<div class="line number10 index9 alt1"><code class="java spaces"> </code><code class="java color1">@Override</code></div>
<div class="line number11 index10 alt2"><code class="java spaces"> </code><code class="java keyword">protected</code> <code class="java keyword">void</code> <code class="java plain">onCreate(Bundle savedInstanceState) {</code></div>
<div class="line number12 index11 alt1"><code class="java spaces"> </code><code class="java keyword">super</code><code class="java plain">.onCreate(savedInstanceState);</code></div>
<div class="line number13 index12 alt2"><code class="java spaces"> </code><code class="java plain">setContentView(R.layout.activity_nfc_test);</code></div>
<div class="line number14 index13 alt1"><code class="java spaces"> </code><code class="java plain">initNfc();</code></div>
<div class="line number15 index14 alt2"><code class="java spaces"> </code><code class="java plain">Log.i(</code><code class="java string">"FlashTestNFC"</code><code class="java plain">, </code><code class="java string">"onCreate"</code><code class="java plain">);</code></div>
<div class="line number16 index15 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number17 index16 alt2"><code class="java spaces"> </code> </div>
<div class="line number18 index17 alt1"><code class="java spaces"> </code><code class="java color1">@Override</code></div>
<div class="line number19 index18 alt2"><code class="java spaces"> </code><code class="java keyword">protected</code> <code class="java keyword">void</code> <code class="java plain">onStop() {</code></div>
<div class="line number20 index19 alt1"><code class="java spaces"> </code><code class="java keyword">super</code><code class="java plain">.onStop();</code></div>
<div class="line number21 index20 alt2"><code class="java spaces"> </code><code class="java plain">Log.i(</code><code class="java string">"FlashTestNFC"</code><code class="java plain">, </code><code class="java string">"onStop"</code><code class="java plain">);</code></div>
<div class="line number22 index21 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number23 index22 alt2"><code class="java spaces"> </code> </div>
<div class="line number24 index23 alt1"><code class="java spaces"> </code><code class="java color1">@Override</code></div>
<div class="line number25 index24 alt2"><code class="java spaces"> </code><code class="java keyword">protected</code> <code class="java keyword">void</code> <code class="java plain">onDestroy() {</code></div>
<div class="line number26 index25 alt1"><code class="java spaces"> </code><code class="java keyword">super</code><code class="java plain">.onDestroy();</code></div>
<div class="line number27 index26 alt2"><code class="java spaces"> </code><code class="java plain">Log.i(</code><code class="java string">"FlashTestNFC"</code><code class="java plain">, </code><code class="java string">"onDestroy"</code><code class="java plain">);</code></div>
<div class="line number28 index27 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number29 index28 alt2"><code class="java spaces"> </code> </div>
<div class="line number30 index29 alt1"><code class="java spaces"> </code><code class="java preprocessor">/**</code></div>
<div class="line number31 index30 alt2"><code class="java spaces"> </code><code class="java preprocessor">* 初始化</code></div>
<div class="line number32 index31 alt1"><code class="java spaces"> </code><code class="java preprocessor">*/</code></div>
<div class="line number33 index32 alt2"><code class="java spaces"> </code><code class="java keyword">private</code> <code class="java keyword">void</code> <code class="java plain">initNfc(){</code></div>
<div class="line number34 index33 alt1"><code class="java spaces"> </code><code class="java plain">mNfcAdapter = NfcAdapter.getDefaultAdapter(</code><code class="java keyword">this</code><code class="java plain">);</code></div>
<div class="line number35 index34 alt2"><code class="java spaces"> </code><code class="java plain">pIntent = PendingIntent.getActivity(</code><code class="java keyword">this</code><code class="java plain">, </code><code class="java value">0</code><code class="java plain">,</code></div>
<div class="line number36 index35 alt1"><code class="java spaces"> </code><code class="java comments">//在Manifest里或者这里设置当前activity启动模式,否则每次向阳NFC事件,activity会重复创建</code></div>
<div class="line number37 index36 alt2"><code class="java spaces"> </code><code class="java comments">// 当然也要按照具体情况来,你设置成singleTask也不是不行,</code></div>
<div class="line number38 index37 alt1"><code class="java spaces"> </code><code class="java keyword">new</code> <code class="java plain">Intent(</code><code class="java keyword">this</code><code class="java plain">, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),</code></div>
<div class="line number39 index38 alt2"><code class="java spaces"> </code><code class="java value">0</code><code class="java plain">);</code></div>
<div class="line number40 index39 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number41 index40 alt2"><code class="java spaces"> </code> </div>
<div class="line number42 index41 alt1"><code class="java spaces"> </code><code class="java color1">@Override</code></div>
<div class="line number43 index42 alt2"><code class="java spaces"> </code><code class="java keyword">protected</code> <code class="java keyword">void</code> <code class="java plain">onNewIntent(Intent intent) {</code></div>
<div class="line number44 index43 alt1"><code class="java spaces"> </code><code class="java keyword">super</code><code class="java plain">.onNewIntent(intent);</code></div>
<div class="line number45 index44 alt2"><code class="java spaces"> </code><code class="java comments">//这里必须setIntent,set NFC事件响应后的intent才能拿到数据</code></div>
<div class="line number46 index45 alt1"><code class="java spaces"> </code><code class="java plain">setIntent(intent);</code></div>
<div class="line number47 index46 alt2"><code class="java spaces"> </code><code class="java plain">Log.i(</code><code class="java string">"FlashTestNFC"</code><code class="java plain">, </code><code class="java string">"onNewIntent"</code><code class="java plain">);</code></div>
<div class="line number48 index47 alt1"><code class="java spaces"> </code><code class="java plain">Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);</code></div>
<div class="line number49 index48 alt2"><code class="java spaces"> </code> </div>
<div class="line number50 index49 alt1"><code class="java spaces"> </code><code class="java comments">//TODO 获取数据进行下一步处理</code></div>
<div class="line number51 index50 alt2"><code class="java spaces"> </code> </div>
<div class="line number52 index51 alt1"><code class="java spaces"> </code><code class="java plain">Log.i(</code><code class="java string">"FlashTestNFC--Tag"</code><code class="java plain">, bytesToHex(tag.getId()));</code></div>
<div class="line number53 index52 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number54 index53 alt1"><code class="java spaces"> </code> </div>
<div class="line number55 index54 alt2"><code class="java spaces"> </code><code class="java color1">@Override</code></div>
<div class="line number56 index55 alt1"><code class="java spaces"> </code><code class="java keyword">protected</code> <code class="java keyword">void</code> <code class="java plain">onResume() {</code></div>
<div class="line number57 index56 alt2"><code class="java spaces"> </code><code class="java keyword">super</code><code class="java plain">.onResume();</code></div>
<div class="line number58 index57 alt1"><code class="java spaces"> </code><code class="java plain">Log.i(</code><code class="java string">"FlashTestNFC"</code><code class="java plain">, </code><code class="java string">"onResume"</code><code class="java plain">);</code></div>
<div class="line number59 index58 alt2"><code class="java spaces"> </code><code class="java keyword">if</code> <code class="java plain">(mNfcAdapter != </code><code class="java keyword">null</code><code class="java plain">) {</code></div>
<div class="line number60 index59 alt1"><code class="java spaces"> </code><code class="java comments">//添加intent-filter</code></div>
<div class="line number61 index60 alt2"><code class="java spaces"> </code><code class="java plain">IntentFilter ndef = </code><code class="java keyword">new</code> <code class="java plain">IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);</code></div>
<div class="line number62 index61 alt1"><code class="java spaces"> </code><code class="java plain">IntentFilter tag = </code><code class="java keyword">new</code> <code class="java plain">IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);</code></div>
<div class="line number63 index62 alt2"><code class="java spaces"> </code><code class="java plain">IntentFilter tech = </code><code class="java keyword">new</code> <code class="java plain">IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);</code></div>
<div class="line number64 index63 alt1"><code class="java spaces"> </code><code class="java plain">IntentFilter[] filters = </code><code class="java keyword">new</code> <code class="java plain">IntentFilter[]{ndef, tag, tech};</code></div>
<div class="line number65 index64 alt2"><code class="java spaces"> </code> </div>
<div class="line number66 index65 alt1"><code class="java spaces"> </code><code class="java comments">//添加 ACTION_TECH_DISCOVERED 情况下所能读取的NFC格式,这里列的比较全,实际我这里是没有用到的,因为测试的卡是NDEF的</code></div>
<div class="line number67 index66 alt2"><code class="java spaces"> </code><code class="java plain">String[][] techList = </code><code class="java keyword">new</code> <code class="java plain">String[][]{</code></div>
<div class="line number68 index67 alt1"><code class="java spaces"> </code><code class="java keyword">new</code> <code class="java plain">String[]{</code></div>
<div class="line number69 index68 alt2"><code class="java spaces"> </code><code class="java string">"android.nfc.tech.Ndef"</code><code class="java plain">,</code></div>
<div class="line number70 index69 alt1"><code class="java spaces"> </code><code class="java string">"android.nfc.tech.NfcA"</code><code class="java plain">,</code></div>
<div class="line number71 index70 alt2"><code class="java spaces"> </code><code class="java string">"android.nfc.tech.NfcB"</code><code class="java plain">,</code></div>
<div class="line number72 index71 alt1"><code class="java spaces"> </code><code class="java string">"android.nfc.tech.NfcF"</code><code class="java plain">,</code></div>
<div class="line number73 index72 alt2"><code class="java spaces"> </code><code class="java string">"android.nfc.tech.NfcV"</code><code class="java plain">,</code></div>
<div class="line number74 index73 alt1"><code class="java spaces"> </code><code class="java string">"android.nfc.tech.NdefFormatable"</code><code class="java plain">,</code></div>
<div class="line number75 index74 alt2"><code class="java spaces"> </code><code class="java string">"android.nfc.tech.MifareClassic"</code><code class="java plain">,</code></div>
<div class="line number76 index75 alt1"><code class="java spaces"> </code><code class="java string">"android.nfc.tech.MifareUltralight"</code><code class="java plain">,</code></div>
<div class="line number77 index76 alt2"><code class="java spaces"> </code><code class="java string">"android.nfc.tech.NfcBarcode"</code></div>
<div class="line number78 index77 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number79 index78 alt2"><code class="java spaces"> </code><code class="java plain">};</code></div>
<div class="line number80 index79 alt1"><code class="java spaces"> </code><code class="java plain">mNfcAdapter.enableForegroundDispatch(</code><code class="java keyword">this</code><code class="java plain">, pIntent, filters, techList);</code></div>
<div class="line number81 index80 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number82 index81 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number83 index82 alt2"><code class="java spaces"> </code> </div>
<div class="line number84 index83 alt1"><code class="java spaces"> </code><code class="java color1">@Override</code></div>
<div class="line number85 index84 alt2"><code class="java spaces"> </code><code class="java keyword">protected</code> <code class="java keyword">void</code> <code class="java plain">onPause() {</code></div>
<div class="line number86 index85 alt1"><code class="java spaces"> </code><code class="java keyword">super</code><code class="java plain">.onPause();</code></div>
<div class="line number87 index86 alt2"><code class="java spaces"> </code><code class="java plain">Log.i(</code><code class="java string">"FlashTestNFC"</code><code class="java plain">, </code><code class="java string">"onPause"</code><code class="java plain">);</code></div>
<div class="line number88 index87 alt1"><code class="java spaces"> </code><code class="java keyword">if</code> <code class="java plain">(mNfcAdapter != </code><code class="java keyword">null</code><code class="java plain">) {</code></div>
<div class="line number89 index88 alt2"><code class="java spaces"> </code><code class="java plain">mNfcAdapter.disableForegroundDispatch(</code><code class="java keyword">this</code><code class="java plain">);</code></div>
<div class="line number90 index89 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number91 index90 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number92 index91 alt1"><code class="java spaces"> </code> </div>
<div class="line number93 index92 alt2"><code class="java spaces"> </code><code class="java preprocessor">/**</code></div>
<div class="line number94 index93 alt1"><code class="java spaces"> </code><code class="java preprocessor">* 2进制to 16进制</code></div>
<div class="line number95 index94 alt2"><code class="java spaces"> </code><code class="java preprocessor">* @param src</code></div>
<div class="line number96 index95 alt1"><code class="java spaces"> </code><code class="java preprocessor">* @return</code></div>
<div class="line number97 index96 alt2"><code class="java spaces"> </code><code class="java preprocessor">*/</code></div>
<div class="line number98 index97 alt1"><code class="java spaces"> </code><code class="java keyword">private</code> <code class="java keyword">static</code> <code class="java plain">String bytesToHex(</code><code class="java keyword">byte</code><code class="java plain">[] src){</code></div>
<div class="line number99 index98 alt2"><code class="java spaces"> </code><code class="java plain">StringBuffer sb = </code><code class="java keyword">new</code> <code class="java plain">StringBuffer();</code></div>
<div class="line number100 index99 alt1"><code class="java spaces"> </code><code class="java keyword">if</code> <code class="java plain">(src == </code><code class="java keyword">null</code> <code class="java plain">|| src.length <= </code><code class="java value">0</code><code class="java plain">) {</code></div>
<div class="line number101 index100 alt2"><code class="java spaces"> </code><code class="java keyword">return</code> <code class="java keyword">null</code><code class="java plain">;</code></div>
<div class="line number102 index101 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number103 index102 alt2"><code class="java spaces"> </code><code class="java plain">String sTemp;</code></div>
<div class="line number104 index103 alt1"><code class="java spaces"> </code><code class="java keyword">for</code> <code class="java plain">(</code><code class="java keyword">int</code> <code class="java plain">i = </code><code class="java value">0</code><code class="java plain">; i < src.length; i++) {</code></div>
<div class="line number105 index104 alt2"><code class="java spaces"> </code><code class="java plain">sTemp = Integer.toHexString(</code><code class="java value">0xFF</code> <code class="java plain">& src);</code></div>
<div class="line number106 index105 alt1"><code class="java spaces"> </code><code class="java keyword">if</code> <code class="java plain">(sTemp.length() < </code><code class="java value">2</code><code class="java plain">){</code></div>
<div class="line number107 index106 alt2"><code class="java spaces"> </code><code class="java plain">sb.append(</code><code class="java value">0</code><code class="java plain">);</code></div>
<div class="line number108 index107 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number109 index108 alt2"><code class="java spaces"> </code><code class="java plain">sb.append(sTemp.toUpperCase());</code></div>
<div class="line number110 index109 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number111 index110 alt2"><code class="java spaces"> </code><code class="java keyword">return</code> <code class="java plain">sb.toString();</code></div>
<div class="line number112 index111 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div>
<div class="line number113 index112 alt2"><code class="java plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p><span style="color: rgba(128, 0, 0, 1)"><strong>解析:</strong>主要其实就是NfcAdapter.enableForegroundDispatch(),开启前台响应;在onNewIntent中获取系统传递过来的数据,并解析;在前台activity停止时,使用NfcAdapter.disableForegroundDispatch()关闭响应。下图是该activity在设置启动模式为singleTop或singleTask情况下,刷卡后该activity生命周期变化:</span></p>
<p><img src="https://img.jbzj.com/file_images/article/202109/2021918113239620.jpg?2021818113256" alt=""></p>
<p>enableForegroundDispatch源码注释解析,这里大致翻译一下:</p>
<ul>
<li>将发现的tag(可以理解为NFC刷卡事件)优先分配给应用程序的前台activity;</li>
<li>如果给该方法提供了任何IntentFilters,那么会优先去匹配ACTION_NDEF_DISCOVERED和ACTION_TAG_DISCOVERED。<span style="color: rgba(128, 0, 0, 1)">由于ACTION_TECH_DISCOVERED依赖于 IntentFilter 匹配之外的元数据,使用改IntentFilter要通过单独传入techLists来处理的。techLists中的每个第一级条目下的配置必须全部匹配才行。如果任何一级下的内容都匹配,则分派将通过给定的 PendingIntent 进行路由。(这三句话我解释一下:techLists参数是一个二维数组,可以设置很多级,每一级下是第二级,在第二级中放置相关匹配项;看我方法②中对techLists数组的构建方式就能明白)。换句话说,第一级内容是逻辑或关系,第二级内容是逻辑与关系。</span></li>
<li>如果IntentFilters和techLists都传了null,那么会默认匹配ACTION_TAG_DISCOVERED</li>
<li>这个方法必须在主线程调用,并且activity必须处于前台的情况下。同时,在activity调用enableForegroundDispatch方法后,必须在onPause时调用disableForegroundDispatch进行关闭。</li>
<li>Manifest文件中要声明NFC权限。</li>
</ul>
<p><img src="https://img.jbzj.com/file_images/article/202109/2021918113143764.jpg?2021818113155" alt=""></p>
<strong>总结:</strong>大概19年8-9月份的时候,那会儿刚开始实习不久,当时手头负责的项目就涉及到NFC刷卡,使用了方案①中的方式。在开发过程中,调试机为自己的华为Mate 20手机,每一次我打开刷卡页面进行刷卡时,都会默认跳转到微信的NFC事件响应页面,这叫一个头大;后来直接找到微信NFC开关,将其关闭后才不影响调试。好在线上手持机设备都是不让用户安装其他应用的。当时还很奇怪,微信到底咋就能强占这NFC响应,现在我终于找到了答案并进行了一定深度的挖掘。<br>
对于这两种方案,我更加偏向于方案②,因为交互上能够体验更好,使用方案①用户可能还会有一个选择的过程。<br><br>
来源:https://www.cnblogs.com/jiftle/p/16508358.html
頁:
[1]