});
程式碼 4.6 選擇顏色按鈕功能實作
4.3 翻牌遊戲
藍芽的普遍性與區網特性,也很適合用在遊戲上,讓兩人可以透過手機來對 戰,因此藉由本文的 NFC 藍芽連線模組,與同一個實驗室的莊惠迪同學所做的
NFC 翻牌遊戲結合,使其具有連線同步遊戲狀態的功能。
遊戲首先需要一個由許多 NFC 標籤構成的平面,每一個標籤內有著符號資 訊,見圖 4.3,遊戲一開始會先使用本文的方式建立藍芽連線,然後開始對戰,
讀取到某個標籤的時候,手機會顯示出該符號的圖案,如圖 4.4,找到一樣的符 號就可以得分,玩法與記憶遊戲相同,在遊戲時,敵人的分數會顯示在左上角,
讓雙方都清楚對方的分數,以增加氣氛的緊張度。
圖 4.3 使用 NFC 標籤所構成的遊戲平台
圖 4.4 翻牌遊戲介面
4.4 模組整合說明
前一節所介紹的遊戲,可以說明本研究所開發的模組是可以輕易整合進其他 應用的,本節將說明整合的方式與步驟。首先要先必須要先取得近場通訊、藍芽 和存取 SD 卡的權限,因此必須修改專案中的 AndroidManifest.xml,新增
<user-permission>元素。
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.NFC"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
接著,因為 SDK 到版本 10 才支援 NFC,所以要將最低 SDK 版本設為 10。
<uses-feature android:name="android.hardware.nfc" android:required="true" />
由於會使用到 Service 程式,所以也需要增加宣告,鍵入程式的名稱。
<service android:enabled="true" android:name=".BlueToothTransmissionService"
/>
最後新增連線的 Activity 程式,設為進去的第一個頁面,還有鎖定螢幕為垂 直即可,AndroidManifest.xml 的設定便到此完成,而該 Activity 程式為
nfc_btActivity.java,可參考附錄 D 修改為個人想要的功能。
<activity
android:label="@string/app_name"
android:name=".nfc_btActivity"
android:screenOrientation="portrait">
</activity>
連線後即可跳轉到自己的 Activity 程式,在需要藍芽的 Activity 上,僅需要 加上幾行與 Service 程式建立溝通的程式碼即可,首先是定義自己的
BroadcastReceiver 類別,有許多的即時狀態可讓開發者自行定義動作,也可自行 在 Service 程式新增動作或參數。
//定義 BroadcastReceiver 類別 BlueToothTransmissionReceiver 廣播接收程式 private class BlueToothTransmissionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent){
Bundle extra = intent.getExtras();
switch(extra.getInt(BlueToothTransmissionService.TYPE)){
Toast.makeText(getApplicationContext(),
case BlueToothTransmissionService.MESSAGE_LOST:
break;
接下來則是宣告 Service 程式相關變數,註冊 BroadcastReceiver 以及啟用
Service 程式和綁定(Bind),啟用的部分已經寫入 setup 函式,在 onCreate 啟用即 可,需要注意的是,Service 在 Bind 後,需要約 1 秒鐘才能使用,否則會有錯誤,
所以若有要及時使用 Server 的部分需要延遲 1 秒後再執行,最後只要將相關檔
//宣告 Service 程式
private BlueToothTransmissionService blueToothTransmissionService = null;
//宣告 BroadcastReceiver 程式 receiver
private final BlueToothTransmissionReceiver receiver = new BlueToothTransmissionReceiver();
//宣告 ServiceConnection 程式 serviceConnection
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
blueToothTransmissionService =
((BlueToothTransmissionService.BlueToothTransmissionBinder)service).getService()
; }
public void onServiceDisconnected(ComponentName className) { blueToothTransmissionService = null;
} };
public void setup(){
//服動服務程式 KitchenTimerService
intent = new Intent(this, BlueToothTransmissionService.class);
startService(intent);
//註冊廣播接收 receiver
filter = new IntentFilter(BlueToothTransmissionService.ACTION);
registerReceiver(receiver, filter);
//綁縛(Bind)服務程式 KitchenTimerService
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
第5章 結論與未來發展
5.1 結論
本研究提出使用 NFC Peer to Peer 模式來建立藍芽連線的方法,讓使用者可 以在不需要了解藍芽連線先備知識的前提下,輕鬆地建立藍芽連線,較傳統方式 節省 52%連線時間,並且發展出一個簡單的方法透過藍芽來傳輸檔案,可以暫時 解決官方 SDK 無提供檔案傳輸方式的問題,測試結果其速度約 16KB/秒,以及 測試 NFC P2P 的傳輸速率並與本文的藍芽傳輸速率做比較,了解到在傳輸量小 於 4KB 時,使用 NFC P2P 傳輸的實際花費時間比使用藍芽還要少,較輕量的文 件皆能使用 NFC P2P 傳送即可,而需要長時間連續通訊的部分則是使用藍芽。
再提出連線方法後,本研究也提出兩個簡單的應用,和一個與其它應用結合 的例子,分別是 Child Guard、Draw Together 和翻牌遊戲,第一個應用是在建立 藍芽連線後,將手機放在小孩身上,倘若小孩的距離超過藍芽的連線範圍,約
10 公尺,便會發出警告聲以提醒家長,途中若家長看不見小孩,亦可按下呼叫 鍵來讓小孩的手機發出警告聲,顯示其位置。第二個應用是讓兩個使用者可以共 同使用同一個畫布繪畫,在一方畫完後,按下換人紐,會將畫布以藍芽傳送到對 方的手機上,可以用此來接力畫畫或者完基本的紙上遊戲。第三個例子是與實驗 室同學莊惠迪所做的 NFC 翻牌遊戲結合,讓遊戲的即時狀況可以同步顯示在使
5.2 未來發展
雖然結合了 NFC 來使藍芽的連線更為簡便,可是連線速度卻因為 Android 官方的 SDK 沒有提供,無法使用原生的藍芽協定傳輸檔案,造成傳輸速率不高 的問題,也間接地限制了應用的發展,不過,目前已有發現 Google Play 上的藍 芽傳檔軟體,Bluetooth File Transfer,能夠支援原生協定,並且能與電腦建立連 線,檔案傳輸速率達到約 120KB/秒,若能了解其實作方式,便能發揮藍芽應有 的效能,也可以進一步擴充到與桌上型或筆記型電腦上的應用。
另外,NFC Forum 並未訂出統一的編號來表示 NFC 對應的不同動作,各家 都是自己使用自己的編號,所以有人提出自己的服務框架[21],但是都仍然無法 相容使用,若 NFC Forum 有訂出相關的標準,Android 作業系統將可以自行對應 到不同的動作,而支援度也會比較好。
儘管藍芽提供 1 對 7 的連線,但 SDK 同樣也未說明相關的部分,若能使用 多人連線,便能開發出更多互動的應用,與社群方面的應用,真正實踐個人區域 網路的功能。
目前市面上的 NFC 手機並不多,因此普遍性並不高,以至於即使開發出許 多 NFC 的應用,仍舊沒有可以使用的環境,所以若能將本文的連線方式,運用 二維條碼的方式,由一端產生出二維條碼,並將連線資訊放入其中,而另一端讀 取後,自動開始建立連線,同樣可以使沒有 NFC 手機的人一樣享受到藍芽的便 利。
參考著作
[1]. ECMA International NFC White Paper
http://www.ecma-international.org/activities/Communications/tc32-tg19-2005-01 2.pdf
[2]. Charl A. Opperman, Gerhard P. Hancke, “Using NFC-enabled Phones for Remote Data Acquisition and Digital Control”, “AFRICON, 2011”, Sept 2011 [3]. Weihua Pan, Fucai Luo, Lei Xu, “Reserch and design of chatting room system
based on Android Bluetooth”, “Consumer Electronics, Communications and Networks (CECNet), 2012 2nd International Conference on”, April 2012.
[4]. Chiu-Chiao Chung, Ching Yuan Huang, Shiau-Chin Wang, Cheng-Min Lin, ” Bluetooth-based Android Interactive Applications for Smart Living”,
“Innovations in Bio-inspired Computing and Applications (IBICA), 2011 Second International Conference on”, Dec 2011
[5]. Wu, Shyi-Shiou, Wu, Hsin-Yi, “The Design of an Intelligent Pedometer using Android”, “Innovations in Bio-inspired Computing and Applications (IBICA), 2011 Second International Conference on”, Dec 2011
[6]. Josh Potts, Somsak Sukittanon, “Exploiting Bluetooth on Android Mobile Devices for Home Security Application”, “Southeastcon, 2012 Proceedings of IEEE”, March 2012
[7]. Brad Boone, Chris Hayes, Corey Darr, Dale Musser, “Using Bluetooth on Android Devices to Implement Real-Time Multiplayer Games”,
“http://people.cs.missouri.edu/~reu/REU11/adhocgaming/”, July 2011
[8]. Leong, C.Y., Ong, K.C., Tan, K.K., Gan, O.P., “Near Field Communication and Bluetooth Bridge System”, “Industrial Informatics, 2006 IEEE International Conference on”, Aug 2006
[9]. 花珀 Dongle, http://flower.emome.net/product-dongle.html
[10]. Burden, M., “Near Field Communications in Public Transport”, “RFID and Electronic Vehicle Identification in Road Transport, 2006. The Instititon of Engineering and Technology Seminar on”, Nov 2006.
[11]. Ben Dodson Monica S. Lam., “P2P Micro-Interactions with NFC-enabled Mobile Phones”, “MobiCASE 2011”, Oct 2011
[12]. Cihan KURNAZ, “ADD-ON APPLICATIONS FOR ANDROID”, “Ayça SANİN”, June 2008
[15]. Yun-Cheng Chen, “Mobile Navigation Service by Bluetooth Protocol”, July 2005
[16]. N. Golmie, “Bluetooth Dynamic Scheduling and Interference Mitigation”,
“Journal Mobile Networks and Applications”, Feb 2004.
[17]. Android Developers. (2011, Feb.). Android 2.3.3 platform (rev. 1). [Online].
Available: http://developer.android.com/sdk/android-2.3.3.html [18]. NFC Forum, “NFC Data Exchange Format”,
http://www.maintag.fr/fichiers/pdf-fr/nfcforum-ts-ndef-1-0.pdf
[19]. NFC Forum, “NFC Record Type Definition”,https://engineering.purdue.edu/477grp14/Specs/NFC/NFCRTD.pdf
[20]. Apache Base64 encoding and decoding:http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Ba se64.html
[21]. 陳宏志,近場通訊之萬用服務框架, 2009 年 6 月
[22]. Behrouz A. Forouzan, “Data Communications and Networking, 4e”
附錄
附錄A. 系統第一層與第二層 class diagram
附錄B. 系統係二層與第三層 class diagram〈一〉
附錄C. 系統第二層與第三層 class diagram〈二〉
附錄D. 連線程式 nfc_btActivity.java
public class nfc_btActivity extends Activity { private String text = "";
private String target = "";
private BluetoothAdapter mBluetoothAdapter = null;
private TextView mText;
private Bundle extras;
//定義 BroadcastReceiver 類別 BlueToothTransmissionReceiver 廣播接收程式 private class BlueToothTransmissionReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent){
Bundle extra = intent.getExtras();
switch(extra.getInt(BlueToothTransmissionService.TYPE)){
case BlueToothTransmissionService.MESSAGE_STATE_CHANGE:
switch(extra.getInt(BlueToothTransmissionService.CONTENT)){
case BlueToothTool.STATE_CONNECTED:
break;
}
break;
case BlueToothTransmissionService.MESSAGE_READ:
break;
case BlueToothTransmissionService.MESSAGE_LOST:
Toast.makeText(getApplicationContext(),
extra.getCharSequence(BlueToothTransmissionService.CONTENT), Toast.LENGTH_SHORT).show();
break;
case BlueToothTransmissionService.MESSAGE_WRITE:
break;
case BlueToothTransmissionService.MESSAGE_CONTENT:
Toast.makeText(getApplicationContext(),
extra.getCharSequence(BlueToothTransmissionService.CONTENT),
private BlueToothTransmissionService blueToothTransmissionService = null;
//宣告 BroadcastReceiver 程式 receiver
private final BlueToothTransmissionReceiver receiver = new BlueToothTransmissionReceiver();
//宣告 ServiceConnection 程式 serviceConnection
private ServiceConnection serviceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) {
blueToothTransmissionService =
((BlueToothTransmissionService.BlueToothTransmissionBinder)service).getService()
;
}
public void onServiceDisconnected(ComponentName className) { blueToothTransmissionService = null;
}
};
@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); public void onClick(View view) {
startActivity(new Intent(nfc_btActivity.this, transFileBT.class));
} });
trans_file_NFC_button = (Button)findViewById(R.id.button1);
trans_file_NFC_button.setOnClickListener(new OnClickListener() { public void onClick(View view) {
startActivity(new Intent(nfc_btActivity.this, transFileNFC.class));
} });
message_button = (Button)findViewById(R.id.button4);
message_button.setOnClickListener(new OnClickListener() { public void onClick(View view) {
startActivity(new Intent(nfc_btActivity.this, message.class));
} });
childCare = (Button)findViewById(R.id.button5);
childCare.setOnClickListener(new OnClickListener() { public void onClick(View view) {
startActivity(new Intent(nfc_btActivity.this, childCare.class));
}
draw_button.setOnClickListener(new OnClickListener() { public void onClick(View view) {
startActivity(new Intent(nfc_btActivity.this, draw.class));
}
NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT , new byte[0],btMac.getBytes());
/*要支援 push, 只需要在 onResume 時使用 enableForegroundNdefPush 就可以了*/
manager.getDefaultAdapter().enableForegroundNdefPush(this, new NdefMessage(new NdefRecord[]{rec}));
//get nfc message
manager.getDefaultAdapter().enableForegroundDispatch(this, PendingIntent.getActivity(this, 0,new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0), new IntentFilter[] {ndef, },
NfcManager manager = (NfcManager) getSystemService(NFC_SERVICE);
manager.getDefaultAdapter().disableForegroundNdefPush(this);
//結束時要交還資訊,Unbind Service, Unregister Receiver, Stop Service blueToothTransmissionService.stopSelf(); //Stop Service }
}
public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
if(blueToothTransmissionService.getState() !=
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
} }