手机BLE蓝牙通讯

Android的蓝牙开发,包括蓝牙的广播事件和扫描,蓝牙配对连接、数据传输等问题,本文着重讲BLE低功耗蓝牙4.0开发

AndroidMainifest权限:

    <uses-sdk
        android:minSdkVersion="18"
        android:targetSdkVersion="19" />

    <!--蓝牙权限-->
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <!--Android 5.0以上蓝牙好需要位置权限-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="andriod.permission.ACCESS_FINE_LOCATION"/>
    <!--设备支持BLE低功耗蓝牙 true -->
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"></uses-feature>

△低功耗蓝牙4.0开发:源码

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import android.app.Activity;
import android.app.AlertDialog;
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.BluetoothProfile;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageManager;
public class MainActivity extends Activity {
	private BluetoothAdapter mBluetoothAdapter;
	private Handler mHandler=new Handler();
	private boolean mScanning;
	private BluetoothGatt mGatt;
	private BluetoothGattCharacteristic mGattCharacteristic;
	
	private ListView mlv;//自定义列表listview
	private BleAdapter mBleAdapter;//自定义适配器adapter
	private ArrayList<BluetoothDevice> mArray=new ArrayList<BluetoothDevice>();//自定义容器
	private EditText mEdit;//自定义edittext
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initUI();
		initBLE();
	}
	
	@Override
	protected void onDestroy() {
		if(mGatt!=null){
			mGatt.close();
			mGatt=null;
		}
		super.onDestroy();
	}
	
	//初始化自定义控件
	private void initUI(){
		findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if(mGatt!=null){
					mGatt.close();
					mGatt=null;
				}
				scanLe(true);
			}
		});
		
		mlv = (ListView) findViewById(R.id.listView1);
		mBleAdapter = new BleAdapter(MainActivity.this,mArray);
    	mlv.setAdapter(mBleAdapter);
    	mlv.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
				if(mGatt==null){
				mGatt = mArray.get(position).connectGatt(MainActivity.this, false, mGattCallback);
				}else{
				mGatt.connect();	
				}
				
				new AlertDialog.Builder(MainActivity.this)
				.setTitle("请输入内容")
				.setView(mEdit=new EditText(MainActivity.this))
				.setPositiveButton("确定", new OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						mGattCharacteristic.setValue(mEdit.getText().toString().trim());
           			 	mGatt.writeCharacteristic(mGattCharacteristic);
					}
				})
				.show();
			}
		});
	}
	
	//初始化蓝牙4.0
	private void initBLE() {
		//如果不支持BLE则退出程序
		if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
		     Toast.makeText(this,"不支持低功耗蓝牙", Toast.LENGTH_SHORT).show();
		     finish();
		}
		//获取蓝牙适配器打开蓝牙
		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		if (mBluetoothAdapter!=null&&!mBluetoothAdapter.isEnabled()) {
		mBluetoothAdapter.enable();//自动打开蓝牙
		}
	}
	
    //开始扫描BLE
    private void scanLe(boolean enable) {
        if (enable) {
            if (mBluetoothAdapter.isEnabled()) {
                if (mScanning){
                return;
                }
                mArray.clear();
                mScanning = true;
                mHandler.postDelayed(mScanRunnable, 5000);//5秒后关闭扫描
                mBluetoothAdapter.startLeScan(mLeScanCallback);
            } else {
            	Toast.makeText(this,"蓝牙检测中", Toast.LENGTH_SHORT).show();
            }
        } else {
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
            mHandler.removeCallbacks(mScanRunnable);
            mScanning = false;
        }
    }
    
   //停止扫描BLE
    private final Runnable mScanRunnable = new Runnable() {
        @Override
        public void run() {
        	scanLe(false);
        }
    };
    
    //扫描结果
	private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        /**@param device:识别的远程设备
         * @param rssi: 信号值为远程蓝牙设备的报告,0代表没有蓝牙设备
         * @param scanRecord:远程设备提供的配对号
         */
        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
            MainActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //保存到本地:用来展示扫描得到的内容
                	if(!mArray.contains(device)){
                	Log.e("onLeScan","===设备"+device.getName()+"="+device.getAddress()+"="+rssi);
                	mArray.add(device);
                	mBleAdapter.notifyDataSetChanged();
                	}
                }
            });
        }
    };
    
	//通知
	public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled){
		mGatt.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);
		}
		mGatt.writeDescriptor(clientConfig);
	}
    
    //数据通讯监听
    private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status,int newState) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {//启动服务状态
                Log.e("======", "===开始启动服务:" + gatt.discoverServices());
            }
        };
        public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS){//发现服务状态
                 Log.e("======", "===发现服务");
                 List<BluetoothGattService> services = mGatt.getServices();
                 for(final BluetoothGattService gattService:services) {
                	 List<BluetoothGattCharacteristic> characteristics = gattService.getCharacteristics();
                	 for (final BluetoothGattCharacteristic gattCharacteristic : characteristics) {
                			 if (gattCharacteristic.getUuid().toString().equals
                					 ("0000ffe1-0000-1000-8000-00805f9b34fb")){
                			 mGattCharacteristic=gattCharacteristic;
                			 mHandler.postDelayed(new Runnable(){
         						@Override
         						public void run()
         						{
         						gatt.readCharacteristic(gattCharacteristic);
         						}
         					}, 200);
                			 
                			 setCharacteristicNotification(gattCharacteristic,true);
                			 List<BluetoothGattDescriptor> descriptors = gattCharacteristic.getDescriptors();
                			 for (BluetoothGattDescriptor descriptor : descriptors)
                			 {
                				 gatt.readDescriptor(descriptor);
                			 }
                		 }
                	 }
                 }
             }
        };
        public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,
        			int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {//写入状态
                 Log.e("======", "===写入" +new String(characteristic.getValue()));
            }
        };
       public void onCharacteristicRead(BluetoothGatt gatt,final BluetoothGattCharacteristic characteristic,
    		   	   int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {//读取状态
            	Log.e("======","===读取" +new String(characteristic.getValue()));
            }
       }
      public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {
    		  	Log.e("======", "===获取数据" +new String(characteristic.getValue()));//获取数据
      };
    };

}
	/**
	 * 蓝牙限制20字节需将数据分包
	 * **/
	public int[] dataSeparate(int len)
	{   
		int[] lens = new int[2];
		lens[0]=len/20;
		lens[1]=len-20*lens[0];
		return lens;
	}
	/* 
	 * 发送按键的响应事件,主要发送文本框的数据
	 */
	@Override
	public void onClick(View v)
	{
		// TODO Auto-generated method stub
		byte[] 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);
		mGattCharacteristic.setValue(str);//只能一次发送20字节,所以这里要分包发送
		//调用蓝牙服务的写特征值方法实现发送数据
		mBluetoothLeService.writeCharacteristic(mGattCharacteristic);
		}
		if(lens[1]!=0)
		{
			String str = new String(buff, 20*lens[0], lens[1]);
			mGattCharacteristic.setValue(str);
			//调用蓝牙服务的写特征值方法实现发送数据
			mBluetoothLeService.writeCharacteristic(mGattCharacteristic);
			
		}
	}

传统蓝牙:

1.打开蓝牙设备BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

mBluetoothAdapter.cancelDiscovery();
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);  
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(mReceiver, filter);
mBluetoothAdapter.startDiscovery();//搜索附近蓝牙

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
  public void onReceive(Context context, Intent intent) {
  String action = intent.getAction();  
  if (BluetoothDevice.ACTION_FOUND.equals(action)){
  //找到设备时 通过EXTRA_DEVICE附加域来得到一个BluetoothDevice设备  
  BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
  //信号强度  
  int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE); 
  }else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){
  //蓝牙配对或取消配对时的状态
  }  
  }
};
device.connectGatt(act, false, new BluetoothGattCallback() {
 public void onConnectionStateChange(android.bluetooth.BluetoothGatt gatt, int status, int newState) {
 if(status == 0&&newState == 2) {
 gatt.discoverServices();//搜索蓝牙周围服务
 }else{
 //"搜索失败"
 }
 };
 public void onServicesDiscovered(android.bluetooth.BluetoothGatt gatt, int status) {
 if(status == BluetoothGatt.GATT_SUCCESS){
 Iterator var4 = gatt.getServices().iterator();
 while(var4.hasNext()) {
 BluetoothGattService var3;
 BluetoothGattCharacteristic var5;
 BluetoothGattService next = (BluetoothGattService)var4.next();
 if((var3 = next).getUuid().equals(UUID.fromString("0000180f-0000-1000-8000-00805f9b34fb")) 
  && (var5 = var3.getCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb"))) != null) {
 gatt.readCharacteristic(var5);
 //"获取电量中…"
 }
 }
 }
 };
 public void onCharacteristicRead(final android.bluetooth.BluetoothGatt gatt, final android.bluetooth.BluetoothGattCharacteristic characteristic, final in t status) {
 act.runOnUiThread(new Runnable() {
 @Override
 public void run() {
 if(characteristic!=null&&status == BluetoothGatt.GATT_SUCCESS){
 //characteristic.getIntValue(17, 0)+"%电量"
 gatt.close();
 }
 }
 });
 };
} );
/** 
 * 根据Rssi获得返回的距离,返回数据单位为m 
 * @param rssi 
 * @return 
 */  
public static double getDistance(int rssi){  
    int iRssi = Math.abs(rssi);  
    double power = (iRssi-A_Value)/(10*n_Value); //A_Value=59发射端和接收端相隔1米时的信号强度,n_Value=2.0环境衰减因子
    return Math.pow(10,power);  
}

2.蓝牙连接有两种方式,可直接配对

String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";     
UUID uuid = UUID.fromString(SPP_UUID); 
mBluetoothAdapter= BluetoothAdapter.getDefaultAdapter();
mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(macAddress);
BluetoothSocket socket= mBluetoothDevice.createRfcommSocketToServiceRecord(uuid);//UUID连接!服务端为listenUsingRfcommWithServiceRecord("name",uuid)
mBluetoothAdapter.cancelDiscovery();  
socket.connect();
mBluetoothAdapter= BluetoothAdapter.getDefaultAdapter();
mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(macAddress);
Method m = mBluetoothDevice.getClass().getMethod(
		    		"createRfcommSocket", new Class[] { int.class });
BluetoothSocket socket = (BluetoothSocket) m.invoke(mBluetoothDevice, 1);//1-30端口连接!
mBluetoothAdapter.cancelDiscovery();  
socket.connect(); 
Method method = mBluetoothDevice.getClass().getMethod("createBond");//配对createBond/取消配对removeBond
Boolean returnValue = (Boolean) method.invoke(mBluetoothDevice);

3.蓝牙数据传输getInputStream getOutputStream

os = accept.getOutputStream();//输出流
os.write("连接成功success".getBytes());
is = socket.getInputStream();//输入流  
byte[] buffer=new byte[512];
int len=0;
ByteArrayBuffer bab = new ByteArrayBuffer(len);
while(-1!=(len=is.read(buffer))){
bab.append(buffer, 0, len);
}
String string = new String(bab.toByteArray(),"utf-8");

注意:BluetoothSocket的等耗时操作需要另外开启线程再进行!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C BLE蓝牙编程是指使用C语言编写蓝牙低功耗(BLE)相关应用程序的技术。BLE是一种低功耗、短距离无线通信技术,可用于连接蓝牙设备,如智能手机、手表、医疗设备等。C语言是一种广泛应用于系统级开发的计算机程序设计语言,适用于开发嵌入式系统、操作系统、网络设备等。因此,C BLE蓝牙编程可以在嵌入式系统、移动设备等各个领域得到应用。 C BLE蓝牙编程需要掌握蓝牙协议和BLE协议,了解各种的信号和数据传输方式。在C BLE蓝牙编程中,需要使用蓝牙标准库和操作系统提供的API,对蓝牙设备进行控制,并实现蓝牙通讯功能。开发人员需要具备扎实的C语言编程基础,了解Low-level driver编程,具备熟练的调试技能和了解硬件资源管理开发技能,才能开发出高质量的BLE应用程序。 总而言之,C BLE蓝牙编程是在掌握蓝牙协议、BLE协议和C语言编程基础的基础上,应用蓝牙标准库和操作系统提供的API,对蓝牙设备进行控制,实现BLE通讯功能的技术。开发人员需要具备专业的技术知识和扎实的编程基础,才能开发出高质量的BLE应用程序。 ### 回答2: C语言蓝牙编程是一种将蓝牙技术与C语言进行集成的编程方法。蓝牙技术是一种无线通信技术,它可以在短距离内无线传输数据,如音频、图像和其他数据。而C语言是一种十分流行的编程语言,拥有广泛的应用领域,如操作系统、网络编程和图形用户界面等。 在使用C语言进行蓝牙编程时,开发者需要掌握蓝牙技术的原理和常用的蓝牙协议,如RFCOMM、L2CAP和HID等。此外,开发者还需要了解蓝牙硬件和软件架构,以便进行相应的编程。 C语言蓝牙编程常用的工具包括BlueZ库、hci-tools和BlueDevil等。开发者可以通过这些工具包来编写C语言程序,实现蓝牙设备的操作和数据传输。 在实际应用中,C语言蓝牙编程有着广泛的应用场景,如智能家居、医疗设备、汽车电子和物联网设备等。在这些场景中,C语言蓝牙编程可以帮助开发者实现设备之间的数据交换和远程控制等功能。 总的来说,C语言蓝牙编程是一种十分有用的编程方法,它将C语言和蓝牙技术有机地结合起来,为开发者提供了一个强大的工具来实现各种数据传输和控制功能。 ### 回答3: BLE(Bluetooth Low Energy)是一种低功耗的蓝牙技术。它是一种为低功耗、短距离、无线数据传输设备而设计的通信协议。这种技术采用无线射频技术短距离传输数据,适用于需要花费较少电量并且数据量不大的各种设备,比如智能手表、健身器材、温度传感器等。 BLE编程的核心是开发一个BLE应用程序,该程序与一个或多个BLE外设(如心率传感器、温度传感器等)进行通信。BLE由两部分组成:周边设备和中央设备。周边设备是指提供服务并可被中央设备检测到的设备,而中央设备则是指发现和寻找周边设备的设备。 BLE编程需要使用适当的编程语言,如C、C++或Objective-C等。一般情况下,开发人员需要使用BLE库(如Bluez),用于访问BLE硬件和实现BLE通信。BLE库可以使用Bluez API或Bluez D-Bus API来访问,并提供广泛的功能,如扫描和连接BLE设备、服务发现和读取特性,以及写入和监听特性。 在BLE编程中,主要的任务是编写处理BLE连接和数据交换的代码,可以通过建立一个BLE链路并使用相应的BLE API与BLE外设通信。针对BLE外设设计服务和特性,可以提供特定数据类型、单个或多个属性,以及读取、写入或订阅某些特定事件的能力。 总之,BLE编程是一种现代的、低功耗、高效的通信技术,已经在众多应用场景中得到了广泛应用,需要开发人员具备相应的技能和经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值