IntelliJ IDEA 手机 NFC 开发入门


1、新建 Android 项目

点击菜单“File / New Project…”开始创建项目:

QQ截图1

为项目起名:

QQ截图2

选择项目要使用的 API:

QQ截图3

点击“Finish”按钮完成项目的创建。

2、运行新建的项目

点击运行按钮:

QQ截图4

选择运行的设备(这里是 HTC One 手机设备):

QQ截图5

运行结果:

-1415589484129

3、添加依赖和权限

从以下地址下载 JAR 包:

android-support-v4.jar:http://pan.baidu.com/s/1c0riGta
org.simalliance.openmobileapi.jar:http://pan.baidu.com/s/1mgFUSNu

将上面下载的两个 JAR 包添加到项目的 libs 目录:

QQ截图20141110135959

在 libs 目录的右键菜单里点击“Add as Lirary”,将 libs 目录设置为项目的 Library 目录:

-1415349758179

在 AndroidManifest.xml 文件里添加访问权限:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="cn.cytong.NFCTest"
          android:versionCode="1"
          android:versionName="1.0">
    <uses-sdk android:minSdkVersion="14"/>
    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
        <!--添加依赖 END-->
        <activity android:name="MyActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
    <!--添加权限-->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="org.simalliance.openmobileapi.SMARTCARD" />
    <!--添加权限 END-->
</manifest>

4、实现接口

修改 MyActivity.java 文件,实现 SEService.CallBack 接口:

package cn.cytong.NFCTest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

/*----- 1、应用 Open Mobile API 包 -----*/
import android.widget.Toast;
import cn.cytong.util.HexTool;
import org.simalliance.openmobileapi.*;

/*----- 2、指定实现 SEService.CallBack 接口 -----*/
public class MyActivity extends Activity implements SEService.CallBack {
    private String LOG_TAG = "NFCTest";
    /*----- 3、定义 SEService 对象 -----*/
    public SEService seService;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        try {
            Log.i(LOG_TAG, "creating SEService object...");

            /*----- 4、创建 SEService 对象 -----*/
            seService = new SEService(this, this);
        } catch (Exception e) {
            Log.e("NFCTest", "Error: " + e.getMessage());
        }
    }

    /*----- 5、实现 SEService.CallBack 接口(连接成功时触发的事件)-----*/
    public void serviceConnected(SEService service) {
        Log.i("NFCTest", "SEService has been successfully connected!");
    }
}

5、发送 APDU 指令

为简化过程,直接在 serviceConnected 方法里发送 APDU 指令

    public void serviceConnected(SEService seService) {
        Log.i("NFCTest", "SEService has been successfully connected!");

        try {
            /* 1)查询有效的 Reader 对象 */
            Log.i(LOG_TAG, "Retrieve available readers...");
            Reader[] readers = seService.getReaders();
            if (readers.length < 1)
                return;

            /* 2)创建 Session 对象 */
            Log.i(LOG_TAG, "Create Session from the first reader...");
            Session session = readers[0].openSession();

            // 3)创建逻辑通道
            Log.i(LOG_TAG, "Create logical channel within the session...");
            // 替换成自己的 AID
            byte[] aid = new byte[]{
                    (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                    (byte) 0x30, (byte) 0x80, (byte) 0x00, (byte) 0x00,
                    (byte) 0x00, (byte) 0x08, (byte) 0x71, (byte) 0x00, (byte) 0x01};
            Channel channel = session.openLogicalChannel(aid);

            // 4)发送 APDU 指令
            Log.d(LOG_TAG, "Send APDU command");
            // 替换成自己的通道命令,如果返回 "6D00" 表示未找到对应的命令
            byte[] command = new byte[]{(byte)0x00, (byte)0x84, (byte)0x00, (byte)0x00, (byte)0x08};
            byte[] respApdu = channel.transmit(command);

            // 4)关闭逻辑通道
            channel.close();

            // 5)显示指令返回结果
            String hexString = "";
            for (int i = 0; i < respApdu.length; i++) {
                hexString += Integer.toHexString((respApdu[i] & 0xFF) | 0x100).toUpperCase().substring(1, 3);
            }
            Log.i(LOG_TAG, hexString);
            Toast.makeText(MyActivity.this, hexString, Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            Log.e(LOG_TAG, "Error:", e);
            return;
        }
    }

前一篇:
后一篇:

评论(共2条)

魏黑黑 10月18日 11:25  回复

java.lang.SecurityException: Access Control Enforcer: access denied:Cannot select PKCS#15 directory via EF Dir

发表评论