1.Bluetooth基本概念

 

可以參考
BlueCove這個實作JSR82的Project,裡面的
這張圖對Bluetooth解說很清楚,可供參考。

 

Bluetooth Stack的部份在不同系統、程式語言上都是相同的,會有差異的只有頂層的Abstract API。

 

若想對Bluetooth整體軟硬體有仔細的瞭解可以參考「Bluetooth Application Programming with the JAVA APIs Essentials Edition」這本書。

 

2.Android Bluetooth開發基本需求

 

Android SDK 2.0以上(含2.0)版本。

 

支援Android 2.0的手機一隻(Android Emulater無法類比Bluetooth,所以一定要有實體手機)。

 

3.實作參考檔


 

HTTP://developer.android.com/guide/topics/wireless/bluetooth.html


 

HTTP://www.anddev.org/serial_over_bluetooth_simple_test_client-t11106.html

 

一 般來說,我們只會實作Bluetooth Client的程式去跟其它的Bluetooth硬體溝通取資料。連線方式大多是利用Serial Port Service方式去跟遠端的裝置溝通,所以相對應的UUID不能設錯,一定要設成下述範例這組UUID,不然會發生找不到Service的問題(附帶一 提,這是假設一般遠端裝置有提供Serial Port Service,所以你才可以用這組UUID來進行通訊,如果遠端裝置比較特別就要去查硬體規格去看它提供的Service是哪些,找出對應的 UUID)。


 

1



 

private static final UUID SERIAL_PORT_SERVICE_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");


 

4.Android Bluetooth API目前的限制

 

目前只支援RFCOMM的方式進行通訊

 

5.實作參考範例


 

// 取自HTTP://www.anddev.org/serial_over_bluetooth_simple_test_client-t11106.html裡的範例
package com.example.thinbtclient;

 

import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

 

public class ThinBTClient extends Activity {

 

private static final String TAG = "THINBTCLIENT";
private static final boolean D = true;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
// Well known SPP UUID (will *probably* map to
// RFCOMM channel 1 (default) if not in use);
// see comments in onResume().
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

 

// ==> hardcode your server's MAC address here <==
private static String address = "XX:XX:XX:XX:XX:XX";

 

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

 

if (D)
Log.e(TAG, "+++ ON CREATE +++");

 

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this,
"Bluetooth is not available.",
Toast.LENGTH_LONG).show();
finish();
return;
}

 

if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(this,
"Please enable your BT and re-run this program.",
Toast.LENGTH_LONG).show();
finish();
return;
}

 

if (D)
Log.e(TAG, "+++ DONE IN ON CREATE, GOT LOCAL BT ADAPTER +++");
}

 

@Override
public void onStart() {
super.onStart();
if (D)
Log.e(TAG, "++ ON START ++");
}

 

@Override
public void onResume() {
super.onResume();

 

if (D) {
Log.e(TAG, "+ ON RESUME +");
Log.e(TAG, "+ ABOUT TO ATTEMPT CLIENT CONNECT +");
}

 

// When this returns, it will 'know' about the server,
// via it's MAC address.
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);

 

// We need two things before we can successfully connect
// (authentication issues aside): a MAC address, which we
// already have, and an RFCOMM channel.
// Because RFCOMM channels (aka ports) are limited in
// number, Android doesn't allow you to use them directly;
// instead you request a RFCOMM mapping based on a service
// ID. In our case, we will use the well-known SPP Service
// ID. This ID is in UUID (GUID to you Microsofties)
// format. Given the UUID, Android will handle the
// mapping for you. Generally, this will return RFCOMM 1,
// but not always; it depends what other BlueTooth services
// are in use on your Android device.
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Socket creation failed.", e);
}
 
// Discovery may be going on, e.g., if you're running a
// 'scan for devices' search from your handset's Bluetooth
// settings, so we call cancelDiscovery(). It doesn't hurt
// to call it, but it might hurt not to... discovery is a
// heavyweight process; you don't want it in progress when
// a connection attempt is made.
mBluetoothAdapter.cancelDiscovery();

 

// Blocking connect, for a simple client nothing else can
// happen until a successful connection is made, so we
// don't care if it blocks.
try {
btSocket.connect();
Log.e(TAG, "ON RESUME: BT connection established, data transfer link open.");
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
Log.e(TAG,"ON RESUME: Unable to close socket during connection failure", e2);
}
}
 
// Create a data stream so we can talk to server.
if (D)
Log.e(TAG, "+ ABOUT TO SAY SOMETHING TO SERVER +");
 
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
 
String message = "Hello message from client to server.";
byte[] msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
}
 
@Override
public void onPause() {
super.onPause();
 
if (D)
Log.e(TAG, "- ON PAUSE -");
 
if (outStream != null) {
try {
outStream.flush();
} catch (IOException e) {
Log.e(TAG, "ON PAUSE: Couldn't flush output stream.", e);
}
}
 
try {
btSocket.close();
} catch (IOException e2) {
Log.e(TAG, "ON PAUSE: Unable to close socket.", e2);
}
}
 
@Override
public void onStop() {
super.onStop();
if (D)
Log.e(TAG, "-- ON STOP --");
}
 
@Override
public void onDestroy() {
super.onDestroy();
if (D)
Log.e(TAG, "--- ON DESTROY ---");
}
}
 
AndroidManifest.xml裡的Permission設定加下述二行
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
 
Android SDK 2.1裡的Bluetooh Sample (在 x:/android sdk安裝目錄/platforms/android-2.1/samples/BluetoothChat 裡面,或是到
HTTP://developer.android.com/resources/samples/BluetoothChat/index.html 看範例,二者是一樣的東西)
 
HTTP://code.google.com/p/apps-for-android/ 裡面有個 BTClickLinkCompete Sample,可經由SVN去下載回來看
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()