NFC学习——NFC Enable 过程分析(一)

6 篇文章 0 订阅

  拿到一台支持NFC手机或是平板设备时,在Settings->more可以看到NFC的enble,disnable的选项,还有android Beam这个东西。现在来分析NFC enable的过程   

          wireless_settings.xml 在Settings配置了NFC功能项:

[html]  view plain copy
  1. <CheckBoxPreference  
  2.     android:key="toggle_nfc"  
  3.     android:title="@string/nfc_quick_toggle_title"  
  4.     android:summary="@string/nfc_quick_toggle_summary"  
  5.     android:persistent="false" />  
  6.   
  7. <PreferenceScreen  
  8.     android:fragment="com.android.settings.nfc.AndroidBeam"  
  9.     android:key="android_beam_settings"  
  10.     android:title="@string/android_beam_settings_title" />  
         xml配置的对应处理代码在:packages/apps/Settings/src/com/android/settings/WirelessSettings.java

[html]  view plain copy
  1. public void onCreate(Bundle savedInstanceState) {  
  2.         super.onCreate(savedInstanceState);  
  3.   
  4.         addPreferencesFromResource(R.xml.wireless_settings);   
  5.         CheckBoxPreference nfc = (CheckBoxPreference) findPreference(KEY_TOGGLE_NFC);  
  6.         PreferenceScreen androidBeam = (PreferenceScreen) findPreference(KEY_ANDROID_BEAM_SETTINGS);   
  7.   
  8.         //setp1:获取NfcEnable的实例  
  9.         mNfcEnabler = new NfcEnabler(activity, nfc, androidBeam);   
  10.         ......  
  11.   
  12.         // Remove NFC if its not available              
  13.         //setp2:获取NfcAdapter实例,查看NFC功能是否可能  
  14.         mNfcAdapter = NfcAdapter.getDefaultAdapter(activity);  
  15.         if (mNfcAdapter == null) {  
  16.             getPreferenceScreen().removePreference(nfc);  
  17.             getPreferenceScreen().removePreference(androidBeam);  
  18.             mNfcEnabler = null;  
  19.         }   
  20.  }  

setp1:NFcEnable实例 packages/apps/Settings/src/com/android/settings/nfc/NfcEnabler.java 实现Preference.OnPreferenceChangeListener接口监听NFC Enable,disnable事件

[html]  view plain copy
  1. public boolean onPreferenceChange(Preference preference, Object value) {  
  2.         // Turn NFC on/off  
  3.   
  4.         final boolean desiredState = (Boolean) value;  
  5.         mCheckbox.setEnabled(false);  
  6.   
  7.         if (desiredState) {             
  8.            //setp3:用setp2一样的方式获取NfcAdapter实例出来nfc enable  
  9.             mNfcAdapter.enable();  
  10.         } else {  
  11.             mNfcAdapter.disable();  
  12.         }  
  13.   
  14.         return false;  
  15.     }  
         同时也是在这个NfcEnabler.java中处理了,Nfc enble,diable时,android beam的灰亮显示问题。

Setp2:现在所有的分析点集中到了NfcAdaper这个类中,首先来看下NfcAdapter实例的获取

源代码的路径:frameworks/base/core/java/android/nfc/NfcAdapter.java

[html]  view plain copy
  1.     public static NfcAdapter getDefaultAdapter(Context context) {   
  2.           ......    
  3.   
  4.        /* use getSystemService() for consistency */  
  5.         NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);  
  6.         if (manager == null) {  
  7.             // NFC not available  
  8.             return null;  
  9.         }            
  10.         //setp2-1  
  11.         return manager.getDefaultAdapter();  
  12.     }  
NFC学习——NfcService 启动过程分析   文章中NfcService的onCreate()方法中有如下code:

[html]  view plain copy
  1.  //把mNfcAdapter 作为Service 添加到系统服务中,ServiceManager.getService("nfc")可以获取到binder   
  2.  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

[html]  view plain copy
  1. public NfcAdapter getDefaultAdapter() {  
  2.         return mAdapter;  
  3.     }  
这个mAdaper如何来的呢?

[html]  view plain copy
  1.     public NfcManager(Context context) {  
  2.         NfcAdapter adapter;  
  3.         ......  
  4.          try {  
  5.             adapter = NfcAdapter.getNfcAdapter(context);  
  6.         } catch (UnsupportedOperationException e) {  
  7.             adapter = null;  
  8.         }  
  9.         mAdapter = adapter;  
  10.     }  
最终又回到NfcAdapter.gerNfcAdapter(context)这个方法上获取实例,具体来分析:

[html]  view plain copy
  1.   public static synchronized NfcAdapter getNfcAdapter(Context context) {  
  2.         if (!sIsInitialized) {  
  3.             ......  
  4.             //setp2-2:应用INfcAdapter.aidl和NfcService通信   
  5.             sService = getServiceInterface();  
  6.             if (sService == null) {  
  7.                 Log.e(TAG, "could not retrieve NFC service");  
  8.                 throw new UnsupportedOperationException();  
  9.             }  
  10.             try {   
  11.                 //note2  
  12.                 sTagService = sService.getNfcTagInterface();  
  13.             } catch (RemoteException e) {  
  14.                 Log.e(TAG, "could not retrieve NFC Tag service");  
  15.                 throw new UnsupportedOperationException();  
  16.             }  
  17.   
  18.             sIsInitialized = true;  
  19.         }  
  20.         if (context == null) {  
  21.             if (sNullContextNfcAdapter == null) {  
  22.                 sNullContextNfcAdapter = new NfcAdapter(null);  
  23.             }  
  24.             return sNullContextNfcAdapter;  
  25.         }                
  26.         //sNFcAdapter 是个HashMap,从中取出之前创建的NfcAdapter实例  
  27.         NfcAdapter adapter = sNfcAdapters.get(context);  
  28.         if (adapter == null) {  
  29.             adapter = new NfcAdapter(context);  
  30.             sNfcAdapters.put(context, adapter);  
  31.         }  
  32.         return adapter;  
  33.     }  
          Setp2-2:应用INfcAdapter.aidl和NfcService通信 ,INfcAdapter的方法都在NfcService的内部类NfcAdapterService中实现。

[html]  view plain copy
  1. /** get handle to NFC service interface */  
  2. private static INfcAdapter getServiceInterface() {  
  3.     /* get a handle to NFC service */  
  4.     IBinder b = ServiceManager.getService("nfc");  
  5.     if (b == null) {  
  6.         return null;  
  7.     }  
  8.     return INfcAdapter.Stub.asInterface(b);  
  9. }  
现在Setp2的NfcAdapter已经得到了它的实例,接下来就Setp3,NfcAdapter.enable()和NfcAdapter.disable():

[html]  view plain copy
  1.     public boolean enable() {  
  2.         try {   
  3.             //从setp2-2可以知道sService.enable()通过NfcAdapterService来实现的  
  4.             return sService.enable();  
  5.         } catch (RemoteException e) {  
  6.             attemptDeadServiceRecovery(e);  
  7.             return false;  
  8.         }  
  9.     }  
接下来看NfcAdapterService extends INfcAdapter.Stub 中的enable()方法:

[html]  view plain copy
  1. public boolean enable() throws RemoteException {              
  2.       //Question 1:  
  3.       NfcService.enforceAdminPerm(mContext);  
  4.       //把NFC 打开状态写到SharedPreferences中保存起来  
  5.       saveNfcOnSetting(true);               
  6.       ......     
  7.       //AsyncTash后台处理NFC的打开        
  8.       new EnableDisableTask().execute(TASK_ENABLE);  
  9.       return true;  
  10. }  

上面code 提到一个Question 1,其实它就是给NFC 赋予一个写的权限。

EnableDisableTask 在doInBackground中调用enableInternal();来处理NFC  turn on。

[html]  view plain copy
  1.  boolean enableInternal() {   
  2.             //logcat 信息可以看到的log信息  
  3.             Log.i(TAG, "Enabling NFC");  
  4.             updateState(NfcAdapter.STATE_TURNING_ON);                     
  5.             //setp3-1:调用jni initialize做init相关的动作  
  6.             if (!mDeviceHost.initialize()) {  
  7.                 Log.w(TAG, "Error enabling NFC");  
  8.                 updateState(NfcAdapter.STATE_OFF);  
  9.                 return false;  
  10.             }  
  11.             synchronized(NfcService.this) {  
  12.                 mObjectMap.clear();   
  13.                 //setp 3-2:开启一些循环监听的线程服务  
  14.                 mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true);  
  15.                 updateState(NfcAdapter.STATE_ON);  
  16.             }  
  17.   
  18.             initSoundPool();  
  19.   
  20.             /* Start polling loop */  
  21.             applyRouting(true);//开始扫描查询tag和P2p设备   
  22.            return true;  
  23.         }  

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 过程分析(三)   分析   

以上部分的分析配合下面这张图就更清晰了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值