Android中蓝牙的基本使用

 一、 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手机中,是不支持在飞行模式下开启蓝牙的。如果蓝牙已经开启,那么蓝牙的开关状态会随着飞行模式

的状态而发生改变。

       代码示例分别如下:

View Code
//第一种打开方法: 调用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类中,稍后讲到)

                说明:蓝牙扫描时,扫描到任一远程蓝牙设备时,会发送此广播。

        通过注册这个广播,我们可以获取扫描到的蓝牙信息。方法如下:

View Code
//扫描到了任一蓝牙设备
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

View Code
<?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

View Code
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

View Code
<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的博客:

                     Android提高第十三篇之探秘蓝牙隐藏API

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/androidsj/archive/2013/03/19/2969494.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值