編輯:關於Android編程
Bluetooth簡介
藍牙,是一種支持設備短距離通信(一般10m內)的無線電技術。能在包括移動電話、PDA、無線耳機、筆記本電腦、相關外設等眾多設備之間進行無線信息交換。利用“藍牙”技術,能夠有效地簡化移動通信終端設備之間的通信,也能夠成功地簡化設備與因特網Internet之間的通信,從而數據傳輸變得更加迅速高效,為無線通信拓寬道路。藍牙采用分散式網絡結構以及快跳頻和短包技術,支持點對點及點對多點通信,工作在全球通用的2.4GHz ISM(即工業、科學、醫學)頻段。其數據速率為1Mbps。采用時分雙工傳輸方案實現全雙工傳輸。
Bluetooth的基本類
Android平台提供了一個android.bluetooth的包,裡面有藍牙API去實現藍牙設備之間的通信,只有8個類。常用的四個類:
BluetoothAdapter類:代表了一個本地的藍牙適配器。它是所有藍牙交互的入口點。利用它你可以發現其他藍牙設備,查詢綁定了的設備,使用已知的MAC地址實例化一個藍牙設
備和建立一個BluetoothServerSocket(作為服務器端)來監聽來自其他設備的連接。
BluetoothDevice類:代表了一個遠端的藍牙設備,使用它請求遠端藍牙設備連接或者獲取遠端藍牙設備的名稱、地址、種類和綁定狀態(其信息是封裝在BluetoothSocket中)。
BluetoothSocket類:代表了一個藍牙套接字的接口(類似於TCP中的套接字),它是應用程序通過輸入、輸出流與其他藍牙設備通信的連接點。
BlueboothServerSocket類:代表打開服務連接來監聽可能到來的連接請求(屬於server端),為了連接兩個藍牙設備必須有一個設備作為服務器打開一個服務套接字。當遠端設
備發起連接連接請求的時候,並且已經連接到了的時候,BlueboothServerSocket類將會返回一個BluetoothSocket。
BluetoothAdapter藍牙適配器
cancelDiscovery()取消發現,當我們正在搜索設備的時候調用這個方法將不再繼續搜索
disable()關閉藍牙
enable()打開藍牙,這個方法打開藍牙不會彈出提示,更多的時候我們需要問下用戶是否打開,以下兩行代碼同樣是打開藍牙,但會提示用戶:
Intentenabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enabler);
getAddress()獲取本地藍牙地址
getDefaultAdapter()獲取默認BluetoothAdapter,實際上,也只有這一種方法獲取BluetoothAdapter
getName()獲取本地藍牙名稱
getRemoteDevice(String address)根據藍牙地址獲取遠程藍牙設備
getState()獲取本地藍牙適配器當前狀態
isDiscovering()判斷當前是否正在查找設備,是則返回true
isEnabled()判斷藍牙是否打開,已打開返回true,否則返回false
listenUsingRfcommWithServiceRecord(String name,UUID uuid)根據名稱,UUID創建並返回BluetoothServerSocket,這是創建BluetoothSocket服務器端的第一步
startDiscovery()開始搜索,這是搜索的第一步
BluetoothDevice:遠程藍牙設備
createRfcommSocketToServiceRecord(UUIDuuid)根據UUID創建並返回一個BluetoothSocket,這個方法也是我們獲取BluetoothDevice的目的——創建BluetoothSocket
這個類其他的方法,如getAddress()、getName()等,同BluetoothAdapter。
BluetoothServerSocket
如果去除了Bluetooth相信大家一定再熟悉不過了,既然是Socket,方法就應該都差不多,這個類一種只有三個方法:
accept()
accept(int timeout)
close()關閉。
兩者的區別在於後面的方法指定了過時時間,需要注意的是,執行這兩個方法的時候,直到接收到了客戶端的請求(或是過期之後),都會阻塞線程,應該放在新線程裡運行。
還有一點需要注意的是,這兩個方法都返回一個BluetoothSocket,最後的連接也是服務器端與客戶端的兩個BluetoothSocket的連接
BluetoothSocket是客戶端
共5個方法
close()關閉
connect()連接
getInptuStream()獲取輸入流
getOutputStream()獲取輸出流
getRemoteDevice()獲取遠程設備,這裡指的是獲取bluetoothSocket指定連接的那個遠程藍牙設備
藍牙數據傳輸——服務器端
1、獲得BluetoothAdapter。
2、通過BluetoothAdapter.listenUsingRfcommWithServiceRecord(name,UUID uuid)方法創建BluetoothServerSocket對象。
3、通過luetoothServerSocket.accept()方法返回一個BluetoothSocket對象。由於該方法處於阻塞狀態,需要開啟線程來處理。
4、通過BluetoothSocket.getInputStream()和BluetoothSocket.getOutputStream()方法獲得讀寫數據的InputStream和OutputStream對象。
5、通過InputStream.read()方法來讀數據。通過OutputStream.write()方法來寫數據。
藍牙數據傳輸——客戶端
1、獲得BluetoothAdapter。
2、通過BluetoothAdapter.getRemoteDevice(String address)獲得指定地址的BluetoothDevice對象。
3、通過BluetoothDevice.createRfcommSocketToServiceRecord (UUID uuid)方法創建BluetoothSocket對象。
4、通過BluetoothSocket.connect()方法來連接藍牙設備。
5、通過BluetoothSocket.getInputStream()和BluetoothSocket.getOutputStream()方法獲得讀寫數據的InputStream和OutputStream對象。
6、通過InputStream.read()方法來讀數據。通過OutputStream.write()方法來寫數據。
UUID
UUID:全局唯一標識符,格式為:8-4-4-4-12
兩個藍牙設備進行連接需要使用同一個UUID
串口服務的UUID:00001101-0000-1000-8000-00805F9B34FB
信息同步服務:00001104-0000-1000-8000-00805F9B34FB
文件傳輸服務:00001106-0000-1000-8000-00805F9B34FB
權限設置
操作藍牙權限:
Bluetooth的應用實現
藍牙設備之間的通信主要包括了四個步驟:
設置藍牙設備
尋找局域網內可能或者匹配的設備
連接設備
設備之間的數據傳輸
具體編程實現
1. 啟動藍牙功能 2. 查找設備
3. 查詢匹配好的設備 4. 掃描設備
5. 使能被發現 6. 連接設備
7. 服務端的連接 8. 客戶端的連接
9. 管理連接 10. 權限設置
1. 啟動藍牙功能
首先通過調用靜態方法getDefaultAdapter()獲取藍牙適配器BluetoothAdapter,如果返回為空,則無法繼續執行了。例如:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter .getDefaultAdapter(); if (mBluetoothAdapter == null) { // Device does not support Bluetooth }
其次,調用isEnabled()來查詢當前藍牙設備的狀態,如果返回為false,則表示藍牙設備沒有開啟,接下來你需要封裝一個ACTION_REQUEST_ENABLE請求到intent裡面,調
用startActivityForResult()方法使能藍牙設備,例如:
if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }
2. 查找設備
使用BluetoothAdapter類裡的方法,你可以查找遠端設備(大概十米以內)或者查詢在你手機上已經匹配(或者說綁
定)的其他設備了。當然需要確定對方藍牙設備已經開啟或者已經開啟了“被發現使能”功能(對方設備是可以被發現
的是你能夠發起連接的前提條件)。如果該設備是可以被發現的,會反饋回來一些對方的設備信息,比如名字、MAC
地址等,利用這些信息,你的設備就可以選擇去向對方初始化一個連接。
如果你是第一次與該設備連接,那麼一個配對的請求就會自動的顯示給用戶。當設備配對好之後,他的一些基本信息
(主要是名字和MAC)被保存下來並可以使用藍牙的API來讀取。使用已知的MAC地址就可以對遠端的藍牙設備發起
連接請求。
匹配好的設備和連接上的設備的不同點:匹配好只是說明對方設備發現了你的存在,並擁有一個共同的識別碼,並且
可以連接。連接上:表示當前設備共享一個RFCOMM信道並且兩者之間可以交換數據。也就是是說藍牙設備在建立
RFCOMM信道之前,必須是已經配對好了的。
3. 查詢匹配好的設備
在建立連接之前你必須先查詢配對好了的藍牙設備集以便選取一個設備進行通信,例如你可以你可以查詢所有配對的
藍牙設備,並使用一個數組適配器將其打印顯示出來:
SetpairedDevices = mBluetoothAdapter .getBondedDevices(); // If there are paired devices if (pairedDevices.size() > 0) { // Loop through paired devices for (BluetoothDevice device : pairedDevices) { // Add the name and address to an array adapter to show in a // ListView mArrayAdapter .add(device.getName() + "\n" + device.getAddress()); } }
建立一個藍牙連接只需要MAC地址就已經足夠。
4. 掃描設備
掃描設備,只需要調用startDiscovery()方法,這個掃描的過程大概持續是12秒,應用程序為了ACTION_FOUND動作
需要注冊一個BroadcastReceiver來接受設備掃描到的信息。對於每一個設備,系統都會廣播ACTION_FOUND動作。
// Create a BroadcastReceiver for ACTION_FOUND private final BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); // When discovery finds a device if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Add the name and address to an array adapter to show in a // ListView mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } }; // Register the BroadcastReceiver IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, filter); // Don't forget to unregister // during onDestroy。
如果你想使你的設備能夠被其他設備發現,將ACTION_REQUEST_DISCOVERABLE動作封裝在intent中並調用
startActivityForResult(Intent, int)方法就可以了。它將在不使你應用程序退出的情況下使你的設備能夠被發現。缺省情
況下的使能時間是120秒,當然你可以可以通過添加EXTRA_DISCOVERABLE_DURATION字段來改變使能時間(最
大不超過300秒)例如:
Intent discoverableIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra( BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent);
運行該段代碼之後,系統會彈出一個對話框來提示你啟動設備使能被發現(此過程中如果你的藍牙功能沒有開啟,系
統會幫你開啟),並且如果你准備對該遠端設備發現一個連接,你不需要開啟設備被發現功能,因為該功能只是在你
的應用程序作為服務器端的時候才需要。
6.連接設備
在應用程序中,想建立兩個藍牙設備之間的連接,必須實現客戶端和服務器端的代碼(因為任何一個設備都必須可以
作為服務端或者客戶端)。一個開啟服務來監聽,一個發起連接請求(使用服務器端設備的MAC地址)。當他們都擁
有一個藍牙套接字在同一RFECOMM信道上的時候,可以認為他們之間已經連接上了。服務端和客戶端通過不同的方
式或其他們的藍牙套接字。當一個連接監聽到的時候,服務端獲取到藍牙套接字。當客戶可打開一個FRCOMM信道給
服務器端的時候,客戶端獲取到藍牙套接字。
注意:在此過程中,如果兩個藍牙設備還沒有配對好的,android系統會通過一個通知或者對話框的形式來通知用戶。
RFCOMM連接請求會在用戶選擇之前阻塞。如下圖:
7.服務端的連接 <喎?/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjxicj4KPC9wPgo8cD61scTjz+vSqsGsvdPBvcyoyeixuMqxo6zSu7j2sdjQ69f3zqq3/s7xtsujqM2ouf2z1tPQ0ru49rTyv6q1xEJsdWV0b290aFNlcnZlclNvY2tldKOpo6zEv7XEyse84Mz9zeLAtMGsPC9wPgo8cD6908frx/OjrLWxvODM/bW90tS688zhuanSu7j2way908nPtcRCbHVldG9vdGhTb2NrZXS4+L/Nu6e2y6OstbG/zbuntsu000JsdWV0b290aFNlcnZlclNvY2tldLXDtb08L3A+CjxwPkJsdWV0b290aFNvY2tldNLUuvO+zb/J0tTP+rvZQmx1ZXRvb3RoU2VydmVyU29ja2V0o6yz/bfHxOO7uc/rvODM/bj8tuC1xMGsvdPH68fzoaM8L3A+CjxwPr2owaK3/s7xzNe909fWus284Mz9way907XEu/mxvrK91uijujwvcD4KPHA+ytfPyM2ouf2199PDbGlzdGVuVXNpbmdSZmNvbW1XaXRoU2VydmljZVJlY29yZChTdHJpbmcsIFVVSUQpt723qMC0u/HIoUJsdWV0b290aFNlcnZlclNvY2tldLbUz/OjrLLOyv08L3A+CjxwPlN0cmluZ7T6se3By7jDt/7O8bXEw/uzxqOsVVVJRLT6se3By7rNv827p7bLway907XE0ru49rHqyrajqDEyOM67JiMyNjY4NDvKvbXE19a3+7SuSUSjrM/gtbHT2lBJTsLro6mjrFVVSUQ8L3A+CjxwPrHY0OvLq7e9xqXF5LLFv8nS1L2owaLBrL3ToaM8L3A+CjxwPsbktM6199PDYWNjZXB0o6ijqbe9t6jAtLzgzP2/ycTctb3AtLXEway908frx/OjrLWxvODM/bW90tS686Ost7W72NK7uPbBrL3Tyc+1xMC20cDM173T19Y8L3A+CjxwPkJsdWV0b290aFNvY2tldKGjPC9wPgo8cD7X7rrzo6zU2rzgzP21vdK7uPbBrL3T0tS686Os0OjSqrX308NjbG9zZaOoo6m3vbeowLS52LHVvODM/bPM0PKho6Oo0ruw48C20cDJ6LG41q685MrHteO21LXjtcS0q8rko6k8L3A+CjxwPtei0uKjumFjY2VwdKOoo6m3vbeosrvTprjDt8XU2tb3QWNpdHZpdHnA78Pmo6zS8s6qy/zKx9K71tbX6Mj7tffTw6Oo1NrDu9PQvODM/bW9way908frx/PWrsews8zQ8r7N0rvWsc2jPC9wPgo8cD7U2sTHwO+jqaGjveK+9re9t6jKx9DCvajSu7j2z9+zzMC0udzA7aGjwP3I56O6IDwvcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(socket);
mmServerSocket.close();
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
} 為了初始化一個與遠端設備的連接,需要先獲取代表該設備的一個BluetoothDevice對象。通過BluetoothDevice對象 來獲取BluetoothSocket並初始化連接,具體步驟: 使用BluetoothDevice對象裡的方法createRfcommSocketToServiceRecord(UUID)來獲取BluetoothSocket。UUID就是 匹配碼。然後,調用connect()方法來。如果遠端設備接收了該連接,他們將在通信過程中共享RFFCOMM信道, 並且connect返回。 注意:conncet()方法也是阻塞調用,一般建立一個獨立的線程中來調用該方法。在設備discover過程中不應該發起 連接connect(),這樣會明顯減慢速度以至於連接失敗。且數據傳輸完成只有調用close()方法來關閉連接,這樣 可以節省系統內部資源。 9.管理連接(主要涉及數據的傳輸) 當設備連接上以後,每個設備都擁有各自的BluetoothSocket。就可以實現設備之間數據的共享了。 首先通過調用getInputStream()和getOutputStream()方法來獲取輸入輸出流。 然後通過調用read(byte[]) 和write(byte[]).方法來讀取或者寫數據。 實現細節:以為讀取和寫操作都是阻塞調用,需要建立一個專用線程來管理。 。 10. 權限設置 操作藍牙權限: 例子程序: main.xml
8.客戶端的連接
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(mmSocket);
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
MainActivity.java
package com.testBlueTooth; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.UUID; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.Toast; import android.widget.ToggleButton; public class testBlueTooth extends Activity { static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB"; Button btnSearch, btnDis, btnExit; ToggleButton tbtnSwitch; ListView lvBTDevices; ArrayAdapteradtDevices; List lstDevices = new ArrayList (); BluetoothAdapter btAdapt; public static BluetoothSocket btSocket; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Button 設置 btnSearch = (Button) this.findViewById(R.id.btnSearch); btnSearch.setOnClickListener(new ClickEvent()); btnExit = (Button) this.findViewById(R.id.btnExit); btnExit.setOnClickListener(new ClickEvent()); btnDis = (Button) this.findViewById(R.id.btnDis); btnDis.setOnClickListener(new ClickEvent()); // ToogleButton設置 tbtnSwitch = (ToggleButton) this.findViewById(R.id.tbtnSwitch); tbtnSwitch.setOnClickListener(new ClickEvent()); // ListView及其數據源 適配器 lvBTDevices = (ListView) this.findViewById(R.id.lvDevices); adtDevices = new ArrayAdapter (testBlueTooth.this, android.R.layout.simple_list_item_1, lstDevices); lvBTDevices.setAdapter(adtDevices); lvBTDevices.setOnItemClickListener(new ItemClickEvent()); btAdapt = BluetoothAdapter.getDefaultAdapter();// 初始化本機藍牙功能 if (btAdapt.getState() == BluetoothAdapter.STATE_ON)// 讀取藍牙狀態並顯示 tbtnSwitch.setChecked(false); else if (btAdapt.getState() == BluetoothAdapter.STATE_OFF) tbtnSwitch.setChecked(true); // 注冊Receiver來獲取藍牙設備相關的結果 IntentFilter intent = new IntentFilter(); intent.addAction(BluetoothDevice.ACTION_FOUND);// 用BroadcastReceiver來取得搜索結果 intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); registerReceiver(searchDevices, intent); } private BroadcastReceiver searchDevices = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Bundle b = intent.getExtras(); Object[] lstName = b.keySet().toArray(); // 顯示所有收到的消息及其細節 for (int i = 0; i < lstName.length; i++) { String keyName = lstName[i].toString(); Log.e(keyName, String.valueOf(b.get(keyName))); } // 搜索設備時,取得設備的MAC地址 if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); String str = device.getName() + "|" + device.getAddress(); if (lstDevices.indexOf(str) == -1)// 防止重復添加 lstDevices.add(str); // 獲取設備名稱和mac地址 adtDevices.notifyDataSetChanged(); } } }; @Override protected void onDestroy() { this.unregisterReceiver(searchDevices); super.onDestroy(); android.os.Process.killProcess(android.os.Process.myPid()); } class ItemClickEvent implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView> arg0, View arg1, int arg2, long arg3) { btAdapt.cancelDiscovery(); String str = lstDevices.get(arg2); String[] values = str.split("\\|"); String address = values[1]; Log.e("address", values[1]); UUID uuid = UUID.fromString(SPP_UUID); BluetoothDevice btDev = btAdapt.getRemoteDevice(address); try { btSocket = btDev.createRfcommSocketToServiceRecord(uuid); btSocket.connect(); } catch (IOException e) { // TODO Auto-generated catch block } } } class ClickEvent implements View.OnClickListener { @Override public void onClick(View v) { if (v == btnSearch)// 搜索藍牙設備,在BroadcastReceiver顯示結果 { if (btAdapt.getState() == BluetoothAdapter.STATE_OFF) {// 如果藍牙還沒開啟 Toast.makeText(testBlueTooth.this, "請先打開藍牙", 1000).show(); return; } setTitle("本機藍牙地址:" + btAdapt.getAddress()); lstDevices.clear(); btAdapt.startDiscovery(); } else if (v == tbtnSwitch) {// 本機藍牙啟動/關閉 if (tbtnSwitch.isChecked() == false) btAdapt.enable(); else if (tbtnSwitch.isChecked() == true) btAdapt.disable(); } else if (v == btnDis)// 本機可以被搜索 { Intent discoverableIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra( BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent); } else if (v == btnExit) { try { if (btSocket != null) btSocket.close(); } catch (IOException e) { e.printStackTrace(); } testBlueTooth.this.finish(); } } } }
Android支持的數據格式 數據格式的Intent filter AndroidManifest.xml文件中,要像向下列示例那樣
自從騰訊QQ中的圓形頭像,火了起來後,現在我們在一些應用中都能看到圓形頭像的身影,在個人主頁或者個人資料面板中使用圓形頭像,會使整個布局變得更加優雅現在我們來進行第一步,
在上一個例子中,最終我們發現,其實用到的線程只有一個,那就是程序的主線程(UI線程)。那麼怎麼把那個例子改成用新建的線程來實現呢,今天我嘗試了一下,寫了下面這個小程序。
我們知道,頁面導航器(Navigator)在幾乎所有的項目中都會用到,平時大多數時候為了節省時間,都會直接在github上面拿別人的開源項目來用,最近自己在復習自定義Vi