一、 BluetoothAdapter类介绍
BluetoothAdapter类简单点来说就是代表了本设备(手机、电脑等)的蓝牙适配器对象,通过它我们可以蓝牙设备进行基本
开发了,主要有如下功能:
1、开关蓝牙设备;
2、扫描蓝牙设备;
3、设置/获取蓝牙状态信息,例如:蓝牙状态值、蓝牙Name、蓝牙Mac地址等;
BluetoothAdapter的一些常用API函数:http://www.cnblogs.com/over140/archive/2010/12/21/1912460.html
1、BluetoothAdapter STATE 状态值 , 即开关状态
int STATE_OFF 蓝牙已经关闭
int STATE_ON 蓝牙已经打开
int STATE_TURNING_OFF 蓝牙处于关闭过程中 ,关闭ing
int STATE_TURNING_ON 蓝牙处于打开过程中 ,打开ing
2、BluetoothAdapter SCAN_MOD状态值 ,即扫描状态
首先说明,可以扫描其他设备的,当然它同时能被其他蓝牙设备扫码。
int SCAN_MODE_CONNECTABLE 表明该蓝牙可以扫描其他蓝牙设备
int SCAN_MODE_CONNECTABLE_DISCOVERABLE 表明该蓝牙设备同时可以扫码其他蓝牙设备,并且可以被其他蓝牙设备扫描到。
int SCAN_MODE_NONE : 该蓝牙不能扫描以及被扫描。
3、获得蓝牙适配器实例
public static synchronized BluetoothAdapter getDefaultAdapter ()
功能:获得本设备的蓝牙适配器实例。
返回值:如果设备具备蓝牙功能,返回BluetoothAdapter 实例;否则,返回null对象。
4、打开/关闭蓝牙的两种方法:
4.1、打开蓝牙:
①、直接调用函数enable()去打开蓝牙设备 ;
②、系统API去打开蓝牙设备,该方式会弹出一个对话框样式的Activity供用户选择是否打开蓝牙设备。
注意:如果蓝牙已经开启,不会弹出该Activity界面。
PS:在目前Android手机中,是不支持在飞行模式下开启蓝牙的。如果蓝牙已经开启,那么蓝牙的开关状态会随着飞行模式
的状态而发生改变。
代码示例分别如下:
//第一种打开方法: 调用enable 即可 boolean result = mBluetoothAdapter.enable(); // /第二种打开方法 ,调用系统API去打开蓝牙 if (!mBluetoothAdapter.isEnabled()) //未打开蓝牙,才需要打开蓝牙 { Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent, REQUEST_OPEN_BT_CODE); //会以Dialog样式显示一个Activity , 我们可以在onActivityResult()方法去处理返回值 }
4.2、关闭蓝牙
直接调用API 函数即disable()即可。
public boolean disable ()
功能:关闭蓝牙设备。
返回值:该函数会立即返回。
true 表示关闭操作成功
false 表示蓝牙操作失败 , ①、当前蓝牙已经关闭 ; ②、其他一些异常情况
5、扫描蓝牙设备
public boolean startDiscovery ()
功能: 扫描蓝牙设备
注意: 如果蓝牙没有开启,该方法会返回false ,即不会开始扫描过程。
public boolean cancelDiscovery ()
功能: 取消扫描过程。
注意: 如果蓝牙没有开启,该方法会返回false。
public boolean isDiscovering ()
功能: 是否正在处于扫描过程中。
注意: 如果蓝牙没有开启,该方法会返回false。
6、 获取蓝牙相关信息
public String getName ()
功能:获取蓝牙设备Name
public String getAddress ()
功能:获取蓝牙设备的硬件地址(MAC地址),例如:00:11:22:AA:BB:CC
public boolean setName (String name)
功能:设置蓝牙设备的Name,
public Set<BluetoothDevice> getBondedDevices ()
功能:获取与本机蓝牙所有绑定的远程蓝牙信息,以BluetoothDevice类实例(稍后讲到)返回。
注意:如果蓝牙为开启,该函数会返回一个空集合 。
public static boolean checkBluetoothAddress (String address)
功能: 验证蓝牙设备MAC地址是否有效。所有设备地址的英文字母必须大写,48位,形如:00:43:A8:23:10:F1 。
返回值: true 设备地址有效
false 设备地址无效
public BluetoothDevice getRemoteDevice (String address)
功能:以给定的MAC地址去创建一个 BluetoothDevice 类实例(代表远程蓝牙实例)。即使该蓝牙地址不可见,也会产生
一个BluetoothDevice 类实例。
返回:BluetoothDevice 类实例 。注意,如果该蓝牙设备MAC地址不能被识别,其蓝牙Name为null。
异常:如果MAC address无效,抛出IllegalArgumentException。
7、蓝牙相关广播
Action值 说明
ACTION_STATE_CHANGED 蓝牙状态值发生改变
ACTION_SCAN_MODE_CHANGED 蓝牙扫描状态(SCAN_MODE)发生改变
ACTION_DISCOVERY_STARTED 蓝牙扫描过程开始
ACTION_DISCOVERY_FINISHED 蓝牙扫描过程结束
ACTION_LOCAL_NAME_CHANGED 蓝牙设备Name发生改变
ACTION_REQUEST_DISCOVERABLE 请求用户选择是否使该蓝牙能被扫描
PS:如果蓝牙没有开启,用户点击确定后,会首先开启蓝牙,继而设置蓝牙能被扫描。
ACTION_REQUEST_ENABLE 请求用户选择是否打开蓝牙
ACTION_FOUND (该常量字段位于BluetoothDevice类中,稍后讲到)
说明:蓝牙扫描时,扫描到任一远程蓝牙设备时,会发送此广播。
通过注册这个广播,我们可以获取扫描到的蓝牙信息。方法如下:
//扫描到了任一蓝牙设备 if(BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) { Log.v(TAG, "### BT BluetoothDevice.ACTION_FOUND ##"); BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if(btDevice != null){ Log.v(TAG , "Name : " + btDevice.getName() + " Address: " + btDevice.getAddress()); } else if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) { Log.v(TAG, "### BT ACTION_BOND_STATE_CHANGED ##"); int cur_bond_state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); int previous_bond_state = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.BOND_NONE); Log.v(TAG, "### cur_bond_state ##" + cur_bond_state + " ~~ previous_bond_state" + previous_bond_state); } }
最后,在使用这两个类时,需要以下两个权限:
BLUETOOTH 值为 "android.permission.BLUETOOTH"
BLUETOOTH_ADMIN 值为 "android.permission.BLUETOOTH_ADMIN"
二、 BluetoothDevice类介绍
该类就是关于远程蓝牙设备的一个描述。通过它可以和本地蓝牙设备---BluetoothAdapter连接通信。
1、 蓝牙绑定(Bound)状态 , 即蓝牙设备是否与其他蓝牙绑定
int BOND_BONDED 表明蓝牙已经绑定
int BOND_BONDING 表明蓝牙正在绑定过程中 , bounding
int BOND_NONE 表明没有绑定
更多关于BluetoothDevice类的更多介绍,请参考该农民伯伯的该篇博客:
http://www.cnblogs.com/over140/archive/2010/12/21/1912482.html
以下是完整代码:
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/btDesc" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/btOpen" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="打开蓝牙" /> <Button android:id="@+id/btClose" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="关闭蓝牙" /> <Button android:id="@+id/btOpenBySystem" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="调用系统API打开蓝牙" /> <Button android:id="@+id/btDiscoveryDevice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="搜索蓝牙设备" /> <Button android:id="@+id/btCancelDiscovery" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="停止搜索蓝牙设备" /> <Button android:id="@+id/btDiscoveryBySystem" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="调用系统API搜索蓝牙设备" /> </LinearLayout>
MainActivity.java
package com.cn; import android.app.Activity; import android.os.Bundle; import java.util.Iterator; import java.util.Set; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener { private static String TAG = "Bluetooth_State"; private BluetoothAdapter mBluetoothAdapter; // 本机蓝牙适配器对象 private TextView btDesc; private Button btOpen; private Button btClose; private Button btOpenBySystem; // 调用系统API去打开蓝牙 private Button btDiscoveryDevice; private Button btCancelDiscovery; private Button btDiscoveryBySystem; // 调用系统Api去扫描蓝牙设备 /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // 获得本机蓝牙适配器对象引用 if (mBluetoothAdapter == null) { toast("对不起 ,您的机器不具备蓝牙功能"); return; } IntentFilter bluetoothFilter = new IntentFilter(); bluetoothFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); bluetoothFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); this.registerReceiver(BluetoothReciever, bluetoothFilter); // 蓝牙扫描相关设备 IntentFilter btDiscoveryFilter = new IntentFilter(); btDiscoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); btDiscoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); btDiscoveryFilter.addAction(BluetoothDevice.ACTION_FOUND); btDiscoveryFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); this.registerReceiver(BTDiscoveryReceiver, btDiscoveryFilter); int initialBTState = mBluetoothAdapter.getState(); printBTState(initialBTState); // 初始时蓝牙状态 initialViews(); btDesc.setText(" Name : " + mBluetoothAdapter.getName() + " Address : " + mBluetoothAdapter.getAddress() + " Scan Mode --" + mBluetoothAdapter.getScanMode()); // 打印处当前已经绑定成功的蓝牙设备 Set<BluetoothDevice> bts = mBluetoothAdapter.getBondedDevices(); Iterator<BluetoothDevice> iterator = bts.iterator(); while (iterator.hasNext()) { BluetoothDevice bd = iterator.next(); Log.i(TAG, " Name : " + bd.getName() + " Address : " + bd.getAddress()); ; Log.i(TAG, "Device class" + bd.getBluetoothClass()); } BluetoothDevice findDevice = mBluetoothAdapter .getRemoteDevice("00:11:22:33:AA:BB"); Log.i(TAG, "findDevice Name : " + findDevice.getName() + " findDevice Address : " + findDevice.getAddress()); ; Log.i(TAG, "findDevice class" + findDevice.getBluetoothClass()); } private void initialViews() { btDesc = (TextView) findViewById(R.id.btDesc); btOpen = (Button) findViewById(R.id.btOpen); btClose = (Button) findViewById(R.id.btClose); btOpenBySystem = (Button) findViewById(R.id.btOpenBySystem); btDiscoveryDevice = (Button) findViewById(R.id.btDiscoveryDevice); btCancelDiscovery = (Button) findViewById(R.id.btCancelDiscovery); btDiscoveryBySystem = (Button) findViewById(R.id.btDiscoveryBySystem); btOpen.setOnClickListener(this); btClose.setOnClickListener(this); btOpenBySystem.setOnClickListener(this); btDiscoveryDevice.setOnClickListener(this); btCancelDiscovery.setOnClickListener(this); btDiscoveryBySystem.setOnClickListener(this); } // 蓝牙开个状态以及扫描状态的广播接收器 private BroadcastReceiver BluetoothReciever = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if (BluetoothAdapter.ACTION_STATE_CHANGED .equals(intent.getAction())) { Log.v(TAG, "### Bluetooth State has changed ##"); int btState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF); printBTState(btState); } else if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(intent .getAction())) { Log.v(TAG, "### ACTION_SCAN_MODE_CHANGED##"); int cur_mode_state = intent.getIntExtra( BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.SCAN_MODE_NONE); int previous_mode_state = intent.getIntExtra( BluetoothAdapter.EXTRA_PREVIOUS_SCAN_MODE, BluetoothAdapter.SCAN_MODE_NONE); Log.v(TAG, "### cur_mode_state ##" + cur_mode_state + " ~~ previous_mode_state" + previous_mode_state); } } }; // 蓝牙扫描时的广播接收器 private BroadcastReceiver BTDiscoveryReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent .getAction())) { Log.v(TAG, "### BT ACTION_DISCOVERY_STARTED ##"); } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent .getAction())) { Log.v(TAG, "### BT ACTION_DISCOVERY_FINISHED ##"); } else if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) { Log.v(TAG, "### BT BluetoothDevice.ACTION_FOUND ##"); BluetoothDevice btDevice = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (btDevice != null) Log.v(TAG, "Name : " + btDevice.getName() + " Address: " + btDevice.getAddress()); } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent .getAction())) { Log.v(TAG, "### BT ACTION_BOND_STATE_CHANGED ##"); int cur_bond_state = intent.getIntExtra( BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); int previous_bond_state = intent.getIntExtra( BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.BOND_NONE); Log.v(TAG, "### cur_bond_state ##" + cur_bond_state + " ~~ previous_bond_state" + previous_bond_state); } } }; private void printBTState(int btState) { switch (btState) { case BluetoothAdapter.STATE_OFF: toast("蓝牙状态:已关闭"); Log.v(TAG, "BT State : BluetoothAdapter.STATE_OFF ###"); break; case BluetoothAdapter.STATE_TURNING_OFF: toast("蓝牙状态:正在关闭"); Log.v(TAG, "BT State : BluetoothAdapter.STATE_TURNING_OFF ###"); break; case BluetoothAdapter.STATE_TURNING_ON: toast("蓝牙状态:正在打开"); Log.v(TAG, "BT State :BluetoothAdapter.STATE_TURNING_ON ###"); break; case BluetoothAdapter.STATE_ON: toast("蓝牙状态:已打开"); Log.v(TAG, "BT State :BluetoothAdapter.STATE_ON ###"); break; default: break; } } private final int REQUEST_OPEN_BT_CODE = 1; private final int REQUEST_DISCOVERY_BT_CODE = 2; @Override public void onClick(View v) { boolean wasBtOpened = mBluetoothAdapter.isEnabled(); // 是否已经打开 switch (v.getId()) { case R.id.btOpen: // 打开蓝牙 boolean result = mBluetoothAdapter.enable(); if (result) toast("蓝牙打开操作成功"); else if (wasBtOpened) toast("蓝牙已经打开了"); else toast("蓝牙打开失败"); break; case R.id.btClose: // 关闭蓝牙 boolean result1 = mBluetoothAdapter.disable(); if (result1) toast("蓝牙关闭操作成功"); else if (!wasBtOpened) toast("蓝牙已经关闭"); else toast("蓝牙关闭失败."); break; case R.id.btOpenBySystem: // 调用系统API打开蓝牙设备 // 未打开蓝牙,才需要打开蓝牙 if (!wasBtOpened) { Intent intent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent, REQUEST_OPEN_BT_CODE); } else toast("Hi ,蓝牙已经打开了,不需要在打开啦 ~~~"); break; case R.id.btDiscoveryDevice: // 扫描时,必须先打开蓝牙 if (!mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.startDiscovery(); } else toast("蓝牙正在搜索设备了 ---- "); break; case R.id.btCancelDiscovery: // 取消扫描 if (mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); } else toast("蓝牙并未搜索设备 ---- "); break; case R.id.btDiscoveryBySystem: // 使蓝牙能被扫描 Intent discoveryintent = new Intent( BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoveryintent.putExtra( BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivityForResult(discoveryintent, REQUEST_DISCOVERY_BT_CODE); break; } } // 请求码 protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_OPEN_BT_CODE) { if (resultCode == RESULT_CANCELED) { toast("Sorry , 用户拒绝了您的打开蓝牙请求."); } else toast("Year , 用户允许了您的打开蓝牙请求."); } else if (requestCode == REQUEST_DISCOVERY_BT_CODE) { if (resultCode == RESULT_CANCELED) { toast("Sorry , 用户拒绝了,您的蓝牙不能被扫描."); } else toast("Year , 用户允许了,您的蓝牙能被扫描"); } } private void toast(String str) { Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); } }
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cn" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> </manifest>
运行结果:
最后关于如果连接某个蓝牙设备,就需要利用蓝牙部分的隐藏API了,关于这方面,大家可以看看hellogv的博客: