編輯:關於Android編程
正文
藍牙是一種支持設備短距離傳輸數據的無線技術。android在2.0以後提供了這方面的支持。
從查找藍牙設備到能夠相互通信要經過幾個基本步驟(本機做為服務器):
1.設置權限
在manifest中配置
[html]
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>2.啟動藍牙
首先要查看本機是否支持藍牙,獲取BluetoothAdapter藍牙適配器對象
[java]
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null){
//表明此手機不支持藍牙
return;
}
if(!mBluetoothAdapter.isEnabled()){ //藍牙未開啟,則開啟藍牙
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
//......
public void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == REQUEST_ENABLE_BT){
if(requestCode == RESULT_OK){
//藍牙已經開啟
}
}
}
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null){
//表明此手機不支持藍牙
return;
}
if(!mBluetoothAdapter.isEnabled()){ //藍牙未開啟,則開啟藍牙
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
//......
public void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == REQUEST_ENABLE_BT){
if(requestCode == RESULT_OK){
//藍牙已經開啟
}
}
}3。發現藍牙設備
這裡可以細分為幾個方面
(1)使本機藍牙處於可見(即處於易被搜索到狀態),便於其他設備發現本機藍牙
[java]
//使本機藍牙在300秒內可被搜索
private void ensureDiscoverable() {
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
//使本機藍牙在300秒內可被搜索
private void ensureDiscoverable() {
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
(2)查找已經配對的藍牙設備,即以前已經配對過的設備
[java]
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
for (BluetoothDevice device : pairedDevices) {
//device.getName() +" "+ device.getAddress());
}
} else {
mPairedDevicesArrayAdapter.add("沒有找到已匹對的設備");
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
for (BluetoothDevice device : pairedDevices) {
//device.getName() +" "+ device.getAddress());
}
} else {
mPairedDevicesArrayAdapter.add("沒有找到已匹對的設備");
}
(3)通過mBluetoothAdapter.startDiscovery();搜索設備,要獲得此搜索的結果需要注冊
一個BroadcastReceiver來獲取。先注冊再獲取信息,然後處理
[java]
//注冊,當一個設備被發現時調用onReceive
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
//當搜索結束後調用onReceive
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
//.......
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 已經配對的則跳過
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); //保存設備地址與名字
}
}else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { //搜索結束
if (mNewDevicesArrayAdapter.getCount() == 0) {
mNewDevicesArrayAdapter.add("沒有搜索到設備");
}
}
}
};
//注冊,當一個設備被發現時調用onReceive
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
//當搜索結束後調用onReceive
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
//.......
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 已經配對的則跳過
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); //保存設備地址與名字
}
}else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { //搜索結束
if (mNewDevicesArrayAdapter.getCount() == 0) {
mNewDevicesArrayAdapter.add("沒有搜索到設備");
}
}
}
};
4.建立連接
查找到設備 後,則需要建立本機與其他設備之間的連接。
一般用本機搜索其他藍牙設備時,本機可以作為一個服務端,接收其他設備的連接。
啟動一個服務器端的線程,死循環等待客戶端的連接,這與ServerSocket極為相似。
這個線程在准備連接之前啟動
[java]
//UUID可以看做一個端口號
private static final UUID MY_UUID =
UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
//像一個服務器一樣時刻監聽是否有連接建立
private class AcceptThread extends Thread{
private BluetoothServerSocket serverSocket;
public AcceptThread(boolean secure){
BluetoothServerSocket temp = null;
try {
temp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(
NAME_INSECURE, MY_UUID);
} catch (IOException e) {
Log.e("app", "listen() failed", e);
}
serverSocket = temp;
}
public void run(){
BluetoothSocket socket=null;
while(true){
try {
socket = serverSocket.accept();
} catch (IOException e) {
Log.e("app", "accept() failed", e);
break;
}
}
if(socket!=null){
//此時可以新建一個數據交換線程,把此socket傳進去
}
}
//取消監聽
public void cancel(){
try {
serverSocket.close();
} catch (IOException e) {
Log.e("app", "Socket Type" + socketType + "close() of server failed", e);
}
}
}
//UUID可以看做一個端口號
private static final UUID MY_UUID =
UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
//像一個服務器一樣時刻監聽是否有連接建立
private class AcceptThread extends Thread{
private BluetoothServerSocket serverSocket;
public AcceptThread(boolean secure){
BluetoothServerSocket temp = null;
try {
temp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(
NAME_INSECURE, MY_UUID);
} catch (IOException e) {
Log.e("app", "listen() failed", e);
}
serverSocket = temp;
}
public void run(){
BluetoothSocket socket=null;
while(true){
try {
socket = serverSocket.accept();
} catch (IOException e) {
Log.e("app", "accept() failed", e);
break;
}
}
if(socket!=null){
//此時可以新建一個數據交換線程,把此socket傳進去
}
}
//取消監聽
public void cancel(){
try {
serverSocket.close();
} catch (IOException e) {
Log.e("app", "Socket Type" + socketType + "close() of server failed", e);
}
}
}搜索到設備後可以獲取設備的地址,通過此地址獲取一個BluetoothDeviced對象,可以看做客戶端,通過此對象device.createRfcommSocketToServiceRecord(MY_UUID);同一個UUID可與服務器建立連接獲取另一個socket對象,由此服務端與客戶端各有一個socket對象,此時
他們可以互相交換數據了。
創立客戶端socket可建立線程
[java]
//另一個設備去連接本機,相當於客戶端
private class ConnectThread extends Thread{
private BluetoothSocket socket;
private BluetoothDevice device;
public ConnectThread(BluetoothDevice device,boolean secure){
this.device = device;
BluetoothSocket tmp = null;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
} catch (IOException e) {
Log.e("app", "create() failed", e);
}
}
public void run(){
mBluetoothAdapter.cancelDiscovery(); //取消設備查找
try {
socket.connect();
} catch (IOException e) {
try {
socket.close();
} catch (IOException e1) {
Log.e("app", "unable to close() "+
" socket during connection failure", e1);
}
connetionFailed(); //連接失敗
return;
}
//此時可以新建一個數據交換線程,把此socket傳進去
}
public void cancel() {
try {
socket.close();
} catch (IOException e) {
Log.e("app", "close() of connect socket failed", e);
}
}
}
//另一個設備去連接本機,相當於客戶端
private class ConnectThread extends Thread{
private BluetoothSocket socket;
private BluetoothDevice device;
public ConnectThread(BluetoothDevice device,boolean secure){
this.device = device;
BluetoothSocket tmp = null;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
} catch (IOException e) {
Log.e("app", "create() failed", e);
}
}
public void run(){
mBluetoothAdapter.cancelDiscovery(); //取消設備查找
try {
socket.connect();
} catch (IOException e) {
try {
socket.close();
} catch (IOException e1) {
Log.e("app", "unable to close() "+
" socket during connection failure", e1);
}
connetionFailed(); //連接失敗
return;
}
//此時可以新建一個數據交換線程,把此socket傳進去
}
public void cancel() {
try {
socket.close();
} catch (IOException e) {
Log.e("app", "close() of connect socket failed", e);
}
}
}
5.建立數據通信線程,進行讀取數據
[java]
//建立連接後,進行數據通信的線程
private class ConnectedThread extends Thread{
private BluetoothSocket socket;
private InputStream inStream;
private OutputStream outStream;
public ConnectedThread(BluetoothSocket socket){
this.socket = socket;
try {
//獲得輸入輸出流
inStream = socket.getInputStream();
outStream = socket.getOutputStream();
} catch (IOException e) {
Log.e("app", "temp sockets not created", e);
}
}
public void run(){
byte[] buff = new byte[1024];
int len=0;
//讀數據需不斷監聽,寫不需要
while(true){
try {
len = inStream.read(buff);
//把讀取到的數據發送給UI進行顯示
Message msg = handler.obtainMessage(BluetoothChat.MESSAGE_READ,
len, -1, buff);
msg.sendToTarget();
} catch (IOException e) {
Log.e("app", "disconnected", e);
connectionLost(); //失去連接
start(); //重新啟動服務器
break;
}
}
}
public void write(byte[] buffer) {
try {
outStream.write(buffer);
// Share the sent message back to the UI Activity
handler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e("app", "Exception during write", e);
}
}
public void cancel() {
try {
socket.close();
} catch (IOException e) {
Log.e("app", "close() of connect socket failed", e);
}
}
}
前面在學習鴻洋大神的一些自定義的View文章,看到了自定義ViewGroup實現浮動標簽,初步看了下他的思路以及結合自己的思路完成了自己的浮動標簽的自定義ViewGrou
什麼是變量?在計算機中用來存儲信息,通過聲明語句來指明存儲位置和所需空間。變量的聲明方法及賦值分號:語句結束標志 賦值號:將=右邊的值賦給左邊的變量變量有哪些數據類型?變
本文屬於實戰系列,是對《Android C代碼回調java方法》等文的實踐,調用meitu秀秀的libmtimage-jni.so文件來實現圖片的美化功能首先反編譯得到/
音頻基礎知識 聲音有哪些重要屬性呢? 響度(Loudness) 響度就是人類可以感知到的各種聲音的大小,也就是音量。響度與聲波的振幅有直接關系。 音調(Pitch)
問題現象: 在剛安裝完demo應用未登錄任何帳號