AndroidManifest.xml
<application android:name=".NfcApplication"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@android:style/Theme.Material.Light"
android:persistent="true"
android:hardwareAccelerated="false"
android:backupAgent="com.android.nfc.NfcBackupAgent"
android:killAfterRestore="false"
android:usesCleartextTraffic="false"
android:supportsRtl="true"
>
public void onCreate() {
super.onCreate();
boolean isMainProcess = false;
......
ActivityManager am = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
List processes = am.getRunningAppProcesses();
Iterator i = processes.iterator();
while (i.hasNext()) {
RunningAppProcessInfo appInfo = (RunningAppProcessInfo)(i.next());
if (appInfo.pid == Process.myPid()) {
isMainProcess = (NFC_PROCESS.equals(appInfo.processName));
break;
}
}
if (UserHandle.myUserId() == 0 && isMainProcess) {
mNfcService = new NfcService(this);
ThreadedRenderer.enableForegroundTrimming();
}
}
xp022430@cnbjlx24729:~$ adb shell ps -A | grep nfc
nfc 897 1 22164 3016 binder_thread_read 70db203f18 S [email protected]
nfc 2785 735 2283348 68876 SyS_epoll_wait 7d0f471e28 S com.android.nfc
u0_a114 7005 735 2249568 39120 SyS_epoll_wait 7d0f471e28 S com.sonymobile.nfcextension
import com.android.nfc.DeviceHost.DeviceHostListener;
public class NfcService implements DeviceHostListener { }.
public interface DeviceHost {
//NfcService实现了它的具体功能,里面基本上都是描述的整体nfc的状态的接口.
public interface DeviceHostListener {
//当检测到远端的tag的时候的回调,TagEndpoint:来表示远端的tag
public void onRemoteEndpointDiscovered(TagEndpoint tag);
......
//当卡模拟的Aid被选中的时候
public void onCardEmulationAidSelected(byte[] aid,byte[] data, int evtSrc);
//通知se相关的事件
public void onConnectivityEvent(int evtSrc);
//当P2P链接成功的时候
public void onLlcpLinkActivated(NfcDepEndpoint device);
......
//作为reader检测到remoteFiled(就是远端的card)的时候
public void onRemoteFieldActivated();
......
}
//NativeNfcTag类实现了它的具体功能,用来实现Nfc Tag的一些功能。
public interface TagEndpoint {
//Tag建立起了连接
boolean connect(int technology);
......
//读取Tag中所用到的tech
int[] getTechList();
......
//读取Tag中的ndef消息
byte[] readNdef();
//向Tag中写入Ndef消息
boolean writeNdef(byte[] data);
......
}
//Tag断开链接的回调
public interface TagDisconnectedCallback {
void onTagDisconnected(long handle);
}
......
//NativeP2pDevice类实现它的具体功能,P2P的Initiator发起端的功能实现。
//自己没有跟这里的看起来即可以表示发起端,又可以表示接收端。
public interface NfcDepEndpoint {
/**
* Peer-to-Peer Target
*/
public static final short MODE_P2P_TARGET = 0x00;
/**
* Peer-to-Peer Initiator
*/
public static final short MODE_P2P_INITIATOR = 0x01;
......
public byte[] receive();
public boolean send(byte[] data);
public boolean connect();
public boolean disconnect();
......
}
//NativeLlcpSocket类实现它的具体功能,
//代表了一个llcp链接中的客户端的通信部分.
//那么问题来了P2P的这个连接中谁是客户端?发起方?接收方?还是说并不是P2P才用这个?
//比如read/write模式。这样就比较好定义客户端和服务端了。?这块不太清楚
public interface LlcpSocket {
......
public void connectToService(String serviceName) throws IOException;
public void close() throws IOException;
public void send(byte[] data) throws IOException;
public int receive(byte[] recvBuff) throws IOException;
public int getRemoteMiu();
......
public int getLocalSap();
......
}
//NativeLlcpServiceSocket类实现它的具体功能,表示一个llcp链接中的服务端的通信部分.
public interface LlcpServerSocket {
//监听客户端的链接
public LlcpSocket accept() throws IOException, LlcpException;
//关闭服务
public void close() throws IOException;
}
//NativeLlcpConnectionlessSocket类实现它的具体功能,代表在无连接通信中使用的LLCP对象?不太清楚.
public interface LlcpConnectionlessSocket {
public int getLinkMiu();
public int getSap();
public void send(int sap, byte[] data) throws IOException;
public LlcpPacket receive() throws IOException;
public void close() throws IOException;
}
//以上的接口在内部实现的时候如它们的名字所示,Native...,他们内部基本都有native方法去进一步的
//通过JNI调用到native层实现的地方。
//下面都是管理NFC功能的api,位于NativeNfcManager当中.
public void checkFirmware();
......
public boolean initialize();
public String getName();
public void enableDiscovery(NfcDiscoveryParameters params, boolean restart);
public void doSetScreenState(int mScreenState);
......
public void disableDiscovery();
......
public LlcpConnectionlessSocket createLlcpConnectionlessSocket(int nSap, String sn)
throws LlcpException;
public LlcpServerSocket createLlcpServerSocket(int nSap, String sn, int miu,
int rw, int linearBufferLength) throws LlcpException;
public LlcpSocket createLlcpSocket(int sap, int miu, int rw,
int linearBufferLength) throws LlcpException;
......
}
public NfcService(Application nfcApplication) {
......
//Nfc Tag相关的一些操作.最终调用到的就是DeviceHost里面的interface的
//实现NativeNfcTag此处就是final class TagService extends INfcTag.Stub {...}
//然后在内部的方法中去调用DeviceHost.TagEndpoint,也就是调用到了NativeNfcTag.
//下面的很多service都是这种实现方式,这样framework层api通过binder调用到native层实现的地方
mNfcTagService = new TagService();
//BluetoothAdapter类似,用于供外部调用NFC功能。个人理解adapter适配,也就是说其实是一个转接口
//它只是提供统一规范,然后在它的内部会再去调用如NativeNfcManager里面真正的native的方法去和NFC打交道
//这样做还有一个好处就是可以一定程度封装代码。结构清晰,代码隐蔽.
//实现方式类似上面的TagService
mNfcAdapter = new NfcAdapterService();
//下面省略了一些NxpNfcAdapterService的初始化,暂时不清楚这些类的功能,可能是HiNXP扩展用.
......
//卡模拟的service,现在直接被注释掉了,可能不用了,直接用对应的manager管理
//mCardEmulationService = new CardEmulationService();
//sService是NfcService
sService = this;
//NFC与屏幕锁定状态相关的类,用来方便屏幕状态的管理
mScreenStateHelper = new ScreenStateHelper(mContext);
//NativeNfcManager里面基本上都是native的方法,用于进一步调用到native层和NFC进行通信.
//private DeviceHost mDeviceHost;可以看到NativeNfcManager就是DeviceHost
mDeviceHost = new NativeNfcManager(mContext, this);
//在进行一些handover等的时候,NFC对屏幕解锁的一些逻辑(某些状态下)。
mNfcUnlockManager = NfcUnlockManager.getInstance();
//使用别的技术如蓝牙进行handover的时候的帮助类,目前为止只有对蓝牙的实现,可以通过此类
//把蓝牙地址、名字等信息封装成对应的标准NDEF Message进行传输.
mHandoverDataParser = new HandoverDataParser();
......//此处省略了在Nfc在setup wizard阶段接受数据的处理
//分发Nfc的不同的EVENT然后根据Android的policy区启动对应的activity处理相应的事件。
mNfcDispatcher = new NfcDispatcher(mContext, mHandoverDataParser, mInProvisionMode);
//基于LLCP连接的服务,含NdefPushService/SnepService/P2pEventManager
//就是处理NFC进行P2P的时候的一些逻辑
mP2pLinkManager = new P2pLinkManager(mContext, mHandoverDataParser,
mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize());
//电源管理模块,主要是处理屏幕状态与NFC是否响应的联系
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
......
//注册屏幕亮/灭,用户激活和切换
IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
mContext.registerReceiver(mOwnerReceiver, filter);
IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiver(mOwnerReceiver, ownerFilter);
//关注程序安装和卸载
ownerFilter = new IntentFilter();
ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
ownerFilter.addDataScheme("package");
mContext.registerReceiver(mOwnerReceiver, ownerFilter);
......
//gmsa enable Nfc的时候,可能和一些测试case有关
IntentFilter enableNfc = new IntentFilter();
enableNfc.addAction(NxpConstants.ACTION_GSMA_ENABLE_NFC);
mContext.registerReceiverAsUser(mEnableNfc, UserHandle.ALL, enableNfc, null, null);
//Nfc状态变化的时候的广播
IntentFilter lsFilter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
//mContext.registerReceiver(mAlaReceiver, lsFilter);
mContext.registerReceiverAsUser(mAlaReceiver, UserHandle.ALL, lsFilter, null, null);
......
//把NfcAdapterService添加到ServiceManager当中,别的就可以通过
//INfcAdapter.Stub.asInterface(nfcServiceBinder).
ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
//Nfc和相机的一些交互,如相机启动的时候Nfc能不能工作等
mCameraManager = (CameraManager)mContext.getSystemService(Context.CAMERA_SERVICE);
......
//TASK_BOOT,异步的开始执行NFC的enable.
new EnableDisableTask().execute(TASK_BOOT);
}
final class TagService extends INfcTag.Stub{
@Override
public int connect(int nativeHandle, int technology) throws RemoteException {
//检查权限
NfcPermissions.enforceUserPermissions(mContext);
TagEndpoint tag = null;
//判断NFC是否可用.
if (!isNfcEnabled()) {
return ErrorCodes.ERROR_NOT_INITIALIZED;
}
//final HashMap mObjectMap = new HashMap();
//tag在发现时候会调用registerTagObject添加到一个集合当中,
//以:key = tag.getHandle() native的handle就是如在c/c++层的对象的代表,value = tag
tag = (TagEndpoint) findObject(nativeHandle);
......
//判断Tag是否还在范围内
if (!tag.isPresent()) {
return ErrorCodes.ERROR_DISCONNECT;
}
//调用NativeNfcTag的connect方法,传入technology
//technology是Nfc Tag使用技术协议有:
//public static final int NFC_A = 1;
//public static final int NFC_B = 2;
//public static final int ISO_DEP = 3;
//public static final int NDEF = 6;
//.....等等很多
if (tag.connect(technology)) {
return ErrorCodes.SUCCESS;
}
......
}
@Override
public int reconnect(int nativeHandle) throws RemoteException {
......
tag.reconnect())
......
}
@Override
public int[] getTechList(int nativeHandle) throws RemoteException {
......
tag.getTechList();
......
}
@Override
public boolean isPresent(int nativeHandle) throws RemoteException {
......
return tag.isPresent();
}
@Override
public boolean isNdef(int nativeHandle) throws RemoteException {
......
return tag.checkNdef(ndefInfo);
}
@Override
public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw)
throws RemoteException {
......
/* find the tag in the hmap */
tag = (TagEndpoint) findObject(nativeHandle);
if (tag != null) {
// Check if length is within limits
if (data.length > getMaxTransceiveLength(tag.getConnectedTechnology())) {
return new TransceiveResult(TransceiveResult.RESULT_EXCEEDED_LENGTH, null);
}
int[] targetLost = new int[1];
response = tag.transceive(data, raw, targetLost);
int result;
if (response != null) {
result = TransceiveResult.RESULT_SUCCESS;
} else if (targetLost[0] == 1) {
result = TransceiveResult.RESULT_TAGLOST;
} else {
result = TransceiveResult.RESULT_FAILURE;
}
return new TransceiveResult(result, response);
}
return null;
}
@Override
public NdefMessage ndefRead(int nativeHandle) throws RemoteException {
......
return new NdefMessage(buf);
......
}
@Override
public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException {
......
tag.writeNdef(msg.toByteArray())
......
}
......
@Override
public int formatNdef(int nativeHandle, byte[] key) throws RemoteException {
......
tag.formatNdef(key)
......
}
......
}
public class NativeNfcTag implements TagEndpoint {
//通过JNI调用到了native层相应的实现处.
private native int doConnect(int handle);
......
public synchronized boolean connect(int technology) {
return connectWithStatus(technology) == 0;
}
public synchronized int connectWithStatus(int technology) {
......
int status = -1;
for (int i = 0; i < mTechList.length; i++) {
//当要链接的tech包含在支持的Tech的时候
if (mTechList[i] == technology) {
// Get the handle and connect, if not already connected
if (mConnectedHandle != mTechHandles[i]) {
//如果是没有连接过,
if (mConnectedHandle == -1) {
//则直接调用到doConnect()
status = doConnect(i);
} else {
//调用接口再次链接
status = reconnectWithStatus(i);
}
if (status == 0) {
mConnectedHandle = mTechHandles[i];
mConnectedTechIndex = i;
}
} else {
//当我们已经连接过Tag的时候要分情况讨论
// 1) We are connected to a technology which has the same
// handle; we do not support connecting at a different
// level (libnfc auto-activates to the max level on
// any handle).
// 2) We are connecting to the ndef technology - always
// allowed.
if ((technology == TagTechnology.NDEF) ||
(technology == TagTechnology.NDEF_FORMATABLE)) {
// special case for NDEF, this will cause switch to ISO_DEP frame intf
i = 0;
}
status = reconnectWithStatus(i);
......
}
break;
}
}
......
return status;
}
......
native int doHandleReconnect(int handle);
public synchronized int reconnectWithStatus(int handle) {
......
int status = doHandleReconnect(handle);
......
return status;
}
}
/*******************************************************************************
**
** Function: nativeNfcTag_doConnect
**
** Description: Connect to the tag in RF field.
** e: JVM environment.
** o: Java object.
** targetHandle: Handle of the tag.
**
** Returns: Must return NXP status code, which NFC service expects.
**
*******************************************************************************/
static jint nativeNfcTag_doConnect (JNIEnv*, jobject, jint targetHandle)
{
ALOGV("%s: targetHandle = %d", __func__, targetHandle);
int i = targetHandle;
NfcTag& natTag = NfcTag::getInstance ();
int retCode = NFCSTATUS_SUCCESS;
sCurrentConnectedTargetType = natTag.mTechList[i];
sCurrentConnectedTargetProtocol = natTag.mTechLibNfcTypes[i];
......
#if(NXP_EXTNS == TRUE) //可以在mk文件中搜索"DNXP_EXTNS"
sCurrentConnectedHandle = targetHandle;
if(sCurrentConnectedTargetProtocol == NFC_PROTOCOL_T3BT)
{
goto TheEnd;
}
#endif
if (sCurrentConnectedTargetProtocol != NFC_PROTOCOL_ISO_DEP)
{
ALOGV("%s() Nfc type = %d, do nothing for non ISO_DEP", __func__,
sCurrentConnectedTargetProtocol);
retCode = NFCSTATUS_SUCCESS; //打印Log的时候发现,即使进入到此处也是能打印出来。
goto TheEnd;
}
/* Switching is required for CTS protocol paramter test case.*/
if (sCurrentConnectedTargetType == TARGET_TYPE_ISO14443_3A || sCurrentConnectedTargetType ==
TARGET_TYPE_ISO14443_3B)
{
retCode = switchRfInterface(NFA_INTERFACE_FRAME) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
}
else
{
//切换NFC chip的RF interface.这样应该不会连接好像再往下会执行好几次的reconnect.
retCode = switchRfInterface(NFA_INTERFACE_ISO_DEP) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
}
TheEnd:
ALOGV("%s: exit 0x%X", __func__, retCode);
return retCode;
}
/*******************************************************************************
**
** Function: nativeNfcTag_doHandleReconnect
**
** Description: Re-connect to the tag in RF field.
** e: JVM environment.
** o: Java object.
** targetHandle: Handle of the tag.
**
** Returns: Status code.
**
*******************************************************************************/
static jint nativeNfcTag_doHandleReconnect (JNIEnv *e, jobject o, jint targetHandle)
{
ALOGV("%s: targetHandle = %d", __func__, targetHandle);
...
//可以看到又调用到了前面说的nativeNfcTag_doConnect
return nativeNfcTag_doConnect (e, o, targetHandle);
}
/*******************************************************************************
**
** Function: switchRfInterface
**
** Description: Switch controller's RF interface to frame, ISO-DEP, or NFC-DEP.
** rfInterface: Type of RF interface.
**
** Returns: True if ok.
**
*******************************************************************************/
static bool switchRfInterface (tNFA_INTF_TYPE rfInterface)
{
ALOGV("%s: rf intf = %d", __func__, rfInterface);
......
bool rVal = true;
if (rfInterface != sCurrentRfInterface)
{
//有变化的话,调用reSelect
//Deactivates the tag and re-selects it with the specified rf interface.
if (0 == reSelect(rfInterface, true))
{
sCurrentRfInterface = rfInterface;
rVal = true;
}
...
}
return rVal;
}
final class NfcAdapterService extends INfcAdapter.Stub{
@Override
public boolean enable() throws RemoteException {
//检查权限
NfcPermissions.enforceAdminPermissions(mContext);
int val = mDeviceHost.GetDefaultSE();
Log.i(TAG, "getDefaultSE " + val);
//默认的安全模块策略
saveNfcOnSetting(true);
//对比前面的NfcService的构造中的最后一步,会发现enable/disable都是通过这个Task
new EnableDisableTask().execute(TASK_ENABLE);
return true;
}
@Override
public boolean disable(boolean saveState) throws RemoteException {
......
new EnableDisableTask().execute(TASK_DISABLE);
return true;
}
......
@Override
public void resumePolling() {
......
new ApplyRoutingTask().execute();
}
......
@Override
public boolean enableNdefPush() throws RemoteException {
......
mDeviceHost.doEnablep2p(mIsNdefPushEnabled);
mP2pLinkManager.enableDisable(true, true);
......
}
@Override
public boolean disableNdefPush() throws RemoteException {
......
mP2pLinkManager.enableDisable(false, true);
......
}
//在activity中置此函数后,收到的消息会只在前台的APP处理。
//场景是进入一个app如taginfo以后再读取nfc tag
@Override
public void setForegroundDispatch(PendingIntent intent,
IntentFilter[] filters, TechListParcel techListsParcel) {
......
mNfcDispatcher.setForegroundDispatch(intent, filters, techLists);
}
......
//得到卡模拟的interface
@Override
public INfcFCardEmulation getNfcFCardEmulationInterface() {
......
return mCardEmulationManager.getNfcFCardEmulationInterface();
......
}
//返回当前Nfc的state: on/off/turning..
@Override
public int getState() throws RemoteException {
synchronized (NfcService.this) {
return mState;
}
}
......
//分发检测到的Tag的信息,尝试去启动相应的activity
@Override
public void dispatch(Tag tag) throws RemoteException {
......
mNfcDispatcher.dispatchTag(tag);
}
@Override
public void setP2pModes(int initiatorModes, int targetModes) throws RemoteException {
NfcPermissions.enforceAdminPermissions(mContext);
mDeviceHost.setP2pInitiatorModes(initiatorModes);
mDeviceHost.setP2pTargetModes(targetModes);
applyRouting(true);
}
//外部第三方app调用,用来做卡模拟的.
@Override
public void setReaderMode(IBinder binder, IAppCallback callback, int flags, Bundle extras)
throws RemoteException {
......
synchronized (NfcService.this) {
...
if (flags != 0) {
mReaderModeParams = new ReaderModeParams();
mReaderModeParams.callback = callback;
mReaderModeParams.flags = flags;
mReaderModeParams.presenceCheckDelay = extras != null
? (extras.getInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY,
DEFAULT_PRESENCE_CHECK_DELAY))
: DEFAULT_PRESENCE_CHECK_DELAY;
binder.linkToDeath(mReaderModeDeathRecipient, 0);
} else {
......
mReaderModeParams = null;
binder.unlinkToDeath(mReaderModeDeathRecipient, 0);
}
Log.e(TAG, "applyRouting -4");
applyRouting(false);
}
}
......
}
class NfcDispatcher {
......
//使用前台调度系统的时候最终会回调到这里。
public synchronized void setForegroundDispatch(PendingIntent intent,
IntentFilter[] filters, String[][] techLists) {
//为相应的变量进行初始化
mOverrideIntent = intent;
mOverrideFilters = filters;
mOverrideTechLists = techLists;
}
......
//分发Tag,内部分发时候调用具体的如:tryOverrides、tryNdef、tryTech去做进一步的处理.
//整体是按照Android Nfc的分发系统来进行不同优先级的处理的,前台的最高,然后是注册
//ACTION_NDEF_DISCOVERED,再然后是ACTION_TECH_DISCOVERED,最后是ACTION_TAG_DISCOVERD
具体策略可查看官方文档:
//https://developer.android.com/guide/topics/connectivity/nfc/nfc.html
public int dispatchTag(Tag tag) {
PendingIntent overrideIntent;
IntentFilter[] overrideFilters;
String[][] overrideTechLists;
String[] provisioningMimes;
boolean provisioningOnly;
synchronized (this) {
overrideFilters = mOverrideFilters;
overrideIntent = mOverrideIntent;
overrideTechLists = mOverrideTechLists;
provisioningOnly = mProvisioningOnly;
provisioningMimes = mProvisioningMimes;
}
//屏幕解锁相关
boolean screenUnlocked = false;
//如果是处在锁屏(屏幕已经点亮)
if (!provisioningOnly &&
mScreenStateHelper.checkScreenState() ==
ScreenStateHelper.SCREEN_STATE_ON_LOCKED) {
//尝试去解锁屏幕
screenUnlocked = handleNfcUnlock(tag);
if (!screenUnlocked) {
return DISPATCH_FAIL;
}
}
......
//当使用前台调度系统的时候会通过它进行覆盖,成功的话就不去执行NFC基本的分发系统了.
if (tryOverrides(dispatch, tag, message, overrideIntent, overrideFilters,
overrideTechLists)) {
return screenUnlocked ? DISPATCH_UNLOCK : DISPATCH_SUCCESS;
}
//尝试去进行Handover.如带Nfc的BT耳机、键盘等等.
if (tryPeripheralHandover(message)) {
if (DBG) Log.i(TAG, "matched BT HANDOVER");
return screenUnlocked ? DISPATCH_UNLOCK : DISPATCH_SUCCESS;
}
//按理说现在Android还没有实现Nfc打开wifi呀?
if (NfcWifiProtectedSetup.tryNfcWifiSetup(ndef, mContext)) {
if (DBG) Log.i(TAG, "matched NFC WPS TOKEN");
return screenUnlocked ? DISPATCH_UNLOCK : DISPATCH_SUCCESS;
}
......
//在进行NDEF Message的判断,判断是否为ACTION_NDEF_DISCOVERD
if (tryNdef(dispatch, message)) {
return screenUnlocked ? DISPATCH_UNLOCK : DISPATCH_SUCCESS;
}
......
//如果前面都没有成功处理消息,判断是否为ACTION_TECH_DISCOVERD.
if (tryTech(dispatch, tag)) {
return DISPATCH_SUCCESS;
}
//最后一种,也是优先级最低的intent为ACTION_TAG_DISCOVERD 。
dispatch.setTagIntent();
//直接尝试查询启动,有多个时候会弹框提示。
if (dispatch.tryStartActivity()) {
if (DBG) Log.i(TAG, "matched TAG");
return DISPATCH_SUCCESS;
}
if (DBG) Log.i(TAG, "no match");
return DISPATCH_FAIL;
}
}
boolean tryStartActivity() {
//查询所有注册了的携带指定action的intent的activities
//注意到这之前就已经为intent配置好了对应的action
List<ResolveInfo> activities = packageManager.queryIntentActivitiesAsUser(intent, 0,
ActivityManager.getCurrentUser());
if (activities.size() > 0) {
context.startActivityAsUser(rootIntent, UserHandle.CURRENT);
NfcIddEvent.NfcTag.dispatchedToApp(tag, activities);
return true;
}
return false;
}
//道理同上
boolean tryStartActivity(Intent intentToStart) {
List<ResolveInfo> activities = packageManager.queryIntentActivitiesAsUser(
intentToStart, 0, ActivityManager.getCurrentUser());
if (activities.size() > 0) {
rootIntent.putExtra(NfcRootActivity.EXTRA_LAUNCH_INTENT, intentToStart);
context.startActivityAsUser(rootIntent, UserHandle.CURRENT);
NfcIddEvent.NfcTag.dispatchedToApp(tag, activities);
return true;
}
return false;
}
interface P2pEventListener {
//user想要通过Nfc去share一些数据,但是远端的设备还没有onRange,对用户进行提示.
public void onP2pNfcTapRequested();
//等待传输超时的回调.
public void onP2pTimeoutWaitingForLink();
//表明P2P的设备in range
public void onP2pInRange();
//当一个NDEF的数据准备发送,并且需要确认的时候调用.
public void onP2pSendConfirmationRequested();
//P2P发送完成
public void onP2pSendComplete();
......
//Called to indicate the remote device does not support connection handover
public void onP2pHandoverNotSupported();
//Called to indicate the device is busy with another handover transfer
public void onP2pHandoverBusy();
//当P2P接受完成的时候
public void onP2pReceiveComplete(boolean playSound);
//Indicates the P2P device went out of range.
public void onP2pOutOfRange();
//Indicates the P2P Beam UI is in idle mode.
public boolean isP2pIdle();
//此处还有两个回调,这两个CallBack是在P2pLinkManager中实现的
public interface Callback {
public void onP2pSendConfirmed();
public void onP2pCanceled();
}
}
class P2pLinkManager implements Handler.Callback, P2pEventListener.Callback {
......
//构造,创建了很多P2P通信需要的server
public P2pLinkManager(Context context, HandoverDataParser handoverDataParser, int
defaultMiu,
int defaultRwSize) {
//用于NdefPushServer:启动NPP Server,等待Client连接
mNdefPushServer = new NdefPushServer(NDEFPUSH_SAP, mNppCallback);
//用于启动SNPP Server,等待Client连接
mDefaultSnepServer = new SnepServer(mDefaultSnepCallback, defaultMiu, defaultRwSize);
//启动Handover Server,等待Client连接
mHandoverServer = new HandoverServer(context, HANDOVER_SAP, handoverDataParser,
mHandoverCallback);
......
//实例化P2pEventManager,用于将底层消息notify到UI或者上层APP
mEventListener = new P2pEventManager(context, this);
mHandler = new Handler(this);
......
}
//处理mHandler中的信息,底层处理完请求后会调用NativeNfcManager中相应回调,然后往外发消息。
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_START_ECHOSERVER:
...
case MSG_STOP_ECHOSERVER:
...
case MSG_WAIT_FOR_LINK_TIMEOUT:
...
case MSG_DEBOUNCE_TIMEOUT:
...
case MSG_RECEIVE_HANDOVER:
...
case MSG_RECEIVE_COMPLETE:
...
case MSG_HANDOVER_NOT_SUPPORTED:
...
case MSG_SEND_COMPLETE:
...
}
return true;
}
}
public void start() {
synchronized (this) {
if (mServerThread == null) {
mServerThread = new ServerThread();
mServerThread.start();
}
}
}
/** Server class, used to listen for incoming connection request */
class ServerThread extends Thread{
boolean mRunning = true;
LlcpServerSocket mServerSocket;
@Override
public void run() {
boolean threadRunning;
synchronized (NdefPushServer.this) {
threadRunning = mRunning;
}
while (threadRunning) {
try {
synchronized (NdefPushServer.this) {
//创建llcp服务端socket,根据所用的协议,填写不同的参数
mServerSocket = mService.createLlcpServerSocket(mSap, SERVICE_NAME,
MIU, 1, 1024);
}
......
synchronized (NdefPushServer.this) {
threadRunning = mRunning;
}
while (threadRunning) {
LlcpServerSocket serverSocket;
synchronized (NdefPushServer.this) {
serverSocket = mServerSocket;
}
......
//阻塞等待客户端连接,一个server端,可以有多个客户端连接
LlcpSocket communicationSocket = serverSocket.accept();
//每次client端连接都会创建新的thread,用于连接服务端.
if (communicationSocket != null) {
new ConnectionThread(communicationSocket).start();
}
synchronized (NdefPushServer.this) {
threadRunning = mRunning;
}
}
if (DBG) Log.d(TAG, "stop running");
} catch (LlcpException e) {
......
} finally {
......
mServerSocket.close();
}
}
}
......
}
/** Connection class, used to handle incoming connections */
private class ConnectionThread extends Thread {
private LlcpSocket mSock;
ConnectionThread(LlcpSocket sock) {
super(TAG);
mSock = sock;
}
@Override
public void run() {
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
byte[] partial = new byte[1024];
int size;
boolean connectionBroken = false;
//从远程服务端获取数据.
// Get raw data from remote server
while(!connectionBroken) {
try {
//把收到数据写入buffer
size = mSock.receive(partial);
......
buffer.write(partial, 0, size);
} catch (IOException e) {...}
}
//把接收到的数据转换成NDEF Message
// Build NDEF message set from the stream
NdefPushProtocol msg = new NdefPushProtocol(buffer.toByteArray());
if (DBG) Log.d(TAG, "got message " + msg.toString());
// Send the intent for the fake tag
//通过回调做进一步的对消息的处理.mCallback是最开始实例化的时候传入的mNppCallback
mCallback.onMessageReceived(msg.getImmediate());
} catch (FormatException e) {
.....
} finally {......}
}
}
final NdefPushServer.Callback mNppCallback = new NdefPushServer.Callback() {
@Override
public void onMessageReceived(NdefMessage msg) {
onReceiveComplete(msg);
}
};
void onReceiveComplete(NdefMessage msg) {
// Make callbacks on UI thread
mHandler.obtainMessage(MSG_RECEIVE_COMPLETE, msg).sendToTarget();
NfcIddEvent.Beam.Ndef.receive(msg);
}
//Manages vibration, sound and animation for P2P events.
public class P2pEventManager implements P2pEventListener, SendUi.Callback {
public P2pEventManager(Context context, P2pEventListener.Callback callback) {
mNfcService = NfcService.getInstance();
mContext = context;
mCallback = callback;
//实例化震动管理和通知管理。
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
......
//用于和UI界面交互,SendUi类实现了一些动画。
mSendUi = new SendUi(context, this);
主要函数如下:从名字也能看出大概意思,碰到相关BUG再详细分析.
public void onP2pInRange()
public void onP2pNfcTapRequested()
public void onP2pTimeoutWaitingForLink()
public void onP2pSendConfirmationRequested()
public void onP2pSendComplete()
public void onP2pHandoverNotSupported()
public void onP2pReceiveComplete(boolean playSound)
public void onP2pOutOfRange()
public void onSendConfirmed()
public void onCanceled()
public void onP2pSendDebounce()
public void onP2pResumeSend()
}
static {
System.loadLibrary("nfc_nci_jni");//对应于nci包下的jni的实现
}
//构造:
public native boolean initializeNativeStructure();
public NativeNfcManager(Context context, DeviceHostListener listener) {
mListener = listener;