概述:实现了BLE扫描、连接、读写、通知接收等操作。
1、扫描方法的回调函数更改
在android5.0(SDK 21)以上时,BluetoothAdapter.startLeScan()和stopLEScan已经过时,所以在5.0以上时需要判定android版本.
扫描代码:
private void scanLeDevice(final boolean enable) {
if (enable) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
}, SCAN_PERIOD);
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mLEScanner.startScan(filters, settings, mScanCallback);
}
} else {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
}
回调函数:
private ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
Log.i("callbackType", String.valueOf(callbackType));
Log.i("result", result.toString());
BluetoothDevice btDevice = result.getDevice();
connectToDevice(btDevice);
}
@Override
public void onBatchScanResults(List results) {
for (ScanResult sr : results) {
Log.i("ScanResult - Results", sr.toString());
}
}
@Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed", "Error Code: " + errorCode);
}
};
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() {
Log.i("onLeScan", device.toString());
connectToDevice(device);
}
});
}
};
2、Android6.0权限问题
在手机上编译调试时,由于android6.0系统APP权限改为手动添加,则在调试低版本android BLE程序时要在build.gradle中将targetSdkVersion改为23以下,否则会运行出错。要想完全解决该问题,则需要判断android系统版本,查看android6.0的权限文档对代码进行修改。
例如:
3、低功耗蓝牙读写通信
package com.example.lenovo.ss1003;
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.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import static android.bluetooth.BluetoothAdapter.STATE_DISCONNECTED;
/**
* Created by lenovo on 2016/11/8.
*/
public class BluetoothLeService extends Service {
//预定义
private Handler mHandler;
private final String LIST_NAME = "NAME";
private final String LIST_UUID = "UUID";
private final static String TAG = BluetoothLeService.class.getSimpleName();
private ArrayList> mGattCharateristics = new ArrayList>();//蓝牙数据描述对象链表
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private String mBluetoothDeviceAddress;
private BluetoothGatt bluetoothGatt;
public BluetoothGattService mBluetoothGattService;
private BluetoothGattCharacteristic mBluetoothGattCharacteristic;
private int mConnectionState = STATE_CONNECTED;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
static final String ACTION_GATT_CONNECTED = "com.example.bluetooth.le.ACTION_GATT_CONNECTED";
static final String ACTION_GATT_DISCONNECTED = "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
private static final String ACTION_GATT_SERVICES_DISCONNECTED = "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_GATT_WRITE="com.example.bluetooth.le.ACTION_WRITE";
static final String ACTION_DATA_AVAILABLE = "com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
static final String EXTRA_DATA = "com.example.bluetooth.le.EXTRA_DATA";
public final static UUID UUID_TENS_MEASUREMWNT = UUID.fromString(SampleGattAttributes.TENS_MEASUREMENT);
public final static UUID UUID_TENS_CHARACTERISTIC = UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG);
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
//获取蓝牙的连接状态,gatt客户端,status蓝牙连接操作成功后的连接状态,newState返回新的连接状态
@Override
public 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");
Log.i(TAG, "Attempting to start service discovery" + bluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server");
broadcastUpdate(intentAction);
}
}
//readCharacteristic的时候会触发
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
Log.e("---------------", "onCharacteristicRead可用");
}
}
//回调显示一个远程变化,broadcastUpdate更新变化数据;
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
Log.e("---------------", "onCharacteristicChanged可用");
}
@Override
public void onCharacteristicWrite(BluetoothGatt mBluetoothGatt,
BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(mBluetoothGatt, characteristic, status);
Log.e(TAG, "onCharWrite " + mBluetoothGatt.getDevice().getName()
+ " write "
+ characteristic.getUuid().toString()
+ " -> ");
}
@Override
public void onDescriptorRead(BluetoothGatt gatt,
BluetoothGattDescriptor descriptor, int status) {
Log.w("lwj", "lwj---onDescriptorRead");
// TODO Auto-generated method stub
//super.onDescriptorRead(gatt, descriptor, status);
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt,
BluetoothGattDescriptor descriptor, int status) {
UUID uuid = descriptor.getCharacteristic().getUuid();
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
Log.w("lwj", "lwj---onReadRemoteRssi");
// TODO Auto-generated method stub
super.onReadRemoteRssi(gatt, rssi, status);
}
@Override
public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
Log.w("lwj", "lwj---onReliableWriteCompleted");
// TODO Auto-generated method stub
super.onReliableWriteCompleted(gatt, status);
}
// 蓝牙连接后回调该函数,立即执行 onServicesDiscovered方法,下列Log都会在Android studio 的error中打印
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
// TODO Auto-generated method stub
super.onServicesDiscovered(gatt, status);
//discoverServices()函数的回调函数
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.e(TAG, "discoverServices完成");
mBluetoothGattService = gatt.getService(UUID_TENS_MEASUREMWNT);
//还需要进行判断是否为null
if (mBluetoothGattService == null) {
Log.e(TAG, "getService未成功");
} else {
Log.e(TAG, "getService成功");
}
//再通过mBluetoothGattService获得BluetoothGattCharacteri
mBluetoothGattCharacteristic =
mBluetoothGattService.getCharacteristic(UUID_TENS_CHARACTERISTIC);
//还需要在进行判断是否为null
if (mBluetoothGattCharacteristic == null) {
Log.e(TAG, "getCharacteristic未成功");
} else {
Log.e(TAG, "getCharacteristic成功");
}
}else {
Log.e(TAG, "discoverServices未完成");
// Toast.makeText(MainActivity.this, "discover不成功,请再尝试", Toast.LENGTH_LONG).show();
}
**Log.e("++++++++++++",displayGattServices(getSupportedGattServices()).get(3).get(7).toString());
//行为广播,可在已绑定的Acivity中获取;
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
}**
};
//广播发送,更新意图对象。
private void broadcastUpdate(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);
//如果TENS_MEASUREMWNT的UUID和获取设备UUID匹配;
if (UUID_TENS_MEASUREMWNT.equals(characteristic.getUuid())) {
int flag = characteristic.getProperties();//获取设备属性
int format = -1;
if ((flag & 0x01) != 0) {
format = BluetoothGattCharacteristic.FORMAT_UINT16;//将uuid转为16进制格式
Log.d(TAG, "Heart rate format UINT16");
} else {
format = BluetoothGattCharacteristic.FORMAT_UINT8;//将uuid转为8进制格式
Log.d(TAG, "Heart rate format UINT8");
}
//
final int TENS = characteristic.getIntValue(format, 1);
Log.d(TAG, String.format("Recevied TENS data:%d", TENS));
intent.putExtra(EXTRA_DATA, String.valueOf(TENS));//将心率的数据添加到intent对象中;
} else {
//如果数据是byte形式数据,将遍历数据并转化为String形式添加到intent中;
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));
intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
}
}
sendBroadcast(intent);//广播转发intent对象;
}
}
//继承Binder类实现BluetoothLeService 的getService方法;
public class LocalBinder extends Binder {
BluetoothLeService getService() {
return BluetoothLeService.this;
}
}
private final IBinder mBinder = new LocalBinder();
//绑定intent对象,作为intent和service之间的数据传递中间者。
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
//解除绑定
@Override
public boolean onUnbind(Intent intent) {
close();
return super.onUnbind(intent);
}
public boolean initialize() {
if (bluetoothManager == null) {
bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);//通过蓝牙管理者获取当前系统蓝牙服务
if (bluetoothManager == null) {
return false;
}
}
bluetoothAdapter = bluetoothManager.getAdapter();//获取适配器
if (bluetoothAdapter == null) {
return false;
}
return true;
}
/*
* 获取低功耗蓝牙设备后,连接到GATT服务
* 目的设备的地址作为参数;
* 连接初始化成功后异步连接到设备;
* */
//判断蓝牙是否可连接
public boolean Connect(final String address) {
if (bluetoothAdapter == null || address == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
return false;
}else if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
&& bluetoothGatt != null) {
Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
if (bluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device = bluetoothAdapter.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.
bluetoothGatt = device.connectGatt(this,true, mGattCallback);//true是设置自动连接蓝牙;
Log.e(TAG, "Trying to create a new connection.");
if(bluetoothGatt.connect()){
// Toast.makeText(this, "连接成功",Toast.LENGTH_LONG).show();
//连接成功后,再进行discoverServices()
//并在其回调函数中执行getService(),获得BluetoothGattService
if(bluetoothGatt.discoverServices()){
Log.e(TAG, "discoverServices已经开始了");
}else{
Log.e(TAG, "discoverServices没有开始");
}
}
else{
Toast.makeText(this, "未连接成功,请再尝试", Toast.LENGTH_LONG).show();
}
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
public void DisConnect(){
if(bluetoothAdapter==null||bluetoothGatt==null){
return;
}
bluetoothGatt.disconnect();
}
//关闭服务,释放Service绑定对象
private void close() {
if(bluetoothGatt==null){
return;
}
bluetoothGatt.close();
bluetoothGatt=null;
}
//读取蓝牙设备特征,如果蓝牙适配器为空则返回空对象;否则读取蓝牙特征值
public void readCharacteristic(BluetoothGattCharacteristic characterristic){
if(bluetoothAdapter==null||bluetoothGatt==null){
Log.e("=============", "适配器或协议栈为空");
}else {
bluetoothGatt.readCharacteristic(characterristic);
Log.e("=============", "开始读取");
}
}
//写入指定的characteristic
public void writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if (bluetoothAdapter == null || bluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
bluetoothGatt.writeCharacteristic(characteristic);
}
//获取蓝牙支持的服务
public List getSupportedGattServices(){
if(bluetoothGatt==null) {
return null;
}else
return bluetoothGatt.getServices();
}
/*
设置蓝牙通信是否可获取通知;
如果bluetoothAdapter和bluetoothGatt都不为null,可向bluetoothGatt中设置蓝牙可通知;
其中public static String CLIENT_CHARACTERISTIC_READ="00002902-0000-1000-8000-00805f9b34fb",是notify中的descriptor的UUID,必须对其进行descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)设置,否知收不到通知。向设备写数据时需要延时操作(200m以上)才能在广播接收者内接收到notify。
*/
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,boolean enabled) {
if (bluetoothAdapter == null || bluetoothGatt == null) {
Log.e(TAG, "BluetoothAdapter not initalized");
return;
}else {
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_READ));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);
Log.e("设置descriptor:",descriptor.toString());
bluetoothGatt.setCharacteristicNotification(characteristic, enabled);
Log.e("设置notify:",characteristic.getUuid().toString()+enabled);
}
}
//遍历蓝牙service和Characteristic列表,返回二维数组;
public ArrayList> displayGattServices(List gattServices) {
if (gattServices == null){ return null;}
String uuid = null;
String unknownServiceString = getResources().getString(R.string.unknown_service);
String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
ArrayList> gattServiceData = new ArrayList>();
ArrayList>> gattCharacteristicData
= new ArrayList>>();
mGattCharateristics= new ArrayList>();
// Loops through available GATT Services.
for (BluetoothGattService gattService : gattServices) {
HashMap currentServiceData = new HashMap();
uuid = gattService.getUuid().toString();
currentServiceData.put(
LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString));
currentServiceData.put(LIST_UUID, uuid);
gattServiceData.add(currentServiceData);
ArrayList> gattCharacteristicGroupData =
new ArrayList>();
List gattCharacteristics =
gattService.getCharacteristics();
ArrayList charas =
new ArrayList();
// Loops through available Characteristics.
for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
HashMap currentCharaData = new HashMap();
uuid = gattCharacteristic.getUuid().toString();
currentCharaData.put(
LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
currentCharaData.put(LIST_UUID, uuid);
gattCharacteristicGroupData.add(currentCharaData);
//接受Characteristic被写的通知,收到蓝牙模块的数据后会触发mOnDataAvailable.onCharacteristicWrite()
setCharacteristicNotification(gattCharacteristic, true);
}
mGattCharateristics.add(charas);
gattCharacteristicData.add(gattCharacteristicGroupData);
}
/* Log.e("---------", String.valueOf(mGattCharateristics.get(3).get(0).getUuid()));
Log.e("---------", String.valueOf(mGattCharateristics.get(3).get(1).getUuid()));
Log.e("---------", String.valueOf(mGattCharateristics.get(3).get(2).getUuid()));
Log.e("---------", String.valueOf(mGattCharateristics.get(3).get(3).getUuid()));
Log.e("---------", String.valueOf(mGattCharateristics.get(3).get(4).getUuid()));
Log.e("---------", String.valueOf(mGattCharateristics.get(3).get(5).getUuid()));*/
return mGattCharateristics;
}
}
private BluetoothGattCharacteristic mGattCharateristics;//蓝牙数据描述对象链表
private BluetoothGatt mBluetoothGatt;
private BluetoothLeService mBluetoothLeService;
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";//外部仪器地址
private String mDeviceAddress;
BluetoothGattCharacteristic mCharacteristic;
private ArrayList> mGattCharacteristics =
new ArrayList>();
private final ServiceConnection mServiceConnection = new ServiceConnection() {
**//初始化蓝牙连接服务,如果蓝牙初始化成功则进行蓝牙连接;如果没有此方法,广播接收者无法接收数据,则不能进行读写操作。**
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder) iBinder).getService();
if (!mBluetoothLeService.initialize()) {//判断蓝牙是否初始化
finish();
}
mBluetoothLeService.Connect(mDeviceAddress);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
mGattCharacteristics=mBluetoothLeService.displayGattServices(mBluetoothLeService.getSupportedGattServices());
}else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
intent.getStringExtra(BluetoothLeService.EXTRA_DATA);
Log.e("+++++++++++",intent.getStringExtra(BluetoothLeService.EXTRA_DATA).toString());
}
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_treatment);
final Intent intent = getIntent();
mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
}
@Override
protected void onResume() {
super.onResume();
//发送数据,应该在按钮监听中添加,这里没有设置按钮,就添加在此方法中。
mGattCharateristics = mGattCharacteristics.get(3).get(8);
Log.e("======",mGattCharateristics.getUuid().toString());
final int charaProp =mGattCharateristics.getProperties();
byte data[] = {(byte)0x33, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00};
//final int charaProp =CharacteristicService.getProperties();
if ((charaProp|BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
if (mGattCharateristics != null) {
Log.d("NotifyCharacteristic:", mGattCharateristics.toString());
mBluetoothLeService.setCharacteristicNotification(
mGattCharateristics, true);
}
mGattCharateristics.setValue(data);//随便举个数据
mBluetoothLeService.writeCharacteristic(mGattCharateristics);//写命令到设备,
Log.e("++++++","数据发送成功");
}
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mGattUpdateReceiver);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
private 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;
}
4、android全局变量设置
目的:用于获取的蓝牙BluetoothGattCharacteristic在activity之间传递,否则一个activity销毁后,另一个activity无法获取。
(1)、在AndroidManifest文件中配置全局变量。
<application
android:allowBackup="true"
android:name=".BluetoothGattBean"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
application>
(2)、创建全局变量类
import android.app.Application;
import android.bluetooth.BluetoothGattCharacteristic;
import java.util.ArrayList;
/**
* Created by lenovo on 2016/12/20.
*/
public class BluetoothGattBean extends Application {
private ArrayList> bluetoothGattCharacteristicList;
public void setBluetoothGattCharacteristicList(ArrayList> bluetoothGattCharacteristicList) {
this.bluetoothGattCharacteristicList = bluetoothGattCharacteristicList;
}
public ArrayList> getBluetoothGattCharacteristicList() {
return bluetoothGattCharacteristicList;
}
}
(3)、向全局变量中保存广播接收者获取的数据
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final BluetoothGattBean bluetoothGattBean= (BluetoothGattBean)getApplication();
bluetoothGattBean.setBluetoothGattCharacteristicList(mGattCharacteristics);
Intent bleIntent = new Intent(DeviceControlActivity.this,
BleCommunicationActivity.class);
}
});
(4)、获取上一个activity保存的全局变量数据用于读写操作。
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
value=0;
intensity_value.setText("0");
final BluetoothGattBean bluetoothGattBean= (BluetoothGattBean)getApplication();
mGattCharacteristics=bluetoothGattBean.getBluetoothGattCharacteristicList();
mCharacteristic = mGattCharacteristics.get(3).get(8);
Log.e("获取的BluetoothGattCharacteristic为:",mCharacteristic)
});
5、倒计时
package utils;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;
public class TimerTextView extends TextView implements Runnable {
public static String Ltime = null;
public TimerTextView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
private long mmin, msecond;
private boolean run = false;
public void setTimes(long[] times) {
mmin = times[0];
msecond = times[1];
}
private void ComputeTime() {
msecond--;
if (msecond < 0) {
mmin--;
msecond = 59;
}
}
public boolean isRun() {
return run;
}
public void beginRun() {
this.run = true;
run();
}
public void stopRun() {
this.run = false;
}
//多线程,时间按mm:ss格式显示
@Override
public void run() {
if (run) {
ComputeTime();
if (mmin>9&&msecond>9) {
String strTime = mmin + ":" + msecond;
this.setText(strTime);
}else if(mmin>9&&msecond<10){
String strTime = mmin + ":0"+ msecond;
this.setText(strTime);
}else if(mmin<10&&msecond>9) {
String strTime = "0"+mmin + ":"+ msecond;
this.setText(strTime);
}else if(mmin<10&&msecond<10){
String strTime = "0"+mmin + ":0"+ msecond;
this.setText(strTime);
}
postDelayed(this, 1000);
} else {
removeCallbacks(this);
}
if (mmin == 0 && msecond == 0) {
stopRun();
}
// Log.e("shijian:",getRemainTime());
}
//回去剩余时间的分和秒
public long getRemainMinute() {
return mmin;
}
public long getRemainSecond(){
return msecond;
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg"
android:orientation="vertical">
<utils.TimerTextView
android:id="@+id/treattime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="30:00"
android:gravity="center"
android:textSize="52sp"
android:textColor="#1987C9"
/>
LinearLayout>
6、不同分辨率手机界面适配
转载:http://blog.csdn.net/lmj623565791/article/details/46695347;
注:有Navigation bar的手机需要获取手机实际分辨率(减去navigation bar占用的尺寸)后再编写一套value布局。