单片机连接手机应用客户端进行蓝牙通讯:

学习了!!!!分享:

package com.severn;import java.util.ArrayList;import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;import com.severn.ui.Ble_Activity;/*** @Description: TODO<MainActivity类实现打开蓝牙、扫描蓝牙>*/
public class MainActivity extends Activity implements OnClickListener {// 扫描蓝牙按钮private Button scan_btn;// 蓝牙适配器BluetoothAdapter mBluetoothAdapter;// 蓝牙信号强度private ArrayList<Integer> rssis;// 自定义AdapterLeDeviceListAdapter mleDeviceListAdapter;// listview显示扫描到的蓝牙信息ListView lv;// 描述扫描蓝牙的状态private boolean mScanning;private boolean scan_flag;private Handler mHandler;int REQUEST_ENABLE_BT = 1;// 蓝牙扫描时间private static final long SCAN_PERIOD = 10000;@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 初始化控件init();// 初始化蓝牙init_ble();scan_flag = true;// 自定义适配器mleDeviceListAdapter = new LeDeviceListAdapter();// 为listview指定适配器lv.setAdapter(mleDeviceListAdapter);/* listview点击函数 */lv.setOnItemClickListener(new AdapterView.OnItemClickListener(){@Overridepublic void onItemClick(AdapterView<?> arg0, View v, int position,long id){// TODO Auto-generated method stubfinal BluetoothDevice device = mleDeviceListAdapter.getDevice(position);if (device == null)return;final Intent intent = new Intent(MainActivity.this,Ble_Activity.class);intent.putExtra(Ble_Activity.EXTRAS_DEVICE_NAME,device.getName());intent.putExtra(Ble_Activity.EXTRAS_DEVICE_ADDRESS,device.getAddress());if (mScanning){/* 停止扫描设备 */mBluetoothAdapter.stopLeScan(mLeScanCallback);mScanning = false;}try{// 启动Ble_ActivitystartActivity(intent);} catch (Exception e){e.printStackTrace();// TODO: handle exception}}});}/*** @Title: init* @Description: TODO(初始化UI控件)* @return void* @throws*/private void init(){scan_btn =  this.findViewById(R.id.scan_dev_btn);scan_btn.setOnClickListener(this);lv =  this.findViewById(R.id.lv);mHandler = new Handler();}/*** @Title: init_ble* @Description: TODO(初始化蓝牙)* @return void* @throws*/private void init_ble(){// 手机硬件支持蓝牙if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){Toast.makeText(this, "不支持BLE", Toast.LENGTH_SHORT).show();finish();}// Initializes Bluetooth adapter.// 获取手机本地的蓝牙适配器final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);mBluetoothAdapter = bluetoothManager.getAdapter();// 打开蓝牙权限if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()){Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);}}/** 按钮响应事件*/@Overridepublic void onClick(View v){// TODO Auto-generated method stubif (scan_flag){mleDeviceListAdapter = new LeDeviceListAdapter();lv.setAdapter(mleDeviceListAdapter);scanLeDevice(true);} else{scanLeDevice(false);scan_btn.setText("扫描设备");}}/*** @Title: scanLeDevice* @Description: TODO(扫描蓝牙设备 )* @param enable*            (扫描使能,true:扫描开始,false:扫描停止)* @return void* @throws*/private void scanLeDevice(final boolean enable){if (enable){// Stops scanning after a pre-defined scan period.mHandler.postDelayed(new Runnable(){@Overridepublic void run(){mScanning = false;scan_flag = true;scan_btn.setText("扫描设备");Log.i("SCAN", "stop.....................");mBluetoothAdapter.stopLeScan(mLeScanCallback);}}, SCAN_PERIOD);/* 开始扫描蓝牙设备,带mLeScanCallback 回调函数 */Log.i("SCAN", "begin.....................");mScanning = true;scan_flag = false;scan_btn.setText("停止扫描");mBluetoothAdapter.startLeScan(mLeScanCallback);} else{Log.i("Stop", "stoping................");mScanning = false;mBluetoothAdapter.stopLeScan(mLeScanCallback);scan_flag = true;}}/*** 蓝牙扫描回调函数 实现扫描蓝牙设备,回调蓝牙BluetoothDevice,可以获取name MAC等信息* * **/private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback(){@Overridepublic void onLeScan(final BluetoothDevice device, final int rssi,byte[] scanRecord){// TODO Auto-generated method stubrunOnUiThread(new Runnable(){@Overridepublic void run(){/* 讲扫描到设备的信息输出到listview的适配器 */mleDeviceListAdapter.addDevice(device);mleDeviceListAdapter.notifyDataSetChanged();}});}};/*** @Description: TODO<自定义适配器Adapter,作为listview的适配器>* @version: V1.0*/private class LeDeviceListAdapter extends BaseAdapter {private ArrayList<BluetoothDevice> mLeDevices;private LayoutInflater mInflator;public LeDeviceListAdapter(){super();//rssis = new ArrayList();mLeDevices = new ArrayList();mInflator = getLayoutInflater();}public void addDevice(BluetoothDevice device){if (!mLeDevices.contains(device)){mLeDevices.add(device);}}public BluetoothDevice getDevice(int position){return mLeDevices.get(position);}public void clear(){mLeDevices.clear();rssis.clear();}@Overridepublic int getCount(){return mLeDevices.size();}@Overridepublic Object getItem(int i){return mLeDevices.get(i);}@Overridepublic long getItemId(int i){return i;}/*** 重写getview* * **/@Overridepublic View getView(int i, View view, ViewGroup viewGroup){// General ListView optimization code.// 加载listview每一项的视图view = mInflator.inflate(R.layout.listitem, null);// 初始化三个textview显示蓝牙信息//TextView deviceAddress =  view//     .findViewById(R.id.tv_deviceAddr);TextView deviceName =  view.findViewById(R.id.tv_deviceName);//TextView rssi =view.findViewById(R.id.tv_rssi);BluetoothDevice device = mLeDevices.get(i);//deviceAddress.setText(device.getAddress());deviceName.setText(device.getName());//rssi.setText("" + rssis.get(i));return view;}}}

main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="${relativePackage}.${activityClass}" ><Button android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="20dip"android:layout_marginRight="20dip"android:layout_marginTop="30dip"android:text="扫描设备"android:id="@+id/scan_dev_btn"/><ListViewandroid:id="@+id/lv"android:layout_marginTop="100dip"android:layout_marginLeft="20dip"android:layout_marginRight="20dip"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginBottom="50dip" >
</ListView></RelativeLayout>

listyview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" android:background="@drawable/bg_button"><LinearLayoutandroid:layout_width="match_parent"android:background="#00BA79"android:layout_height="wrap_content" ><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#ffffff"android:textSize="25dp"android:text="设备名称:" /><TextViewandroid:id="@+id/tv_deviceName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#ffffff"android:textSize="25dp"android:text="TextView" /></LinearLayout></LinearLayout>

Ble_activity

package com.severn.ui;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.severn.service.*;
import android.app.Activity;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;import com.severn.R;
import com.severn.service.BluetoothLeService;/** * @Description:  TODO<Ble_Activity实现连接BLE,发送和接受BLE的数据> */
public class Ble_Activity extends Activity implements OnClickListener {private final static String TAG = Ble_Activity.class.getSimpleName();//蓝牙4.0的UUID,其中0000ffe1-0000-1000-8000-00805f9b34fb是广州汇承信息科技有限公司08蓝牙模块的UUIDpublic static String HEART_RATE_MEASUREMENT = "0000ffe1-0000-1000-8000-00805f9b34fb";public static String EXTRAS_DEVICE_NAME = "DEVICE_NAME";;public static String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";public static String EXTRAS_DEVICE_RSSI = "RSSI";//蓝牙连接状态private boolean mConnected = false;private String status = "disconnected";//蓝牙名字private String mDeviceName;//蓝牙地址private String mDeviceAddress;//蓝牙信号值private String mRssi;private Bundle b;private String rev_str = "";//蓝牙service,负责后台的蓝牙服务private static BluetoothLeService mBluetoothLeService;//文本框,显示接受的内容private TextView rev_tv, connect_state;//发送按钮private Button send_btn;//文本编辑框private EditText send_et;private ScrollView rev_sv;private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();//蓝牙特征值private static BluetoothGattCharacteristic target_chara = null;private Handler mhandler = new Handler();private Handler myHandler = new Handler(){// 2.重写消息处理函数public void handleMessage(Message msg){switch (msg.what){// 判断发送的消息case 1:{// 更新ViewString state = msg.getData().getString("connect_state");connect_state.setText(state);break;}}super.handleMessage(msg);}};@Overrideprotected void onCreate(Bundle savedInstanceState){// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.ble_activity);b = getIntent().getExtras();//从意图获取显示的蓝牙信息mDeviceName = b.getString(EXTRAS_DEVICE_NAME);mDeviceAddress = b.getString(EXTRAS_DEVICE_ADDRESS);//mRssi = b.getString(EXTRAS_DEVICE_RSSI);/* 启动蓝牙service */Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);init();}@Overrideprotected void onDestroy(){super.onDestroy();//解除广播接收器unregisterReceiver(mGattUpdateReceiver);mBluetoothLeService = null;}// Activity出来时候,绑定广播接收器,监听蓝牙连接服务传过来的事件@Overrideprotected void onResume(){super.onResume();//绑定广播接收器registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());if (mBluetoothLeService != null){    //根据蓝牙地址,建立连接final boolean result = mBluetoothLeService.connect(mDeviceAddress);Log.d(TAG, "Connect request result=" + result);}}/** * @Title: init * @Description: TODO(初始化UI控件) * @param  无* @return void    * @throws */ private void init(){rev_sv = (ScrollView) this.findViewById(R.id.rev_sv);rev_tv = (TextView) this.findViewById(R.id.rev_tv);connect_state = (TextView) this.findViewById(R.id.connect_state);send_btn = (Button) this.findViewById(R.id.send_btn);send_et = (EditText) this.findViewById(R.id.send_et);connect_state.setText(status);send_btn.setOnClickListener(this);}/* BluetoothLeService绑定的回调函数 */private final ServiceConnection mServiceConnection = new ServiceConnection(){@Overridepublic void onServiceConnected(ComponentName componentName,IBinder service){mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();if (!mBluetoothLeService.initialize()){Log.e(TAG, "Unable to initialize Bluetooth");finish();}// 根据蓝牙地址,连接设备mBluetoothLeService.connect(mDeviceAddress);}@Overridepublic void onServiceDisconnected(ComponentName componentName){mBluetoothLeService = null;}};/*** 广播接收器,负责接收BluetoothLeService类发送的数据*/private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver(){@Overridepublic void onReceive(Context context, Intent intent){final String action = intent.getAction();if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action))//Gatt连接成功{mConnected = true;status = "connected";//更新连接状态updateConnectionState(status);System.out.println("BroadcastReceiver :" + "device connected");} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED//Gatt连接失败.equals(action)){mConnected = false;status = "disconnected";//更新连接状态updateConnectionState(status);System.out.println("BroadcastReceiver :"+ "device disconnected");} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED//发现GATT服务器.equals(action)){// Show all the supported services and characteristics on the// user interface.//获取设备的所有蓝牙服务displayGattServices(mBluetoothLeService.getSupportedGattServices());System.out.println("BroadcastReceiver :"+ "device SERVICES_DISCOVERED");} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action))//有效数据{    //处理发送过来的数据displayData(intent.getExtras().getString(BluetoothLeService.EXTRA_DATA));System.out.println("BroadcastReceiver onData:"+ intent.getStringExtra(BluetoothLeService.EXTRA_DATA));}}};/* 更新连接状态 */private void updateConnectionState(String status){Message msg = new Message();msg.what = 1;Bundle b = new Bundle();b.putString("connect_state", status);msg.setData(b);//将连接状态更新的UI的textview上myHandler.sendMessage(msg);System.out.println("connect_state:" + status);}/* 意图过滤器 */private static IntentFilter makeGattUpdateIntentFilter(){final IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);return intentFilter;}/** * @Title: displayData * @Description: TODO(接收到的数据在scrollview上显示) * @param @param rev_string(接受的数据)* @return void   * @throws */ private void displayData(String rev_string){rev_str += rev_string;runOnUiThread(new Runnable(){@Overridepublic void run(){rev_tv.setText(rev_str);rev_sv.scrollTo(0, rev_tv.getMeasuredHeight());System.out.println("rev:" + rev_str);}});}/** * @Title: displayGattServices * @Description: TODO(处理蓝牙服务) * @param 无  * @return void  * @throws */ private void displayGattServices(List<BluetoothGattService> gattServices){if (gattServices == null)return;String uuid = null;// 服务数据,可扩展下拉列表的第一级数据ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();// 特征数据(隶属于某一级服务下面的特征值集合)ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>();// 部分层次,所有特征值集合mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();// Loops through available GATT Services.for (BluetoothGattService gattService : gattServices){// 获取服务列表HashMap<String, String> currentServiceData = new HashMap<String, String>();uuid = gattService.getUuid().toString();// 查表,根据该uuid获取对应的服务名称。SampleGattAttributes这个表需要自定义。gattServiceData.add(currentServiceData);System.out.println("Service uuid:" + uuid);ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>();// 从当前循环所指向的服务中读取特征值列表List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();// Loops through available Characteristics.// 对于当前循环所指向的服务中的每一个特征值for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics){charas.add(gattCharacteristic);HashMap<String, String> currentCharaData = new HashMap<String, String>();uuid = gattCharacteristic.getUuid().toString();if (gattCharacteristic.getUuid().toString().equals(HEART_RATE_MEASUREMENT)){// 测试读取当前Characteristic数据,会触发mOnDataAvailable.onCharacteristicRead()mhandler.postDelayed(new Runnable(){@Overridepublic void run(){// TODO Auto-generated method stubmBluetoothLeService.readCharacteristic(gattCharacteristic);}}, 200);// 接受Characteristic被写的通知,收到蓝牙模块的数据后会触发mOnDataAvailable.onCharacteristicWrite()mBluetoothLeService.setCharacteristicNotification(gattCharacteristic, true);target_chara = gattCharacteristic;// 设置数据内容// 往蓝牙模块写入数据// mBluetoothLeService.writeCharacteristic(gattCharacteristic);}List<BluetoothGattDescriptor> descriptors = gattCharacteristic.getDescriptors();for (BluetoothGattDescriptor descriptor : descriptors){System.out.println("---descriptor UUID:"+ descriptor.getUuid());// 获取特征值的描述mBluetoothLeService.getCharacteristicDescriptor(descriptor);// mBluetoothLeService.setCharacteristicNotification(gattCharacteristic,// true);}gattCharacteristicGroupData.add(currentCharaData);}// 按先后顺序,分层次放入特征值集合中,只有特征值mGattCharacteristics.add(charas);// 构件第二级扩展列表(服务下面的特征值)gattCharacteristicData.add(gattCharacteristicGroupData);}}/*** 将数据分包* * **/public int[] dataSeparate(int len){   int[] lens = new int[2];lens[0]=len/20;lens[1]=len-20*lens[0];return lens;}/* * 发送按键的响应事件,主要发送文本框的数据*/@Overridepublic void onClick(View v){// TODO Auto-generated method stubbyte[] buff = send_et.getText().toString().getBytes();int len = buff.length;int[] lens = dataSeparate(len);for(int i =0;i<lens[0];i++){String str = new String(buff, 20*i, 20);target_chara.setValue(str);//只能一次发送20字节,所以这里要分包发送//调用蓝牙服务的写特征值方法实现发送数据mBluetoothLeService.writeCharacteristic(target_chara);}if(lens[1]!=0){String str = new String(buff, 20*lens[0], lens[1]);target_chara.setValue(str);//调用蓝牙服务的写特征值方法实现发送数据mBluetoothLeService.writeCharacteristic(target_chara);}}}

ble_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><LinearLayout android:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="状态:"android:layout_marginLeft="10dip"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/connect_state"/></LinearLayout><ScrollViewandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:id="@+id/rev_sv"><TextView android:layout_width="fill_parent"android:layout_height="wrap_content"android:id="@+id/rev_tv"/></ScrollView><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_gravity="bottom"android:orientation="horizontal" ><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:id="@+id/send_et"android:typeface="normal" ></EditText><Buttonandroid:id="@+id/send_btn"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="3"android:text="send" /></LinearLayout></LinearLayout>

BluetoothLeService.class

package com.severn.service;import java.util.ArrayList;
import java.util.List;
import java.util.UUID;import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;/** * @Description:  TODO<蓝牙服务,负责在后台实现蓝牙的连接,数据的发送接受> */
public class BluetoothLeService extends Service {private final static String TAG = "BluetoothLeService";// luetoothLeService.class.getSimpleName();private List<Sensor> mEnabledSensors = new ArrayList<Sensor>();//蓝牙相关类private BluetoothManager mBluetoothManager;private BluetoothAdapter mBluetoothAdapter;private String mBluetoothDeviceAddress;private BluetoothGatt mBluetoothGatt;private int mConnectionState = STATE_DISCONNECTED;private static final int STATE_DISCONNECTED = 0;private static final int STATE_CONNECTING = 1;private static final int STATE_CONNECTED = 2;public final static String ACTION_GATT_CONNECTED = "com.hc_ble.bluetooth.le.ACTION_GATT_CONNECTED";public final static String ACTION_GATT_DISCONNECTED = "com.hc_ble.bluetooth.le.ACTION_GATT_DISCONNECTED";public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.hc_ble.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";public final static String ACTION_DATA_AVAILABLE = "com.hc_ble.bluetooth.le.ACTION_DATA_AVAILABLE";public final static String EXTRA_DATA = "com.hc_ble.bluetooth.le.EXTRA_DATA";// public final static UUID UUID_HEART_RATE_MEASUREMENT =zzzzzzzzzzzzz// UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);private OnDataAvailableListener mOnDataAvailableListener;// Implements callback methods for GATT events that the app cares about. For// example,// connection change and services discovered.public interface OnDataAvailableListener {public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status);public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic);public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic);}public void setOnDataAvailableListener(OnDataAvailableListener l){mOnDataAvailableListener = l;}/* 连接远程设备的回调函数 */private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback(){@Overridepublic void onConnectionStateChange(BluetoothGatt gatt, int status,int newState){String intentAction;if (newState == BluetoothProfile.STATE_CONNECTED)//连接成功{intentAction = ACTION_GATT_CONNECTED;mConnectionState = STATE_CONNECTED;/* 通过广播更新连接状态 */broadcastUpdate(intentAction);Log.i(TAG, "Connected to GATT server.");// Attempts to discover services after successful connection.Log.i(TAG, "Attempting to start service discovery:"+ mBluetoothGatt.discoverServices());} else if (newState == BluetoothProfile.STATE_DISCONNECTED)//连接失败{intentAction = ACTION_GATT_DISCONNECTED;mConnectionState = STATE_DISCONNECTED;Log.i(TAG, "Disconnected from GATT server.");broadcastUpdate(intentAction);}}/** 重写onServicesDiscovered,发现蓝牙服务* * */@Overridepublic void onServicesDiscovered(BluetoothGatt gatt, int status){if (status == BluetoothGatt.GATT_SUCCESS)//发现到服务{broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);Log.i(TAG, "--onServicesDiscovered called--");} else{Log.w(TAG, "onServicesDiscovered received: " + status);System.out.println("onServicesDiscovered received: " + status);}}/** 特征值的读写* */@Overridepublic void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status){if (status == BluetoothGatt.GATT_SUCCESS){Log.i(TAG, "--onCharacteristicRead called--");//从特征值读取数据byte[] sucString = characteristic.getValue();String string = new String(sucString);//将数据通过广播到Ble_ActivitybroadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);}}/** 特征值的改变* */@Overridepublic void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic){broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);}/** 特征值的写* */@Overridepublic void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status){// 以下语句实现 发送完数据或也显示到界面上//broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);}/** 读描述值* */@Overridepublic void onDescriptorRead(BluetoothGatt gatt,BluetoothGattDescriptor descriptor, int status){// TODO Auto-generated method stub// super.onDescriptorRead(gatt, descriptor, status);Log.w(TAG, "----onDescriptorRead status: " + status);byte[] desc = descriptor.getValue();if (desc != null){Log.w(TAG, "----onDescriptorRead value: " + new String(desc));}}/** 写描述值* */@Overridepublic void onDescriptorWrite(BluetoothGatt gatt,BluetoothGattDescriptor descriptor, int status){// TODO Auto-generated method stub// super.onDescriptorWrite(gatt, descriptor, status);Log.w(TAG, "--onDescriptorWrite--: " + status);}/** 读写蓝牙信号值* */@Overridepublic void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status){// TODO Auto-generated method stub// super.onReadRemoteRssi(gatt, rssi, status);Log.w(TAG, "--onReadRemoteRssi--: " + status);broadcastUpdate(ACTION_DATA_AVAILABLE, rssi);}@Overridepublic void onReliableWriteCompleted(BluetoothGatt gatt, int status){// TODO Auto-generated method stub// super.onReliableWriteCompleted(gatt, status);Log.w(TAG, "--onReliableWriteCompleted--: " + status);}};//广播意图private void broadcastUpdate(final String action, int rssi){final Intent intent = new Intent(action);intent.putExtra(EXTRA_DATA, String.valueOf(rssi));sendBroadcast(intent);}//广播意图private void broadcastUpdate(final String action){final Intent intent = new Intent(action);sendBroadcast(intent);}/* 广播远程发送过来的数据 */public void broadcastUpdate(final String action,final BluetoothGattCharacteristic characteristic){final Intent intent = new Intent(action);//从特征值获取数据final byte[] data = characteristic.getValue();if (data != null && data.length > 0){final StringBuilder stringBuilder = new StringBuilder(data.length);for (byte byteChar : data){stringBuilder.append(String.format("%02X ", byteChar));Log.i(TAG, "***broadcastUpdate: byteChar = " + byteChar);}intent.putExtra(EXTRA_DATA, new String(data));System.out.println("broadcastUpdate for  read data:"+ new String(data));}sendBroadcast(intent);}public class LocalBinder extends Binder {public BluetoothLeService getService(){return BluetoothLeService.this;}}@Overridepublic IBinder onBind(Intent intent){return mBinder;}@Overridepublic boolean onUnbind(Intent intent){close();return super.onUnbind(intent);}private final IBinder mBinder = new LocalBinder();/*** Initializes a reference to the local Bluetooth adapter.* * @return Return true if the initialization is successful.*//* service 中蓝牙初始化 */public boolean initialize(){// For API level 18 and above, get a reference to BluetoothAdapter// through// BluetoothManager.if (mBluetoothManager == null){   //获取系统的蓝牙管理器mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);if (mBluetoothManager == null){Log.e(TAG, "Unable to initialize BluetoothManager.");return false;}}mBluetoothAdapter = mBluetoothManager.getAdapter();if (mBluetoothAdapter == null){Log.e(TAG, "Unable to obtain a BluetoothAdapter.");return false;}return true;}/*** Connects to the GATT server hosted on the Bluetooth LE device.* * @param address*            The device address of the destination device.* * @return Return true if the connection is initiated successfully. The*         connection result is reported asynchronously through the*         {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}*         callback.*/// 连接远程蓝牙public boolean connect(final String address){if (mBluetoothAdapter == null || address == null){Log.w(TAG,"BluetoothAdapter not initialized or unspecified address.");return false;}// Previously connected device. Try to reconnect.if (mBluetoothDeviceAddress != null&& address.equals(mBluetoothDeviceAddress)&& mBluetoothGatt != null){Log.d(TAG,"Trying to use an existing mBluetoothGatt for connection.");if (mBluetoothGatt.connect())//连接蓝牙,其实就是调用BluetoothGatt的连接方法{mConnectionState = STATE_CONNECTING;return true;} else{return false;}}/* 获取远端的蓝牙设备 */final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);if (device == null){Log.w(TAG, "Device not found.  Unable to connect.");return false;}// We want to directly connect to the device, so we are setting the// autoConnect// parameter to false./* 调用device中的connectGatt连接到远程设备 */mBluetoothGatt = device.connectGatt(this, false, mGattCallback);Log.d(TAG, "Trying to create a new connection.");mBluetoothDeviceAddress = address;mConnectionState = STATE_CONNECTING;System.out.println("device.getBondState==" + device.getBondState());return true;}/*** Disconnects an existing connection or cancel a pending connection. The* disconnection result is reported asynchronously through the* {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}* callback.*//** 取消连接* * *//** * @Title: disconnect * @Description: TODO(取消蓝牙连接) * @param   无* @return void    * @throws */ public void disconnect(){if (mBluetoothAdapter == null || mBluetoothGatt == null){Log.w(TAG, "BluetoothAdapter not initialized");return;}mBluetoothGatt.disconnect();}/*** After using a given BLE device, the app must call this method to ensure* resources are released properly.*//** * @Title: close * @Description: TODO(关闭所有蓝牙连接) * @param  无* @return void   * @throws */ public void close(){if (mBluetoothGatt == null){return;}mBluetoothGatt.close();mBluetoothGatt = null;}/*** Request a read on a given {@code BluetoothGattCharacteristic}. The read* result is reported asynchronously through the* {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}* callback.* * @param characteristic*            The characteristic to read from.*//** * @Title: readCharacteristic * @Description: TODO(读取特征值) * @param @param characteristic(要读的特征值)* @return void    返回类型 * @throws */ public void readCharacteristic(BluetoothGattCharacteristic characteristic){if (mBluetoothAdapter == null || mBluetoothGatt == null){Log.w(TAG, "BluetoothAdapter not initialized");return;}mBluetoothGatt.readCharacteristic(characteristic);}// 写入特征值public void writeCharacteristic(BluetoothGattCharacteristic characteristic){if (mBluetoothAdapter == null || mBluetoothGatt == null){Log.w(TAG, "BluetoothAdapter not initialized");return;}mBluetoothGatt.writeCharacteristic(characteristic);}// 读取RSSipublic void readRssi(){if (mBluetoothAdapter == null || mBluetoothGatt == null){Log.w(TAG, "BluetoothAdapter not initialized");return;}mBluetoothGatt.readRemoteRssi();}/*** Enables or disables notification on a give characteristic.* * @param characteristic*            Characteristic to act on.* @param enabled*            If true, enable notification. False otherwise.*//** * @Title: setCharacteristicNotification * @Description: TODO(设置特征值通变化通知) * @param @param characteristic(特征值)* @param @param enabled (使能)   * @return void    * @throws */ public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled){if (mBluetoothAdapter == null || mBluetoothGatt == null){Log.w(TAG, "BluetoothAdapter not initialized");return;}mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));if (enabled){clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);} else{clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);}mBluetoothGatt.writeDescriptor(clientConfig);}/** * @Title: getCharacteristicDescriptor * @Description: TODO(得到特征值下的描述值) * @param @param 无* @return void   * @throws */ public void getCharacteristicDescriptor(BluetoothGattDescriptor descriptor){if (mBluetoothAdapter == null || mBluetoothGatt == null){Log.w(TAG, "BluetoothAdapter not initialized");return;}mBluetoothGatt.readDescriptor(descriptor);}/*** Retrieves a list of supported GATT services on the connected device. This* should be invoked only after {@code BluetoothGatt#discoverServices()}* completes successfully.* * @return A {@code List} of supported services.*//** * @Title: getSupportedGattServices * @Description: TODO(得到蓝牙的所有服务) * @param @return    无* @return List<BluetoothGattService>    * @throws */ public List<BluetoothGattService> getSupportedGattServices(){if (mBluetoothGatt == null)return null;return mBluetoothGatt.getServices();}}

Androidmainfest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.severn"android:versionCode="1"android:versionName="1.2" ><uses-permission android:name="android.permission.BLUETOOTH"/><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/><uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/><applicationandroid:allowBackup="true"android:icon="@drawable/hc"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid: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><activity android:name=".ui.Ble_Activity"></activity><service android:name="com.huicheng.service.BluetoothLeService" android:enabled="true"></service></application></manifest>

单片机与手机应用进行蓝牙通讯相关推荐

  1. 手机app和单片机蓝牙通讯c语言,单片机怎么和手机通信,你知道吗?

    原标题:单片机怎么和手机通信,你知道吗? 在用单片机做产品的时候,难免会用到单片机和手机通信,能和手机通信的方案有很多这种,像常用的蓝牙,Wifi等等,当然还有更高层次的通过互联网,一般我们使用比较多 ...

  2. 51单片机蓝牙通讯精准控制步进电机简易教学

    51单片机蓝牙通讯精准控制步进电机 1.蓝牙模块 本次用到的蓝牙模块为HC-05,关于HC-05怎么配置的文章已经写过很多,这里就不一一介绍了,我下面具体讲一些关于单片机蓝牙数据的收发简单快捷的方法实 ...

  3. microbit编程_使用图形化编程实现主控板与手机蓝牙通讯(2019.3.25)

    本文转自:DFRobot创客社区 原文链接: [Mind+]使用图形化编程实现主控板与手机蓝牙通讯-Mind+论坛-DF创客社区​mc.dfrobot.com.cn 本帖最后由 Forgotten 于 ...

  4. 蓝牙通讯调试方法-windows与手机

    需要做个安卓端蓝牙连接.收发数据的APP,程序写完需要测试,可惜不是有两个手机的人............ 笔记本自带蓝牙,但是尝试查找蓝牙专用的调试工具没有,然后考虑怎么把蓝牙变为串口(差点一冲动买 ...

  5. 小白学习HC-05蓝牙透传模块(有实例讲解——自制手机app实现蓝牙控制单片机加热系统)第一天 :整体分析,理清思路

    小编刚开始接触HC-05蓝牙透传模块,只是感到很神奇.但对它的原理和使用方法一无所知.做项目要用到它的时候,无非就是代码复制粘贴,有种照搬照抄的意思. 但是今天小编要谈谈一段时间内对HC-05学习的心 ...

  6. 源代码,基于Stm32f030单片机开发日历显示,内部包括,按键检测、蓝牙通讯、温度传感器读取以及贪吃蛇游戏

    源代码,基于Stm32f030单片机开发日历显示,内部包括,按键检测.蓝牙通讯.温度传感器读取以及贪吃蛇游戏. OLED 屏幕的i2c驱动代码. 非常是初学者用于参考学习. :862564016125 ...

  7. 快速实现单片机和手机蓝牙通信

    Core和手机通过Ble蓝牙进行通信 重磅更新! 一.实现功能 二.实现机制 三.完整代码 四.演示 重磅更新! shineblink.com 已推出免开发App,开发者无需做任何安卓或IOS开发,即 ...

  8. arduino蓝牙通讯代码_通过手机控制蓝牙串口模块与Arduino通讯

    功能 通过手机APP向蓝牙模块发送指令,蓝牙模块通过串口将指令传递给Arduino开发板,并由Arduino做出反馈,传递给手机. 工具材料Arduino 开发板 ×1 蓝牙串口模块×1 Androi ...

  9. 51单片机期末课程作业之蓝牙、操控、测速、里程小车

    文章底部附源码 课程设计报告 学 科:单片机原理及应用 项 目:里程记录仪 学 院: 专业.年级: 指导老师: 摘要 设计首先实现对小车行驶时的平均速度.即时速度以及里程等行驶参量的实时测量和显示功能 ...

最新文章

  1. Java谜题:等于,还是不等于?
  2. c语言降序多项式加法,数据结构算法(多项式加法)的C语言完美实现
  3. c语言中ai是什么,科普 | 什么是 cDai?
  4. 系统管理员设置了系统策略 禁止进行此安装的修改办法
  5. CentOS 6 系统优化检测脚本
  6. docker下载地址及 设置自己的阿里云镜像加速器,Kubernetes(K8S) 安装
  7. ASP.NET MVC的客户端验证:jQuery验证在Model验证中的实现
  8. html表格基础及案例示图代码。
  9. win7计算机用户文件,如何修改win7系统桌面“用户”文件夹路径
  10. 如果你是互联网创业者,这个视频值1万元
  11. 给电脑装一个双系统Linux,安装Linux让你的电脑变成双系统的七个理由
  12. 《VERSE Versatile Graph Embeddings from Similarity Measures》阅读笔记
  13. 三角形法则平行四边形法则
  14. 怎么为PE添加输入法
  15. 团队项目:即时聊天软件 需求分析、用例、UI原型
  16. 10个小窍门,让你轻松准确搜索(转)
  17. linux安装界面键盘失灵,安装win7鼠标键盘失灵怎么办_win7安装界面鼠标键盘失灵解决方法【147下载站】...
  18. 翻译来自HiDDeN网络架构-Lifeifei
  19. Solidity中文文档(内部)
  20. 【Linux 常用命令】

热门文章

  1. 三角形外心坐标的计算公式
  2. Quantifying causality in data science with quasi-experiments
  3. 第三方支付机构是如何产生的?有着怎样的历史背景?它的未来又该如何去走得更加辉煌?
  4. 2023 最新 抖音AI换脸表情包小程序变现玩法项目
  5. mysql 插入数据报错,a foreign key constraint fails
  6. 薅羊毛!企业微信自动加好友工具免费使用机会!
  7. 猿创征文 |【算法入门必刷】数据结构-栈(三)
  8. 表达式的LenB(123程序设计ABC)的值是27吗
  9. python图片压缩原理_LZ77无损压缩算法原理详解(结合图片和简单代码)
  10. org.hibernate.MappingException: Unknown entity常见问题(新手需注意)