1. 程式人生 > >BLE 安卓APP控制LED燈的實現

BLE 安卓APP控制LED燈的實現



//注:參考AmoMcu原始碼修改。


開啟APP,檢查藍芽是否開啟

BluetoothAdapter mBluetoothAdapter;

final BluetoothManager bluetoothManager =(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
      mBluetoothAdapter = bluetoothManager.getAdapter();

// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
   Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
   startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}

藍芽掃描
private void scanLeDevice(final boolean enable) {
if (enable) {
    // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                }
            }, SCAN_PERIOD);


            mScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        } else {
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
    }

連線GATT服務
繫結一個服務
  Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
    bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
注:BluetoothLeService.java,屬於安卓原始碼,可以到網上下載回來。
// Code to manage Service lifecycle.
    private final ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!mBluetoothLeService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");
                finish();
            }
            // Automatically connects to the device upon successful start-up initialization.
            mBluetoothLeService.connect(mDeviceAddress);
        }
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mBluetoothLeService = null;
        }  
    };


點選某個特徵值的響應:
獲取前面的資料,不用再次掃描,由掃描頁面得到的資料,傳過來的
b=getIntent().getExtras();
tv_addr.setText(b.getString(EXTRAS_DEVICE_ADDRESS));
mDeviceAddress=b.getString(EXTRAS_DEVICE_ADDRESS);
tv_name.setText(b.getString(EXTRAS_DEVICE_NAME));
mDeviceName=b.getString(EXTRAS_DEVICE_NAME);
tv_rssi.setText(b.getString(EXTRAS_DEVICE_RSSI));

lv=(ExpandableListView)this.findViewById(R.id.expandableListView1);
lv.setOnChildClickListener(servicesListClickListner);


private final ExpandableListView.OnChildClickListener servicesListClickListner =
           new ExpandableListView.OnChildClickListener() {
               @Override
               public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
                                           int childPosition, long id) {                              
                   if (mGattCharacteristics != null) {
                       final BluetoothGattCharacteristic characteristic =
                               mGattCharacteristics.get(groupPosition).get(childPosition);
                       
                       //當前目標特徵值
                       target_chara=characteristic;
                                              
                       final int charaProp = characteristic.getProperties();
                   
                       if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                           mNotifyCharacteristic = characteristic;
                           
                           mBluetoothLeService.setCharacteristicNotification(
                                  characteristic, true);
                       }
                      tv_uuid.setText(characteristic.getUuid().toString());
                      Intent intent=new Intent();
                      b.putString("CONNET_SATE", status);
                      b.putString("UUID", characteristic.getUuid().toString());
                      intent.putExtras(b);
                      intent.setClass(MyGattDetail.this, LEDControl.class);
                      startActivity(intent);
                                      
               return true;
                   }             
                   return false;               
              }                       
   };


讀寫特徵值的資料
讀資料:
private static BluetoothGattCharacteristic myCharacteristic=null;
private static BluetoothLeService mBluetoothLeService;
mBluetoothLeService.readCharacteristic(myCharacteristic);

註釋:readCharacteristic該函式會呼叫BluetoothGatt.readCharacteristic(BluetoothGattCharacteristic characteristic)


寫資料:
mBluetoothLeService.writeCharacteristic(myCharacteristic);
註釋:writeCharacteristic該函式會呼叫BluetoothGatt.writeCharacteristic(BluetoothGattCharacteristic characteristic)


示例程式碼:
private char[] buffer =new char [] {0x6F,0x0F,0x0F,0x0F,0x0F,0x0F};
private void send() { 
MyGattDetail.write(ConvertString(buffer));
}

private String ConvertString(char buffer[]){
String nRcvString;
     StringBuffer tStringBuf=new StringBuffer ();
     tStringBuf.append(buffer);      
     nRcvString=tStringBuf.toString();     
     return  nRcvString;
}

device_name = (TextView) findViewById(R.id.ledpage_devname);

ledButton1 = (ToggleButton) findViewById(R.id.ledpage_led1);
ledButton1.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if(isChecked){
buffer[1]=0x01;
}else{
buffer[1]=0x00;
}
send();
}
});

ledButton2 = (ToggleButton) findViewById(R.id.ledpage_led2);
ledButton2.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if(isChecked){
buffer[2]=0x01;

}else{
buffer[2]=0x00;
}
send();
}
});
ledButton3 = (ToggleButton) findViewById(R.id.ledpage_led3);
ledButton3.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// TODO Auto-generated method stub
if(isChecked){
buffer[3]=0x01;
}else{
buffer[3]=0x00;
}
send();
}
});

ledButton4 = (ToggleButton) findViewById(R.id.ledpage_led4);
ledButton4.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// TODO Auto-generated method stub
if(isChecked){
buffer[4]=0x01;
}else{
buffer[4]=0x00;
}
send();
}
});

使用ToggleButton控制元件控制LED:
問題:
使用TI的demo會發現開啟一個LED會比較慢,偶爾還會失效。也就是說會掉幀,考慮大之前的所寫的關於延時值的設定,如下:
Connection Interval(GAPROLE_MIN_CONN_INTERVAL && GAPROLE_MAX_CONN_INTERVAL)- 連線間隔,在BLE的兩個裝置的連線中使用跳頻機制。兩個裝置使用特定的通道傳送和接收資料,然後過一段時間後再使用新的通道(BLE協議棧的鏈路層處理通道的切換)。兩個裝置在切換通道後傳送和接收資料稱為一個連線事件。儘管沒有應用資料被髮送和接收,兩個裝置仍舊會交換鏈路層資料來維持連線。這個連線間隔就是這個兩個連線事件的之間的時間間隔。間隔以1.25ms為單元,連線間隔的範圍的6-3200既7.5ms-4s(4000ms)之間。
由此可以看出:間隔小,適用於那些需要快速反應的任務。LED燈需要快速的反應,所以經過設定如下:
// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL     6//80
// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL     80//800

這樣子實時體驗就有大大的提升。


注意自己修改底層的設定!下載地址如下:

http://download.csdn.net/detail/liqinghan/9540416

相關推薦

BLE APP控制LED實現

//注:參考AmoMcu原始碼修改。 開啟APP,檢查藍芽是否開啟BluetoothAdapter mBluetoothAdapter; final BluetoothManager bluetoothManager =(BluetoothManager) getSys

手機與藍芽模組聯合除錯(二)—— 微控制器藍芽控制LED亮滅(上)

系列博文: 忙裡偷閒,承接上一篇文章繼續 本篇將實現兩個例項,手頭正好有8位的微控制器,索性就用來練手了。將會提供兩個例子,一個是基於STM8的庫函式例項,一個是基於STC89C52的例項。 1.首先了解下微控制器串列埠通訊線的接法。這個比較重要,建

常用控制元件RecyclerView+HorizontalScrollView實現item側滑效果 常用控制元件RecyclerView+HorizontalScrollView實現item側滑效果

原 安卓常用控制元件RecyclerView+HorizontalScrollView實現item側滑效果 2017年10月28日 12:23:14 低-調

Android 開發:(三)常用控制元件以及仿《微門戶》登入介面實現

一、常用控制元件: 1、文字類控制元件 TextView 負責展示文字,非編輯 EditText 可編輯文字控制元件 2、按鈕類控制元件 Button 按鈕 ImageButton 圖片按鈕 RadioButton與RadioGroup 單

java操作樹莓派GPIO控制LED--結合springboot實現介面呼叫

1、概述 本文使用java結合springboot實現了對樹莓派GPIO介面的操作以達到控制LED燈的功能 2、pom檔案如下: <project xmlns="http://maven.apache.org/POM/4.0.0"      &nb

Vux+Cordova打包的App實現微信分享朋友和朋友圈

知識儲備 Cordova Plugin ShareSDK 外掛 什麼是Cordova Plugin ShareSDK Cordova Plugin ShareSDK封裝了ShareSDK的android和ios平臺的分享功能。在hybird app開發中可以方便的完成分享功能。如:ion

app-LED跑馬燈

起因: 由於前一段時間Ti的時候的時候我看大家手上都有拿這種手機LED跑馬燈燈,但是我自己小米商店下回來的都有廣告,強迫症很難受,於是決定自己寫一個。 開始: 我開始構思的是將螢幕設定成橫屏,然後用TextView迴圈滑動達到,但是我發現這個方法BUG較多,也不太好用,

App登出登陸實現

一、Intent intent10=new Intent(MainActivity.this,LoginActivity.class); intent10.setFlags(Intent.FLAG_A

簡單實現app自動更新功能

一般的安卓app都有自動更新功能,實現app的更新,以讓使用者體驗新版本的功能,這裡也是專案中用到的,今天就來總結一下,程式碼應該有點多,還請耐心點哈。 安卓應用實現自動更新比較簡單,這裡跟大家介紹下: 第一步 伺服器端: 服務端提供一個藉口,或者網

APP測試之使用Burp Suite實現HTTPS抓包方法

APP的測試重點小部分在APP本身,大部分還是在網路通訊上(單機版除外)。所以在安卓APP測試過程中,網路抓包非常重要,一般來說,app開發會採用HTTP協議、Websocket、socket協議,一般來說,HTTP協議最多,Websocket是後起之秀,socket最少,

APP底部導航欄(有訊息圓點指示器),實現fragment切換(eclipse)

本專案使用了相對佈局和單選按鈕實現了安卓app常見的底部導航欄(帶有訊息圓點指示器),效果如果所示 一、佈局程式碼如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/androi

-自定義佈局】App開發思路 一步一個腳印(十)實現內嵌在app中的webview 騰訊開源X5 高效安全

實現內嵌在app中的webview 採用騰訊開源X5 高效安全 webview在app的使用中,十分頻繁,原生的webview載入速度相對來說很慢,而且很費流量。騰訊開源了x5的webview

ESP8266-01之NodeMCU(lua)實現遠端控制LED

開發環境 ESP-01 wifi模組 LualLoader NodeMCU nodemcu_float_0.9.6-dev_20150704.bin nodemcu_integer_0.9.6-de

【醬菜創客】ESP8266連線伺服器實現遠端控制LED

#include <ESP8266WiFi.h> WiFiClient client; #define relay1 2 //繼電器連線在8266的GPIO2上 const char *ssid = "xxxx";//這裡是我的wifi,你使用時修改為你要連線的wifi ssid con

【SikuliX】SikuliX+Vysor實現app自動化測試

簡介 Vysor用於顯示Android裝置介面和操作 SikuliX用於編寫自動化指令碼 安裝Vysor 開啟谷歌瀏覽器,點選擴充套件程式設定 搜尋Vysor,進行安裝 點選 View

-自定義佈局】App開發思路 一步一個腳印(九)實現自定義滾動的新聞條目上下滾動-仿蘑菇街

實現自定義滾動的新聞條目上下滾動-仿蘑菇街       這種上下滾動的自定義佈局,就像是公告那種上下的翻滾,一般為文字的滾動,很明顯,就是自定義佈局,一般是線性佈局。這裡提到的安卓原生的控制元件自然是

NodeMCU實現遠端控制LED

   NodeMCU是一塊集成了ESP8266的微控制器,它具有體積小,擴充套件性強的特點。在物聯網應用領域將迸發出強大的能量。我們通過入門一個NodeMCU的程式來展示一下它的強大功能。   NodeMCU的WIFI模組有三種模式,AP模式(即路由器模式),STA模式(我

開發app插件有能力的來

thread 插件 app插件 1-1 能力 www app player .com %E6%9D%A5%E8%87%AARockPlayer%E8%81%94%E5%90%88%E5%88%9B%E5%A7%8B%E4%BA%BA%E6%9D%A8%E6%AD%A6%E8

怎樣獲得app的資源包

mage spa font 程序 logs 得到 獲得 入門 tro   對於安卓剛入門的人來說經常模仿項目是最快的進步方法,實戰才能提升水平。模仿別人軟件的時候我們需要有那個軟件的圖片,這樣才可以寫出和這個軟件一樣的界面效果,接下來我要記錄下我剛剛嘗試的怎麽獲取安卓軟件資

webapp檢測app是否安裝並launch

nbsp rdo agen bsp 後臺 方法 ins 動態 dev 1. cordova插件 1)查看所有已安裝的安卓app https://www.npmjs.com/package/cordova-plugin-packagemanager A simple p