zoukankan      html  css  js  c++  java
  • Android 蓝牙的常用操作

    最近对Android设备的蓝牙操作进行了一些研究, 下面做一些总结, 版本是4.4,列出的解决方案多来源于网络,感谢强大的网友们:

    操作蓝牙可以分为常规的操作,和非常规的操作。所谓常规的操作,就是界面上有提示,需要客户许可进行的一些操作。非常规的则通常是采用反射等手段,达到不知不觉连接蓝牙的目的。

    一. 常规操作:

    1. 获取蓝牙的操作接口:

    BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();

    蓝牙的相关操作基本都是通过上面这个类。

    2. 打开本机的蓝牙设备:

    if (!mBtAdapter.isEnabled()) {
      Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
      startActivityForResult(enableIntent, 0);
    }

    3. 打开蓝牙的可见性:

    
    
    if (mBtAdapter.isEnabled()) {
      Intent visibleIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
      visibleIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);  // 后面的ms最多就是300
      startActivity(visibleIntent);
    }

    4. 开启了蓝牙设备,就是为了与其他设备通信,所以需要扫描周围可用的设备:

    // 注册两个intent,并定义receiver接受蓝牙设备检测过程中,"发现设备"和"完成"的回调事件
    IntentFilter discoveryFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    IntentFilter discoveryFinishedFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    BroadcastReceiver discoverReceiver = 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);  // 拿到别的device才能进行连接操作
         } 
    else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) 
    {
         // DO Something
    }
    }
    };
    this.registerReceiver(discoverReceiver, discoveryFilter);
    this.registerReceiver(discoverReceiver, discoveryFinishedFilter);

    /************************************/

    mBtAdapter.startDiscovery(); // 用来开始搜索周围可见的蓝牙设备 // 如果在发现过程中想要停止,可以调用下面的API if(mBtAdapter.isDiscovering()) { mBtAdapter.cancelDiscovery(); return; }

     5. 作为server端,等待其他设备连接:

    BluetoothServerSocket mServerSocket = mBtAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM, UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
    BluetoothSocket mClientSocket = mServerSocket.accept();

    // 有了socket对象,可以获取stream了, 可以用stream的read,write方法来读写数据了,read可以在独立线程的循环里,以保证持续接受到数据。
    InputStream inStream = mClientSocket.getInputStream();
    OutputStream outStream = mClientSocket.getOutputStream();

    6. 作为client端,可以去连接server:

    BluetoothDevice mDevice = mBtAdapter.getRemoteDevice(device.getAddress());   //首先要获得server的设备对象,这个兑现可以在之前 discover的时候就拿到,也可以通过之前记录的address获取到

    // connect 如果成功了,就得到socket连接了,之后和上面一样,就可以通过stream进而收发消息了
    mClientSocket = mDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
    mClientSocket.connect();

    二. 非常规操作:

    1. 打开本机的蓝牙设备:

    // 这样是不会弹出对话框的
    if
    (!mBtAdapter.isEnabled()) {   mBtAdapter.enable(); }

    2. 打开蓝牙的可见性:


      //值得一提的是,这个方法在 mBtAdapter.enable(); 之后立即调用是很有可能不生效的。可能是蓝牙设备开启需要一些时间。所以,最好是在确认设备确实已经开启了之后(比如说sleep一会儿,或者有个有个循环不断check mBtAdapter.isEnabled  (),来保证设备已经准备好了。  
      public
    void setDiscoverableTimeout(int timeout) {

         try {
              Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
                setDiscoverableTimeout.setAccessible(true);
                Method setScanMode =BluetoothAdapter.class.getMethod("setScanMode", int.class,int.class);
                setScanMode.setAccessible(true);
                 
                setDiscoverableTimeout.invoke(mBtAdapter, timeout);
                setScanMode.invoke(mBtAdapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,timeout);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    3. 不配对就进行蓝牙通信:

    // 通过这两个API, 可以很神奇的, 不配对蓝牙设备就进行通信
    mServerSocket = mBtAdapter.listenUsingInsecureRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM, UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
    mClientSocket = mDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));

    三. 最后列一下需要的权限:

        <uses-permission android:name="android.permission.BLUETOOTH"/>
        <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

    蓝牙参考网页: 

    http://stackoverflow.com/questions/5308373/how-to-create-insecure-rfcomm-socket-in-android

    http://stackoverflow.com/questions/5885438/bluetooth-pairing-without-user-confirmation

    http://blog.csdn.net/zshq280017423/article/details/7645622

    http://blog.csdn.net/menghnhhuan/article/details/7057484

    http://blog.csdn.net/eric41050808/article/details/16967189

    http://www.2cto.com/kf/201312/261093.html

    WIFI 参考网页:

    http://blog.csdn.net/ranger1111/article/details/6777153

    http://lszdb1983.blog.163.com/blog/static/20426348201209251344/

    格式啊,怎么也搞不好,,,

  • 相关阅读:
    linux之awk命令
    HDU 2097 Sky数 进制转换
    HDU 2077 汉诺塔IV
    HDU 2094 产生冠军 dfs加map容器
    HDU 2073 叠框
    HDU 2083 简易版之最短距离
    HDU 2063 过山车 二分匹配
    天梯 1014 装箱问题
    天梯 1214 线段覆盖
    天梯 1098 均分纸牌
  • 原文地址:https://www.cnblogs.com/beautiful-scenery/p/4113440.html
Copyright © 2011-2022 走看看