Kevin Learn Android-->NFC 技术解析

Posted Kevin_小飞象

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kevin Learn Android-->NFC 技术解析相关的知识,希望对你有一定的参考价值。

前言

NFC 是 Near Field Communication 缩写,即近距离无线通讯技术。可以在移动设备、消费类电子产品、PC 和智能控件工具间进行近距离无线通信。

NFC 工作模式

NFC 工作模式主要有三种工作模式,分别是卡模式(Card emulation)、点对点模式(P2P mode)和读卡器模式(Reader/writer mode)。

  • 读卡器模式
    数据在 NFC 芯片中,可以简单理解成“刷标签”。本质上就是通过支持 NFC 的手机或其它电子设备从带有 NFC 芯片的标签、贴纸、名片等媒介中读写信息。通常 NFC 标签是不需要外部供电的。当支持 NFC 的外设向 NFC 读写数据时,它会发送某种磁场,而这个磁场会自动的向 NFC 标签供电。

  • 仿真卡模式
    数据在支持 NFC 的手机或其它电子设备中,可以简单理解成“刷手机”。本质上就是将支持 NFC 的手机或其它电子设备当成借记卡、公交卡、门禁卡等 IC 卡使用。基本原理是将相应IC卡中的信息凭证封装成数据包存储在支持 NFC 的外设中 。在使用时还需要一个 NFC 射频器(相当于刷卡器)。将手机靠近 NFC 射频器,手机就会接收到 NFC 射频器发过来的信号,在通过一系列复杂的验证后,将 IC 卡的相应信息传入 NFC 射频器,最后这些 IC 卡数据会传入 NFC 射频器连接的电脑,并进行相应的处理(如电子转帐、开门等操作)。

  • 点对点模式
    该模式与蓝牙、红外差不多,用于不同NFC设备之间进行数据交换,不过这个模式已经没有有“刷”的感觉了。其有效距离一般不能超过4厘米,但传输建立速度要比红外和蓝牙技术快很多,传输速度比红外块得多,如过双方都使用 android4.2,NFC会直接利用蓝牙传输。这种技术被称为 AndroidBeam。所以使用 androidBeam 传输数据的两部设备不再限于4厘米之内。

准备工作

1. 在清单文件中,设置权限和配置 launchMode 属性

	<uses-permission android:name="android.permission.NFC" /> 
    <uses-feature
        android:name="android.hardware.nfc"
        android:required="true" />

	...
	<activity
            android:name=".ui.RunUrlActivity"
            android:exported="false"
            android:launchMode="singleTop" />

注意:通常来说,所有处理 NFCActivity 都要设置 launchMode 属性为 singleTop 或者 singleTask,保证了无论 NFC 标签靠近手机多少次,Activity 实例只有一个。

2. BaseNfcActivity.java

public abstract class BaseNfcActivity extends AppCompatActivity 
    private NfcAdapter mNfcAdapter;
    private PendingIntent mPendingIntent;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        View view = LayoutInflater.from(this).inflate(getLayoutId(), null);
        setContentView(view);
        ButterKnife.bind(this);
        initView();
    

    protected abstract int getLayoutId();

    protected abstract void initView();

    /**
     * 启动Activity,界面可见时
     */
    @Override
    protected void onStart() 
        super.onStart();
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        //一旦截获NFC消息,就会通过PendingIntent调用窗口
        mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()), 0);
    

    /**
     * 获得焦点,按钮可以点击
     */
    @Override
    public void onResume() 
        super.onResume();
        //设置处理优于所有其他NFC的处理
        if (mNfcAdapter != null)
            mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
    

    /**
     * 暂停Activity,界面获取焦点,按钮可以点击
     */
    @Override
    public void onPause() 
        super.onPause();
        //恢复默认状态
        if (mNfcAdapter != null)
            mNfcAdapter.disableForegroundDispatch(this);
    

    /**
     * 不带参数的跳转
     *
     * @param clazz 跳转到的目标类
     */
    protected void readyGo(final Class<?> clazz) 
        Intent intent = new Intent(this, clazz);
        startActivity(intent);
    

    /**
     * 带参数的跳转
     *
     * @param clazz  跳转到的目标类
     * @param bundle 参数
     */
    protected void readyGo(final Class<?> clazz, final Bundle bundle) 
        Intent intent = new Intent(this, clazz);
        if (bundle != null) 
            intent.putExtras(bundle);
        
        startActivity(intent);
    

简单实例

场景:现将应用程序的包写到 NFC 程序上,然后我们将 NFC 标签靠近 Android 手机,手机就会自动运行包所对应的程序,这个是 NFC 比较基本的一个应用。下面以贴近标签自动运行 Android 自带的“短信”为例。
1. 获取 Tag 对象

@Override
    public void onNewIntent(Intent intent) 
        super.onNewIntent(intent);
        if (mPackageName == null)
            return;
        //1.获取Tag对象
        Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        writeNFCTag(detectedTag);
    

2. 判断 NFC 标签的数据类型(通过 Ndef.get 方法)

	//2.判断NFC标签的数据类型(通过Ndef.get方法)
    Ndef ndef = Ndef.get(tag);

3. 写入数据

	//3.写入数据
    ndef.writeNdefMessage(ndefMessage);

完整代码

public class RunAppActivity extends BaseNfcActivity 
    private String mPackageName = "com.android.mms";//短信

    @BindView(R.id.topbar)
    QMUITopBar mTopBar;

    @Override
    protected int getLayoutId() 
        return R.layout.activity_run_app;
    

    @Override
    protected void initView() 
        mTopBar.setTitle("自动运行程序");
    

    @Override
    public void onNewIntent(Intent intent) 
        super.onNewIntent(intent);
        if (mPackageName == null)
            return;
        //1.获取Tag对象
        Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        writeNFCTag(detectedTag);
    

    /**
     * 往标签写数据的方法
     *
     * @param tag
     */
    public void writeNFCTag(Tag tag) 
        if (tag == null) 
            return;
        
        NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]NdefRecord
                .createApplicationRecord(mPackageName));
        //转换成字节获得大小
        int size = ndefMessage.toByteArray().length;
        try 
            //2.判断NFC标签的数据类型(通过Ndef.get方法)
            Ndef ndef = Ndef.get(tag);
            //判断是否为NDEF标签
            if (ndef != null) 
                ndef.connect();
                //判断是否支持可写
                if (!ndef.isWritable()) 
                    return;
                
                //判断标签的容量是否够用
                if (ndef.getMaxSize() < size) 
                    return;
                
                //3.写入数据
                ndef.writeNdefMessage(ndefMessage);
                Toast.makeText(this, "写入成功", Toast.LENGTH_SHORT).show();
             else  //当我们买回来的NFC标签是没有格式化的,或者没有分区的执行此步
                //Ndef格式类
                NdefFormatable format = NdefFormatable.get(tag);
                //判断是否获得了NdefFormatable对象,有一些标签是只读的或者不允许格式化的
                if (format != null) 
                    //连接
                    format.connect();
                    //格式化并将信息写入标签
                    format.format(ndefMessage);
                    Toast.makeText(this, "写入成功", Toast.LENGTH_SHORT).show();
                 else 
                    Toast.makeText(this, "写入失败", Toast.LENGTH_SHORT).show();
                
            
         catch (Exception e) 
        
    

测试方法:
NFC 标签贴近手机背面,自动写入数据,此时退出所有程序,返回桌面,然后再将 NFC 标签贴近手机背面,将会看到自动打开了“短信”。

以上是关于Kevin Learn Android-->NFC 技术解析的主要内容,如果未能解决你的问题,请参考以下文章

Kevin Learn Kotlin:构建第一个 Android App

Kevin Learn Android:Android 手签板

Kevin Learn Android:Android 手签板

Kevin Learn Android--> Android Studio 小技巧

Kevin Learn Kotlin-->Kotlin 学习资料

Kevin Learn Kotlin:循环控制