讲师博文
智能手环客户端详细设计 来源 : 未知     2018-09-21

1.1 客户端简介

1.1.1 界面操作

进入页面后,会自动进行扫描,以发现周围可用蓝牙设备。

在搜索蓝牙设备的多层中,会出现圆环形进度条,当设定的搜索时间到了之后,或者我们选中了被扫描到的设备,该进度条消失,“停止扫描”转换会“扫描”。

点击扫描到的设备进入控制设备控制页面。

这个页面是我们的主要控制界面,我们可以在这个界面看到手环为我们提供的一些数据。

这个下拉菜单可以同过点击也可以通过设备的menu按键获得,主要用来控制计步器。

“断开连接”的按钮的作用是显示现在设备的连接情况,如果不是已经连接了设备,那么可以看到“连接”按钮,可以通过“连接”按钮来实现和蓝牙设备的连接,如果是已经连接了的设备,可以看到“断开连接”,可以通过“断开连接”来断开和蓝牙设备的连接。

设置时间按钮,可以将我们的设备上的时间,同步到蓝牙手环上。

1.1.2 工程结构

Src为java文件目录。

Res为资源文件目录。

AndroidManifest.xml为配置文件。

在src目录下:

Acticity包中,是工程的两个Activity活动相关的代码。

Service包中,是工程启动的服务相关代码。

Tools包中,是工具类相关代码。

UI包中,是自定义界面相关代码。

在资源文件夹中,包含了Layout,values,Drawable等资源文件夹:

其中layout中是布局文件,menu中,是菜单栏的布局文件,values中包括color,string,styles等设置。

1.2 代码分析

1.2.1 界面代码分析

本工程一共有两个主要显示界面,分别为扫描设备,和设备控制,通过两个活动—Activity来进行设置与控制。

扫描-----界面ScanningActivity

在onCreate中设定标题。

Java Code

public void onCreate(Bundle savedInstanceState){

getActionBar().setTitle(R.string.title_devices);

}

在扫描的时候,menu显示为“停止扫描”,并显示圆环进度条以提醒等待;在扫描结束时,menu显示为“扫描”。在界面中使用ListView展示扫描到的设备。

Java Code

/**

* 创建Menu菜单栏

*/

@Override

public boolean onCreateOptionsMenu(Menu menu)

{

getMenuInflater().inflate(R.menu.main, menu);

if (!mScanning)

{

menu.findItem(R.id.menu_stop).setVisible(false);

menu.findItem(R.id.menu_scan).setVisible(true);

menu.findItem(R.id.menu_refresh).setActionView(null);

} else{

menu.findItem(R.id.menu_stop).setVisible(true);

menu.findItem(R.id.menu_scan).setVisible(false);

menu.findItem(R.id.menu_refresh).setActionView(

R.layout.actionbar_indeterminate_progress);

}

return true;

}

/**

* Menu菜单栏被选择时

*/

@Override

public boolean onOptionsItemSelected(MenuItem item)

{

switch (item.getItemId())

{

case R.id.menu_scan:

mLeDeviceListAdapter.clear();

scanLeDevice(true);

break;

case R.id.menu_stop:

scanLeDevice(false);

break;

}

return true;

}

ListView显示扫描到的设备。

Java Code

@Override

protected void onResume(){

super.onResume();

if (!mBluetoothAdapter.isEnabled()){

if (!mBluetoothAdapter.isEnabled()){

Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

}

}

mLeDeviceListAdapter = new LeDeviceListAdapter();

setListAdapter(mLeDeviceListAdapter);

scanLeDevice(true);

}

点击ListView中的设备跳转到控制界面。

Java Code

@Override

protected void onListItemClick(ListView l, View v, int position, long id){

final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);

if (device == null) return;

final Intent intent = new Intent(this, DeviceControlActivity.class);

intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME, device.getName());

intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress());

if (mScanning) {

mBluetoothAdapter.stopLeScan(mLeScanCallback);

mScanning = false;

}

startActivity(intent);

}

设备控制-------界面DeviceControlActivity

在Activity中设置主界面:

Java Code

@Override

protected void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_device_control);

initShow();

btnTime.setOnClickListener(this);

final Intent intent = getIntent();

mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);

mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);

Toast.makeText(this, mDeviceAddress, Toast.LENGTH_SHORT).show();

getActionBar().setTitle(mDeviceName);

getActionBar().setDisplayHomeAsUpEnabled(true);

}

菜单栏包括两部分,一部分是显示“连接”或“断开连接”,一部分是隐藏的用以对计步功能进行设置。

Java Code

@Override

public boolean onCreateOptionsMenu(Menu menu){

getMenuInflater().inflate(R.menu.device_control, menu);

if (connected) {

menu.findItem(R.id.menu_connect).setVisible(false);

menu.findItem(R.id.menu_disconnect).setVisible(true);

}else{

menu.findItem(R.id.menu_connect).setVisible(true);

menu.findItem(R.id.menu_disconnect).setVisible(false);

}

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item){

int id = item.getItemId();

switch (id){

case R.id.setting_gogal:

showGogalDialog();

break;

case R.id.setting_reset:

showResetDialog();

break;

case R.id.setting_stop:

showStopDialog();

break;

case R.id.menu_connect:

mBleService.connect(mDeviceAddress);

return true;

case R.id.menu_disconnect:

mBleService.disconnect();

return true;

case android.R.id.home:

onBackPressed();

return true;

default:

break;

}

return super.onOptionsItemSelected(item);

}

1.2.2 蓝牙连接代码分析

扫描

蓝牙连接建立的过程中,首先要先扫描到设备。

在ScanningActivity中:

Java Code

public class ScanningActivity extends ListActivity{

private LeDeviceListAdapter mLeDeviceListAdapter;

private BluetoothAdapter mBluetoothAdapter;

private boolean mScanning;

private Handler mHandler;

private static final int REQUEST_ENABLE_BT = 1;

// Stops scanning after 10 seconds.

private static final long SCAN_PERIOD = 10000;

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mHandler = new Handler();

//PackageManager.FEATURE_BLUETOOTH_LE

if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){

Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();

finish();

}

//BluetoothManager

final BluetoothManager bluetoothManager =

(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

mBluetoothAdapter = bluetoothManager.getAdapter();

//BluetoothAdapter

if (mBluetoothAdapter == null){

Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();

finish();

return;

}

}

private void scanLeDevice(final boolean enable){

if (enable){

mHandler.postDelayed(new Runnable(){

@Override

public void run(){

mScanning = false;

mBluetoothAdapter.stopLeScan(mLeScanCallback);

invalidateOptionsMenu();

}

}, SCAN_PERIOD);

mScanning = true;

mBluetoothAdapter.startLeScan(mLeScanCallback);

}else{

mScanning = false;

mBluetoothAdapter.stopLeScan(mLeScanCallback);

}

invalidateOptionsMenu();

}

private BluetoothAdapter.LeScanCallback mLeScanCallback =

new BluetoothAdapter.LeScanCallback(){

@Override

public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord){

runOnUiThread(new Runnable(){

@Override

public void run(){

mLeDeviceListAdapter.addDevice(device);

mLeDeviceListAdapter.notifyDataSetChanged();

}

});

}

};

}

连接蓝牙

在扫描结束的时候,点击ListView上的设备名称的时候,将设备MAC通过Intent传递给DeviceControlActivity,在控制页面启动BLEService服务,控制设备连接。

Java Code

public class DeviceControlActivity extends Activity implements View.OnClickListener

{

private final String TAG = "Device";

private final Double G = 9.8;

public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";

public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";

private static String UUID_date = "0000180f-0000-1000-8000-00805f9b34fb";

private static String UUID_D = "00002a19-0000-1000-8000-00805f9b34fb";

private String UUID_write = "00001802-0000-1000-8000-00805f9b34fb";

private String UUID_W = "00002a06-0000-1000-8000-00805f9b34fb";

private Phone mPhone;

private BLEService mBleService;

private String mDeviceAddress;

private String mDeviceName;

private int xBefore, yBefore, zBefore;

private CircleBar mCircleBar;

private Button btnTime;

private TextView txvX, txvY, txvZ, txvPower;

private EditText gogalInput;

private boolean connected = false;

private boolean first = true;

private BluetoothGattCharacteristic mNotifyCharacteristic;

protected void onCreate(Bundle savedInstanceState){

//...

super.onCreate(savedInstanceState);

//bindService启动服务,注册广播接收器实现服务与活动之间的通信

Intent gattIntent = new Intent(this, BLEService.class);

bindService(gattIntent, mServiceConnection, BIND_AUTO_CREATE);

registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());

//实例化一个电话模型。

mPhone = new Phone(this);

}

@Override

protected void onResume(){

super.onResume();

registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());

if (mBleService != null){

final boolean result = mBleService.connect(mDeviceAddress);

Log.d(TAG, "Connect request result=" + result);

}

}

//服务连接

private final ServiceConnection mServiceConnection = new ServiceConnection(){

@Override

public void onServiceDisconnected(ComponentName name){

}

@Override

public void onServiceConnected(ComponentName name, IBinder service){

mBleService = ((BLEService.LocalBinder) service).getService();

if (!mBleService.initialize()){

Log.e(TAG, "unable to initilize Bluetooth Service");

finish();

}

mBleService.connect(mDeviceAddress);

}

};

}

BLEService服务代码如下:

Java Code

public class BLEService extends Service{

private BluetoothManager mBluetoothManager;

private BluetoothAdapter mBluetoothAdapter;

private String mBluetoothDeviceAddress;

public BluetoothGatt mBluetoothGatt;

public final static String ACTION_TIME_SETTING = "com.farsight.bluetooth.le.ACTION_TIME_SETTING";

public final static String ACTION_GATT_CONNECTED = "com.farsight.bluetooth.le.ACTION_GATT_CONNECTED";

public final static String ACTION_GATT_DISCONNECTED = "com.farsight.bluetooth.le.ACTION_GATT_DISCONNECTED";

public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.farsight.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";

public final static String ACTION_DATA_AVAILABLE = "com.farsight.bluetooth.le.ACTION_DATA_AVAILABLE";

public final static String EXTRA_DATA = "com.farsight.bluetooth.le.EXTRA_DATA";

public final static UUID UUID_FARSIGHT_SMART_WRIST = UUID.fromString(GattAttributes.FARSIGHT_SMART_WRIST);

/**

* 回调函数

*/

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback(){

@Override

public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState){

String intentAction;

if (newState == BluetoothProfile.STATE_CONNECTED){

mBluetoothGatt.getServices();

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);

}

}

//发现新服务

@Override

public void onServicesDiscovered(BluetoothGatt gatt, int status){

if (status == BluetoothGatt.GATT_SUCCESS){

broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);

}else{

Log.w("DSTTTTTTTTT", "onServicesDiscovered received: " + status);

}

}

//读到特征设备

@Override

public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status){

if (status == BluetoothGatt.GATT_SUCCESS){

broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);

}

}

@Override

public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic){

broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);

}

};

/**

* 通过广播发送数据

*/

private void broadcastUpdate(final String action){

final Intent intent = new Intent(action);

sendBroadcast(intent);

}

/**

* 通过广播发送数据

*/

private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic){

final Intent intent = new Intent(action);

// For all profiles, writes the data formatted in HEX.

final byte[] data = characteristic.getValue();

Log.d(TAG, data.length + "");

if (data != null && data.length > 0){

final StringBuilder stringBuilder = new StringBuilder(data.length);

for (byte byteChar : data)

stringBuilder.append(String.format("%02X ", byteChar));

// new String(data) + "\n" +

intent.putExtra(EXTRA_DATA, stringBuilder.toString());

}

sendBroadcast(intent);

}

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;

}

/**

* 连接

*/

public boolean connect(final String address){

if (mBluetoothAdapter == null || address == null){

Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");

return false;

}

if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null){

Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");

if (mBluetoothGatt.connect()){

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;

}

mBluetoothGatt = device.connectGatt(this, false, mGattCallback);

Log.d(TAG, "Trying to create a new connection.");

mBluetoothDeviceAddress = address;

mConnectionState = STATE_CONNECTING;

return true;

}

/**

* 可通知

*/

public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled){

if (mBluetoothAdapter == null || mBluetoothGatt == null){

Log.w(TAG, "BluetoothAdapter not initialized");

return;

}

mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

if (UUID_FARSIGHT_SMART_WRIST.equals(characteristic.getUuid())){

BluetoothGattDescriptor descriptor = characteristic

.getDescriptor(UUID.fromString(GattAttributes.CLIENT_CHARACTERISTIC_CONFIG));

descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);

mBluetoothGatt.writeDescriptor(descriptor);

}

}

/**

* 所有服务列表

*/

public List getSupportedGattServices(){

if (mBluetoothGatt == null)

return null;

return mBluetoothGatt.getServices();

}

1.2.3 信号处理

从蓝牙设备接收数据

这里我们使用设备接收来自蓝牙的通知即Notification信号,所以我们需要让我们的设备读取相应特征值的可通知信号。

在BLEService中:

Java Code

public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled)

{

if (mBluetoothAdapter == null || mBluetoothGatt == null)

{

Log.w(TAG, "BluetoothAdapter not initialized");

return;

}

mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

if (UUID_FARSIGHT_SMART_WRIST.equals(characteristic.getUuid()))

{

BluetoothGattDescriptor descriptor = characteristic

.getDescriptor(UUID.fromString(GattAttributes.CLIENT_CHARACTERISTIC_CONFIG));

descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);

mBluetoothGatt.writeDescriptor(descriptor);

}

}

在DeviceControlActivity中,通过广播接收器接收来自BLEService中的广播发出的信号:

Java Code

private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver(){

@Override

public void onReceive(Context context, Intent intent)

{

final String action = intent.getAction();

Log.d(TAG, action);

if (BLEService.ACTION_GATT_CONNECTED.equals(action))

{

connected = true;

invalidateOptionsMenu();

}

else if (BLEService.ACTION_GATT_DISCONNECTED.equals(action))

{

connected = false;

invalidateOptionsMenu();

}

else if (BLEService.ACTION_GATT_SERVICES_DISCOVERED.equals(action))

{

Log.d(TAG, "received Discoveryed");

if (first)

{

first = false;

}

getcharacteristic(mBleService.getSupportedGattServices());

}

else if (BLEService.ACTION_DATA_AVAILABLE.equals(action))

{

String data = intent.getStringExtra(BLEService.EXTRA_DATA);

setTribleAndPower(data);

getcharacteristic(mBleService.getSupportedGattServices());

Log.d("DATAIS", data);

}

}

};

当发现服务的时候,调用getcharacteristic(mBleService.getSupportedGattServices())以判断特征值是否是我们需要的。

Java Code

private void getcharacteristic(List gattServices){

String uuid = null;

Log.d(TAG, "++++++++++++++++++++++++++++++++++++++++++++");

for (BluetoothGattService gattService : gattServices) {

uuid = gattService.getUuid().toString();

Log.d(TAG, uuid);

if (uuid.equalsIgnoreCase(UUID_date)) {

List gattCharacteristics = gattService.getCharacteristics();

for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics)

uuid = gattCharacteristic.getUuid().toString();

Log.d(TAG, uuid + "characteristic");

if (uuid.equalsIgnoreCase(UUID_D)) {

final int charaProp = gattCharacteristic.getProperties();

if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {

// If there is an active notification on a

// characteristic, clear

if (mNotifyCharacteristic != null) {

mBleService.setCharacteristicNotification(mNotifyCharacteristic, false);

mNotifyCharacteristic = null;

}

mBleService.readCharacteristic(gattCharacteristic);

}

if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {

mNotifyCharacteristic = gattCharacteristic;

mBleService.setCharacteristicNotification(gattCharacteristic, true); }

}else{

continue;

}

}

}

}

当接收到ACTION_DATA_AVAILABLE广播的时候,读出广播中的数据,并通过数据对界面进行操作。

向蓝牙设备发送数据

电话状态监听类代码:

Java Code

package com.farsight.lastsmartwrist.tools;

import android.annotation.SuppressLint;

import android.content.Context;

import android.database.ContentObserver;

import android.database.Cursor;

import android.net.Uri;

import android.os.Handler;

import android.provider.CallLog;

import android.provider.CallLog.Calls;

import android.telephony.PhoneStateListener;

import android.telephony.TelephonyManager;

public class Phone

{

private boolean first = true;

public byte msgCount = 0;

public byte phoneCount = 0;

private Context context = null;

public BufferTool cmdBuf = null;

public Phone(Context con)

{

context = con;

cmdBuf = new BufferTool(1024);

TelephonyManager teleMgr = (TelephonyManager) context

.getSystemService(Context.TELEPHONY_SERVICE);

teleMgr.listen(new MyPhoneStateListener(),

PhoneStateListener.LISTEN_CALL_STATE);

registerObserver();

init();

}

// 刚开始就发送现有的数据

void init()

{

phoneCount = (byte) readMissCall();

cmdBuf.addBuffer((byte) 'a', 1, phoneCount);

msgCount = (byte) getNewSmsCount();

cmdBuf.addBuffer((byte) 'c', 1, msgCount);

}

public void Quit()

{

unregisterObserver();

}

// 监听来电

class MyPhoneStateListener extends PhoneStateListener

{

@Override

public void onCallStateChanged(int state, String incomingNumber)

{

if (state == TelephonyManager.CALL_STATE_RINGING)

{

cmdBuf.addBuffer((byte) 'b', incomingNumber.getBytes().length,

incomingNumber.getBytes());

}

else if (state == TelephonyManager.CALL_STATE_IDLE)

{

int tmp = readMissCall();

if (first == true)

{

phoneCount = (byte) (tmp);

first = false;

}

else

{

phoneCount = (byte) (tmp + 1);

}

cmdBuf.addBuffer((byte) 'a', 1, phoneCount);

}

}

}

// 监听短信

public ContentObserver newMmsContentObserver = new ContentObserver(

new Handler())

{

public void onChange(boolean selfChange)

{

if (cmdBuf.getVolume() == 0)

{

cmdBuf.addBuffer((byte) 'd', 1, (byte) (getNewSmsCount() + 1));// 发送短信通知

}

}

};

// 注册监听者

@SuppressLint("NewApi")

public void registerObserver()

{

unregisterObserver();

context.getContentResolver().registerContentObserver(

Uri.parse("content://sms"), true, newMmsContentObserver);

}

// 取消注册

public void unregisterObserver()

{

try

{

if (newMmsContentObserver != null)

{

context.getContentResolver().unregisterContentObserver(

newMmsContentObserver);

}

}

catch (Exception e)

{

}

}

// 获得短信条数

public int getNewSmsCount()

{

int result = 0;

Cursor csr = context.getContentResolver().query(

Uri.parse("content://sms"), null, "type = 1 and read = 0",

null, null);

if (csr != null)

{

result = csr.getCount();

csr.close();

return result;

}

else

{

return 0;

}

}

// 获得电话个数

public int readMissCall()

{

int result = 0;

Cursor cursor = context.getContentResolver().query(

CallLog.Calls.CONTENT_URI, new String[] { Calls.TYPE },

" type=? and new=?",

new String[] { Calls.MISSED_TYPE + "", "1" }, "date desc");

if (cursor != null)

{

result = cursor.getCount();

cursor.close();

return result;

}

else

{

return 0;

}

}

}

要发送的数据通过BuffTools来设置:

Java Code

package com.farsight.lastsmartwrist.tools;

mport java.util.Collection;

import java.util.HashMap;

import android.annotation.SuppressLint;

public class BufferTool

{

private int volume = 0;

private HashMap buffer = null;

@SuppressLint("UseSparseArrays")

public BufferTool(int dataVolume)

{

volume = dataVolume;

buffer = new HashMap(volume);

}

public synchronized Boolean addBuffer(byte[] data)

{

if (data != null)

{

if (buffer.size() < volume)

{

buffer.put(buffer.size(), data);

return true;

}

else

{

return false;

}

}

else

{

return false;

}

}

public synchronized Boolean addBuffer(int kind, int num, int msg)

{

byte[] cmdd = { (byte) kind, (byte) num, (byte) msg };

if (buffer.size() < volume)

}

else

{

return false;

}

}

public synchronized Boolean addBuffer(int kind, int num, byte[] msg)

{

byte[] cmdd = new byte[msg.length + 2];

cmdd[0] = (byte) kind;

cmdd[1] = (byte) num;

System.arraycopy(msg, 0, cmdd, 2, msg.length);

if (buffer.size() < volume)

{

buffer.put(buffer.size(), cmdd);

return true;

}

else

{

return false;

}

}

public synchronized Boolean addBuffer(int cmd)

{

byte[] cmdd = { (byte) cmd };

if (buffer.size() < volume)

{

buffer.put(buffer.size(), cmdd);

return true;

}

else

{

return false;

}

}

public synchronized byte[] getBuffer()

{

byte[] data = null;

if (buffer.size() > 0)

{

data = buffer.get(buffer.size() - 1);

buffer.remove(buffer.size() - 1);

}

else

{

}

return data;

}

public synchronized byte[][] getBuffer(int num)

{

byte[][] data = new byte[num][];

for (int i = 0; i < num; i++)

{

if (buffer.size() > 0)

{

data[i] = buffer.get(0);

buffer.remove(0);

}

else

{

data[i] = null;

break;

}

}

return data;

}

public synchronized byte[][] getAllBuffer()

{

if (buffer.isEmpty() == false)

{

int num = 0;

Collection Col = buffer.values();

int vol = Col.size();

byte[][] data = new byte[vol + 1][];

for (byte[] i : Col)

{

data[num] = i;

num++;

}

data[num] = null;

buffer.clear();

return data;

}

else

{

return null;

}

}

public synchronized int getVolume()

{

return buffer.size();

}

}

和接收数据时不一样的是,我们在发现服务和特征值之后,就应该去查看Phone实例中是否有未传输出去的数据,如果有,而且服务和特征值是我们要发送的设备的话,就要进行数据传送。

Java Code

private void getcharacteristic(List gattServices)

{

String uuid = null;

Log.d(TAG, "++++++++++++++++++++++++++++++++++++++++++++");

for (BluetoothGattService gattService : gattServices)

{

uuid = gattService.getUuid().toString();

Log.d(TAG, uuid);

if (uuid.equalsIgnoreCase(UUID_date))

{

。。。。

}

else if (uuid.equals(UUID_write))

{

List gattCharacteristics = gattService.getCharacteristics();

for (BluetoothGattCharacteristic bluetoothGattCharacteristic : gattCharacteristics)

{

uuid = bluetoothGattCharacteristic.getUuid().toString();

final BluetoothGattCharacteristic inBluetoothGattCharacteristic = bluetoothGattCharacteristic;

if (uuid.equals(UUID_W))

{

byte[] datas = null;

if (0 != mPhone.cmdBuf.getVolume())

{

}

while (null != (datas = mPhone.cmdBuf.getBuffer()))

{

inBluetoothGattCharacteristic.setValue(datas);

mBleService.mBluetoothGatt.writeCharacteristic(inBluetoothGattCharacteristic);

}

}

else

{

continue;

}

}

}

else

{

continue;

}

}

}

扫码申领本地嵌入式教学实录全套视频及配套源码

上一篇:安卓开发中实用的例子

下一篇:Android日志消息的生成

400-611-6270

Copyright © 2004-2024 华清远见教育科技集团 版权所有
京ICP备16055225号-5京公海网安备11010802025203号