• 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

  • 相关阅读:
    elasticsearch(一):JAVA api操作
    elasticsearch(一):安装与配置
    Apache POI导出excel
    Java实现验证码
    Java数据库连接池原理与简易实现
    SpringMvc注解开发
    类型转换的时候,.valueOf()和.parseX(),.Xvalue()的区别
    kmp算法模板
    java 的任意进制间转换(很方便)
    海伦-秦九韶公式(利用三角形的三边求面积)
  • 原文地址:https://www.cnblogs.com/androidsj/p/2969494.html
Copyright © 2020-2023  润新知