當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 智能手環(huán)客戶(hù)端詳細(xì)設(shè)計(jì)
1.1 客戶(hù)端簡(jiǎn)介
1.1.1 界面操作
進(jìn)入頁(yè)面后,會(huì)自動(dòng)進(jìn)行掃描,以發(fā)現(xiàn)周?chē)捎盟{(lán)牙設(shè)備。
在搜索藍(lán)牙設(shè)備的多層中,會(huì)出現(xiàn)圓環(huán)形進(jìn)度條,當(dāng)設(shè)定的搜索時(shí)間到了之后,或者我們選中了被掃描到的設(shè)備,該進(jìn)度條消失,“停止掃描”轉(zhuǎn)換會(huì)“掃描”。
點(diǎn)擊掃描到的設(shè)備進(jìn)入控制設(shè)備控制頁(yè)面。
這個(gè)頁(yè)面是我們的主要控制界面,我們可以在這個(gè)界面看到手環(huán)為我們提供的一些數(shù)據(jù)。
這個(gè)下拉菜單可以同過(guò)點(diǎn)擊也可以通過(guò)設(shè)備的menu按鍵獲得,主要用來(lái)控制計(jì)步器。
“斷開(kāi)連接”的按鈕的作用是顯示現(xiàn)在設(shè)備的連接情況,如果不是已經(jīng)連接了設(shè)備,那么可以看到“連接”按鈕,可以通過(guò)“連接”按鈕來(lái)實(shí)現(xiàn)和藍(lán)牙設(shè)備的連接,如果是已經(jīng)連接了的設(shè)備,可以看到“斷開(kāi)連接”,可以通過(guò)“斷開(kāi)連接”來(lái)斷開(kāi)和藍(lán)牙設(shè)備的連接。
設(shè)置時(shí)間按鈕,可以將我們的設(shè)備上的時(shí)間,同步到藍(lán)牙手環(huán)上。
1.1.2 工程結(jié)構(gòu)
Src為java文件目錄。
Res為資源文件目錄。
AndroidManifest.xml為配置文件。
在src目錄下:
Acticity包中,是工程的兩個(gè)Activity活動(dòng)相關(guān)的代碼。
Service包中,是工程啟動(dòng)的服務(wù)相關(guān)代碼。
Tools包中,是工具類(lèi)相關(guān)代碼。
UI包中,是自定義界面相關(guān)代碼。
在資源文件夾中,包含了Layout,values,Drawable等資源文件夾:
其中l(wèi)ayout中是布局文件,menu中,是菜單欄的布局文件,values中包括color,string,styles等設(shè)置。
1.2 代碼分析
1.2.1 界面代碼分析
本工程一共有兩個(gè)主要顯示界面,分別為掃描設(shè)備,和設(shè)備控制,通過(guò)兩個(gè)活動(dòng)—Activity來(lái)進(jìn)行設(shè)置與控制。
掃描-----界面ScanningActivity
在onCreate中設(shè)定標(biāo)題。
Java Code
public void onCreate(Bundle savedInstanceState){
getActionBar().setTitle(R.string.title_devices);
}
在掃描的時(shí)候,menu顯示為“停止掃描”,并顯示圓環(huán)進(jìn)度條以提醒等待;在掃描結(jié)束時(shí),menu顯示為“掃描”。在界面中使用ListView展示掃描到的設(shè)備。
Java Code
/**
* 創(chuàng)建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菜單欄被選擇時(shí)
*/
@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顯示掃描到的設(shè)備。
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);
}
點(diǎn)擊ListView中的設(shè)備跳轉(zhuǎn)到控制界面。
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);
}
設(shè)備控制-------界面DeviceControlActivity
在Activity中設(shè)置主界面:
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);
}
菜單欄包括兩部分,一部分是顯示“連接”或“斷開(kāi)連接”,一部分是隱藏的用以對(duì)計(jì)步功能進(jìn)行設(shè)置。
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 藍(lán)牙連接代碼分析
掃描
藍(lán)牙連接建立的過(guò)程中,首先要先掃描到設(shè)備。
在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();
}
});
}
};
}
連接藍(lán)牙
在掃描結(jié)束的時(shí)候,點(diǎn)擊ListView上的設(shè)備名稱(chēng)的時(shí)候,將設(shè)備MAC通過(guò)Intent傳遞給DeviceControlActivity,在控制頁(yè)面啟動(dòng)BLEService服務(wù),控制設(shè)備連接。
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啟動(dòng)服務(wù),注冊(cè)廣播接收器實(shí)現(xiàn)服務(wù)與活動(dòng)之間的通信
Intent gattIntent = new Intent(this, BLEService.class);
bindService(gattIntent, mServiceConnection, BIND_AUTO_CREATE);
registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
//實(shí)例化一個(gè)電話(huà)模型。
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);
}
}
//服務(wù)連接
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服務(wù)代碼如下:
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);
/**
* 回調(diào)函數(shù)
*/
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);
}
}
//發(fā)現(xiàn)新服務(wù)
@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);
}
}
//讀到特征設(shè)備
@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);
}
};
/**
* 通過(guò)廣播發(fā)送數(shù)據(jù)
*/
private void broadcastUpdate(final String action){
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
/**
* 通過(guò)廣播發(fā)送數(shù)據(jù)
*/
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);
}
}
/**
* 所有服務(wù)列表
*/
public List getSupportedGattServices(){
if (mBluetoothGatt == null)
return null;
return mBluetoothGatt.getServices();
}
1.2.3 信號(hào)處理
從藍(lán)牙設(shè)備接收數(shù)據(jù)
這里我們使用設(shè)備接收來(lái)自藍(lán)牙的通知即Notification信號(hào),所以我們需要讓我們的設(shè)備讀取相應(yīng)特征值的可通知信號(hào)。
在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中,通過(guò)廣播接收器接收來(lái)自BLEService中的廣播發(fā)出的信號(hào):
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);
}
}
};
當(dāng)發(fā)現(xiàn)服務(wù)的時(shí)候,調(diào)用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;
}
}
}
}
當(dāng)接收到ACTION_DATA_AVAILABLE廣播的時(shí)候,讀出廣播中的數(shù)據(jù),并通過(guò)數(shù)據(jù)對(duì)界面進(jìn)行操作。
向藍(lán)牙設(shè)備發(fā)送數(shù)據(jù)
電話(huà)狀態(tài)監(jiān)聽(tīng)類(lèi)代碼:
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();
}
// 剛開(kāi)始就發(fā)送現(xiàn)有的數(shù)據(jù)
void init()
{
phoneCount = (byte) readMissCall();
cmdBuf.addBuffer((byte) 'a', 1, phoneCount);
msgCount = (byte) getNewSmsCount();
cmdBuf.addBuffer((byte) 'c', 1, msgCount);
}
public void Quit()
{
unregisterObserver();
}
// 監(jiān)聽(tīng)來(lái)電
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);
}
}
}
// 監(jiān)聽(tīng)短信
public ContentObserver newMmsContentObserver = new ContentObserver(
new Handler())
{
public void onChange(boolean selfChange)
{
if (cmdBuf.getVolume() == 0)
{
cmdBuf.addBuffer((byte) 'd', 1, (byte) (getNewSmsCount() + 1));// 發(fā)送短信通知
}
}
};
// 注冊(cè)監(jiān)聽(tīng)者
@SuppressLint("NewApi")
public void registerObserver()
{
unregisterObserver();
context.getContentResolver().registerContentObserver(
Uri.parse("content://sms"), true, newMmsContentObserver);
}
// 取消注冊(cè)
public void unregisterObserver()
{
try
{
if (newMmsContentObserver != null)
{
context.getContentResolver().unregisterContentObserver(
newMmsContentObserver);
}
}
catch (Exception e)
{
}
}
// 獲得短信條數(shù)
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;
}
}
// 獲得電話(huà)個(gè)數(shù)
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;
}
}
}
要發(fā)送的數(shù)據(jù)通過(guò)BuffTools來(lái)設(shè)置:
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();
}
}
和接收數(shù)據(jù)時(shí)不一樣的是,我們?cè)诎l(fā)現(xiàn)服務(wù)和特征值之后,就應(yīng)該去查看Phone實(shí)例中是否有未傳輸出去的數(shù)據(jù),如果有,而且服務(wù)和特征值是我們要發(fā)送的設(shè)備的話(huà),就要進(jìn)行數(shù)據(jù)傳送。
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;
}
}
}