前情提要:
上一篇提到很多工作都在 BeamTransferManafer
裡面完成的,
那我們就先來看一下第一個通知 updateNotification
:
packages/apps/Nfc/src/com/android/nfc/beam/BeamTransferManager.java
302 void updateNotification() {
... ...
309 String beamString;
**//下面判斷是往外發送還是接受的,此處我們分析的是發送的。(看接受的是不是從HandoverServer)**
310 if (mIncoming) {
311 beamString = mContext.getString(R.string.beam_progress);
312 } else {
313 beamString = mContext.getString(R.string.beam_outgoing);
314 }
**//第一次的時候mState == STATE_NEW在構造中進行的實例化**
315 if (mState == STATE_NEW || mState == STATE_IN_PROGRESS ||
316 mState == STATE_W4_NEXT_TRANSFER || mState == STATE_W4_MEDIA_SCANNER) {
317 notBuilder.setAutoCancel(false);
318 notBuilder.setSmallIcon(mIncoming ? android.R.drawable.stat_sys_download :
319 android.R.drawable.stat_sys_upload);
320 notBuilder.setTicker(beamString);
321 notBuilder.setContentTitle(beamString);
322 notBuilder.addAction(R.drawable.ic_menu_cancel_holo_dark,
323 mContext.getString(R.string.cancel), mCancelIntent);
**//下面就是處理進度條顯示的問題**
324 float progress = 0;
325 if (mTotalCount > 0) {
326 float progressUnit = 1.0f / mTotalCount;
327 progress = (float) mCurrentCount * progressUnit + mProgress * progressUnit;
328 }
329 if (mTotalCount > 0 && progress > 0) {
330 notBuilder.setProgress(100, (int) (100 * progress), false);
331 } else {
332 notBuilder.setProgress(100, 0, true);
333 }
**//傳輸成功的時候**
334 } else if (mState == STATE_SUCCESS) {
335 notBuilder.setAutoCancel(true);
... ...
**//傳輸失敗的時候**
349 } else if (mState == STATE_FAILED) {
350 notBuilder.setAutoCancel(false);
... ...
**//傳輸取消的時候**
355 } else if (mState == STATE_CANCELLED || mState == STATE_CANCELLING) {
356 notBuilder.setAutoCancel(false);
... ...
361 } else {
362 return;
363 }
364
**//這裡把不同的顯示結果提示出去即可**
365 mNotificationManager.notify(null, mTransferId, notBuilder.build());
366 }
再來就是上一篇一直提到的 BeamTransferManager
的 start()
的部份:
packages/apps/Nfc/src/com/android/nfc/beam/BeamTransferManager.java
191 public void start() {
... ...
**//往外傳輸的時候**
199 if (!mIncoming) {
**//通過藍芽傳輸的時候**
200 if (mDataLinkType == BeamTransferRecord.DATA_LINK_TYPE_BLUETOOTH) {
**//傳入Handoverserver後返回的NDEF消息用於和本地藍牙配對鏈接等**
201 new **BluetoothOppHandover(mContext, mRemoteDevice, mUris, mRemoteActivating).start()**;
202 }
203 }
204 }
再來跳到 BluetoothOppHandover
的 start()
部份:
packages/apps/Nfc/src/com/android/nfc/beam/BluetoothOppHandover.java
77 public void start() {
78 if (mRemoteActivating) {
79 Long timeElapsed = SystemClock.elapsedRealtime() - mCreateTime;
80 if (timeElapsed < REMOTE_BT_ENABLE_DELAY_MS) {
81 mHandler.sendEmptyMessageDelayed(MSG_START_SEND,
82 REMOTE_BT_ENABLE_DELAY_MS - timeElapsed);
83 } else {
84 // Already waited long enough for BT to come up
85 // - start send.
86 **sendIntent()**;
87 }
88 } else {
89 // Remote BT enabled already, start send immediately
90 **sendIntent()**;
91 }
92 }
packages/apps/Nfc/src/com/android/nfc/beam/BluetoothOppHandover.java
98 void sendIntent() {
99 Intent intent = new Intent();
100 intent.setPackage(mContext.getString(R.string.bluetooth_package));
101 String mimeType = MimeTypeUtil.getMimeTypeForUri(mContext, mUris.get(0));
102 intent.setType(mimeType);
103 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
104 for (Uri uri : mUris) {
105 // TODO we need to transfer our permission grant from NFC
106 // to the Bluetooth process. This works, but we don't have
107 // a good framework API for revoking permission yet.
108 try {
109 mContext.grantUriPermission(mContext.getString(R.string.bluetooth_package), uri,
110 Intent.FLAG_GRANT_READ_URI_PERMISSION);
111 } catch (SecurityException e) {
112 Log.e(TAG, "Failed to transfer permission to Bluetooth process.");
113 }
114 }
115 if (mUris.size() == 1) {
116 intent.setAction(ACTION_HANDOVER_SEND);
117 intent.putExtra(Intent.EXTRA_STREAM, mUris.get(0));
118 } else {
119 intent.setAction(ACTION_HANDOVER_SEND_MULTIPLE);
120 intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, mUris);
121 }
122 if (DBG) Log.d(TAG, "Handing off outging transfer to BT");
123 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
124 mContext.sendBroadcast(intent);
125
126 complete();
127 }
到此我們就完成了 NFC 端的發送廣播和 BT 通信去完成最終的數據傳輸,
一旦開始傳輸,BT 就會在每個傳輸的階段發送廣播給 NFC 的應用,
以便 NFC 應用可以更新通知的顯示。
後面相對地有點無趣,就不去介紹了。
再來下一篇就繼續把 Kernel 的部份講完吧,
NFC 系列就先暫時這樣了。