NFC学习——NFC Enable 过程分析(一)
来源:互联网 发布:张宇和陈奕迅 知乎 编辑:程序博客网 时间:2024/06/01 08:41
拿到一台支持NFC手机或是平板设备时,在Settings->more可以看到NFC的enble,disnable的选项,还有android Beam这个东西。现在来分析NFC enable的过程
wireless_settings.xml 在Settings配置了NFC功能项:
<CheckBoxPreference android:key="toggle_nfc" android:title="@string/nfc_quick_toggle_title" android:summary="@string/nfc_quick_toggle_summary" android:persistent="false" /> <PreferenceScreen android:fragment="com.android.settings.nfc.AndroidBeam" android:key="android_beam_settings" android:title="@string/android_beam_settings_title" />xml配置的对应处理代码在:packages/apps/Settings/src/com/android/settings/WirelessSettings.java
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.wireless_settings); CheckBoxPreference nfc = (CheckBoxPreference) findPreference(KEY_TOGGLE_NFC); PreferenceScreen androidBeam = (PreferenceScreen) findPreference(KEY_ANDROID_BEAM_SETTINGS); //setp1:获取NfcEnable的实例 mNfcEnabler = new NfcEnabler(activity, nfc, androidBeam); ...... // Remove NFC if its not available //setp2:获取NfcAdapter实例,查看NFC功能是否可能 mNfcAdapter = NfcAdapter.getDefaultAdapter(activity); if (mNfcAdapter == null) { getPreferenceScreen().removePreference(nfc); getPreferenceScreen().removePreference(androidBeam); mNfcEnabler = null; } }
setp1:NFcEnable实例 packages/apps/Settings/src/com/android/settings/nfc/NfcEnabler.java 实现Preference.OnPreferenceChangeListener接口监听NFC Enable,disnable事件
public boolean onPreferenceChange(Preference preference, Object value) { // Turn NFC on/off final boolean desiredState = (Boolean) value; mCheckbox.setEnabled(false); if (desiredState) { //setp3:用setp2一样的方式获取NfcAdapter实例出来nfc enable mNfcAdapter.enable(); } else { mNfcAdapter.disable(); } return false; }同时也是在这个NfcEnabler.java中处理了,Nfc enble,diable时,android beam的灰亮显示问题。
Setp2:现在所有的分析点集中到了NfcAdaper这个类中,首先来看下NfcAdapter实例的获取
源代码的路径:frameworks/base/core/java/android/nfc/NfcAdapter.java
public static NfcAdapter getDefaultAdapter(Context context) { ...... /* use getSystemService() for consistency */ NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE); if (manager == null) { // NFC not available return null; } //setp2-1 return manager.getDefaultAdapter(); }在NFC学习——NfcService 启动过程分析 文章中NfcService的onCreate()方法中有如下code:
//把mNfcAdapter 作为Service 添加到系统服务中,ServiceManager.getService("nfc")可以获取到binder ServiceManager.addService(SERVICE_NAME, mNfcAdapter);NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);获取到的Service 就是之前add的service。
Setp2-1:manager.getDefaultAdapter其实饶了一圈又回到NfcAdapter类中获取NfcAdapter实例,具体看下面code
code路径:frameworks/base/core/java/android/nfc/NfcManager.java
public NfcAdapter getDefaultAdapter() { return mAdapter; }这个mAdaper如何来的呢?
public NfcManager(Context context) { NfcAdapter adapter; ...... try { adapter = NfcAdapter.getNfcAdapter(context); } catch (UnsupportedOperationException e) { adapter = null; } mAdapter = adapter; }最终又回到NfcAdapter.gerNfcAdapter(context)这个方法上获取实例,具体来分析:
public static synchronized NfcAdapter getNfcAdapter(Context context) { if (!sIsInitialized) { ...... //setp2-2:应用INfcAdapter.aidl和NfcService通信 sService = getServiceInterface(); if (sService == null) { Log.e(TAG, "could not retrieve NFC service"); throw new UnsupportedOperationException(); } try { //note2 sTagService = sService.getNfcTagInterface(); } catch (RemoteException e) { Log.e(TAG, "could not retrieve NFC Tag service"); throw new UnsupportedOperationException(); } sIsInitialized = true; } if (context == null) { if (sNullContextNfcAdapter == null) { sNullContextNfcAdapter = new NfcAdapter(null); } return sNullContextNfcAdapter; } //sNFcAdapter 是个HashMap,从中取出之前创建的NfcAdapter实例 NfcAdapter adapter = sNfcAdapters.get(context); if (adapter == null) { adapter = new NfcAdapter(context); sNfcAdapters.put(context, adapter); } return adapter; }Setp2-2:应用INfcAdapter.aidl和NfcService通信 ,INfcAdapter的方法都在NfcService的内部类NfcAdapterService中实现。
/** get handle to NFC service interface */ private static INfcAdapter getServiceInterface() { /* get a handle to NFC service */ IBinder b = ServiceManager.getService("nfc"); if (b == null) { return null; } return INfcAdapter.Stub.asInterface(b); }现在Setp2的NfcAdapter已经得到了它的实例,接下来就Setp3,NfcAdapter.enable()和NfcAdapter.disable():
public boolean enable() { try { //从setp2-2可以知道sService.enable()通过NfcAdapterService来实现的 return sService.enable(); } catch (RemoteException e) { attemptDeadServiceRecovery(e); return false; } }接下来看NfcAdapterService extends INfcAdapter.Stub 中的enable()方法:
public boolean enable() throws RemoteException { //Question 1: NfcService.enforceAdminPerm(mContext); //把NFC 打开状态写到SharedPreferences中保存起来 saveNfcOnSetting(true); ...... //AsyncTash后台处理NFC的打开 new EnableDisableTask().execute(TASK_ENABLE); return true;}
上面code 提到一个Question 1,其实它就是给NFC 赋予一个写的权限。
EnableDisableTask 在doInBackground中调用enableInternal();来处理NFC turn on。
boolean enableInternal() { //logcat 信息可以看到的log信息 Log.i(TAG, "Enabling NFC"); updateState(NfcAdapter.STATE_TURNING_ON); //setp3-1:调用jni initialize做init相关的动作 if (!mDeviceHost.initialize()) { Log.w(TAG, "Error enabling NFC"); updateState(NfcAdapter.STATE_OFF); return false; } synchronized(NfcService.this) { mObjectMap.clear(); //setp 3-2:开启一些循环监听的线程服务 mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true); updateState(NfcAdapter.STATE_ON); } initSoundPool(); /* Start polling loop */ applyRouting(true);//开始扫描查询tag和P2p设备 return true; }
setp3-1:initialize()对应的是在NativeNfcManager.java 中initialize()实现的,NativeNfcManager.initialize()直接调用的是jni方法doInitialize(),doInitialize()对应的在jni的方法:com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o),这部分将在NFC学习——NFC Enable 过程分析(二) 分析。
setp3-2:这一部分将在NFC学习——NFC Enable 过程分析(三) 分析
以上部分的分析配合下面这张图就更清晰了
以上图片来自:NFC framework introduce(一)
- NFC学习——NFC Enable 过程分析(一)
- NFC学习——NFC Enable 过程分析(一)
- NFC学习——NFC Enable 过程分析(一)
- NFC学习——NFC Enable 过程分析(二)
- NFC学习——NFC Enable 过程分析(三)
- NFC学习——NFC Enable 过程分析(三)
- NFC Enable 过程分析(三)
- NFC学习——NfcService 启动过程分析
- NFC学习——NfcService 启动过程分析
- NFC 启动和enable 过程
- NFC学习记录一
- NFC学习——准备
- NFC学习——准备
- NFC——学习准备
- android NFC学习笔记(一)
- android NFC学习笔记(一)
- android NFC学习笔记(一)
- android NFC学习笔记(一)
- Tomcat7 Applet 访问Servlet Session失效
- Microsoft .Net Remoting系列专题之一:.Net Remoting基础篇
- Linux安装JDK详细步骤
- Dijkstra算法
- 创业篇(1)____坚守底线方能美梦成真
- NFC学习——NFC Enable 过程分析(一)
- [ php ] php smarty使用!
- 设计模式总结—工厂三姐妹
- Linux Vim替换字符串的方法总结
- 如何理解oracle的锁
- Microsoft .Net Remoting系列专题之二:Marshal、Disconnect与生命周期以及跟踪服务
- android 正在运行的activity和services
- computer vision:algorithm and application计算机视觉算法与应用 这本书中附录里关于计算机视觉的一些测试数据集和源码站点
- sql 语句 in 注意事项