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/

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

  • 相关阅读:
    react native 添加mobx
    js-(19,999,999.00)
    html移动端 -- meta-模板 + rem
    HTML5 移动端头部标签
    js
    html --- rem
    es6--async--await
    nrm+nvm
    js-call-apply
    SQL映射文件
  • 原文地址:https://www.cnblogs.com/beautiful-scenery/p/4113440.html
Copyright © 2011-2022 走看看