android_实时获取蓝牙profile连接状态
android_蓝牙profile的连接操作
該篇介紹如何在自己的app中去實現藍牙各種profile的連接,包括a2dp,handfree/headset,hid的連接。
由於google官方將藍牙連接的主要api全部隱藏起來了,所以我們無法直接利用其api去實現藍牙的連接,所以我們需要利用反射區實現藍牙的連接。
想要使用反射,首先你需要利用反射機制是什麽,這裡請讀者自行查找反射機制的原理。
Headset/Handfree的连接:BluetoothAdapter mBtAdapter;BluetoothHeadset mBluetoothHeadset;mBtAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET);private BluetoothProfile.ServiceListener mProfileListener = newBluetoothProfile.ServiceListener(){@Overridepublic void onServiceConnected(int profile, BluetoothProfile proxy) {// TODO Auto-generated method stubif (profile == BluetoothProfile.HEADSET){mBluetoothHeadset = (BluetoothHeadset) proxy;}}@Overridepublic void onServiceDisconnected(int profile) {// TODO Auto-generated method stubif (profile == BluetoothProfile.HEADSET){mBluetoothHeadset = null;}}}//獲取藍牙設備,btAddr為藍牙地址BluetoothDevice device = mBtAdapter.getRemoteDevice(btAddr);然後利用反射進行藍牙headset的連接Class cHeadset = Class.forName("android.bluetooth.BluetoothHeadset");Method connMethod = cHeadset.getMethod("connect",BluetoothDevice.class); connMethod.invoke(mBluetoothHeadset,device);其他profile如a2dp,hid連接方式與之基本一樣。
Android开发实现实时检测蓝牙连接状态的方法【附源码下载】
Android开发实现实时检测蓝⽛连接状态的⽅法【附源码下载】本⽂实例讲述了Android开发实现实时检测蓝⽛连接状态的⽅法。
分享给⼤家供⼤家参考,具体如下:本程序能实时监听并检测Android蓝⽛的连接状态,⽆论是通过界⾯上的switch按钮打开/关闭⼿机蓝⽛,还是⼿动打开/关闭⼿机蓝⽛,程序都能监听当前的状态。
⼀、软件界⾯⼆、程序实现① switch开关—-打开/关闭蓝⽛Switch switchTest = (Switch) findViewById(R.id.switch1);switchTest.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {if (isChecked) {mBluetoothAdapter.enable();//打开蓝⽛} else {mBluetoothAdapter.disable();// 关闭蓝⽛}}});②查看蓝⽛状态监听Button btn = (Button) findViewById(R.id.button);btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Toast.makeText(MainActivity.this, "bluetooth is " +bluetoothStatus,Toast.LENGTH_SHORT).show();}});③监听蓝⽛连接状态AndroidManifest权限设置:<uses-permission android:name="android.permission.BLUETOOTH"/><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>可点击此处查看监听代码://注册蓝⽛监听mContext.registerReceiver(mReceiver, makeFilter());//注销蓝⽛监听//mContext.unregisterReceiver(mReceiver);private IntentFilter makeFilter() {IntentFilter filter = new IntentFilter();filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);return filter;}private BroadcastReceiver mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {switch (intent.getAction()) {case BluetoothAdapter.ACTION_STATE_CHANGED:int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);switch (blueState) {case BluetoothAdapter.STATE_TURNING_ON:Log.e("TAG", "TURNING_ON");break;case BluetoothAdapter.STATE_ON:bluetoothStatus="on";Log.e("TAG", "STATE_ON");break;case BluetoothAdapter.STATE_TURNING_OFF:Log.e("TAG", "STATE_TURNING_OFF");break;case BluetoothAdapter.STATE_OFF:bluetoothStatus="off";Log.e("TAG", "STATE_OFF");break;}break;}}};附:完整实例代码点击此处。
Android上成功实现了蓝牙的一些Profile
Android上成功实现了蓝牙的一些Profile前段时间做蓝牙方面的开发,Google的Android只实现了Handset/Handfree和A2DP/AVRCP等Profile,而其它常用的Profile如HID/DUN/SPP/OPP/FTP/PAN等却没有实现,并且Google方面关于何时实现也没有一个时间表。
前段时间我实现了HID/DUN/SPP三个Profile,下一步实现OPP/FTP等Profile。
具体的开发其实也简单,我是参照A2DP的代码进行的相关Profile的实现。
Android的Handset/Handfree的实现方式和A2DP/AVRCP的方式有很大的不同,Handset/Handfree是直接在bluez的RFCOMM Socket上开发的,没有利用bluez的audio plugin,而A2DP/AVRCP是在bluez的audio plugin基础上开发的,所以大大降低了实现的难度。
其实bluez的audio plugin上也有Handset/Handfree的实现,但不知道为什么Google没有用它,而要在RFCOMM Socket上自己实现一个,这使得Handset/Handfree的实现显得比较复杂。
HID要用到bluez的input plugin,Android已经把它编译进去了,在system/lib/bluez-plugin/input.so下,与input.so一起的还有audio.so库,那是供A2DP/AVRCP用的。
参照frameworks/base/core/jni /android_server_BluetoothA2dpService.cpp,自己写一个HID用的的.cpp文件,其中跟A2DP一样利用 DBUS调用input.so库的CreateDevice/Connect/Disconnect 等函数,具体源码在external/bluez /utils/input/manager.c和external/bluez/utils/input/device.c 中。
android蓝牙连接与通讯(Bluetooth)
android蓝⽛连接与通讯(Bluetooth)最近做了⼀个⼩项⽬,关于蓝⽛的⼀个智能硬件。
其中涉及到了蓝⽛模块的操作。
特记下蓝⽛模块的操作过程。
只记录下关于蓝⽛部分的操作,具体业务逻辑不涉及其中。
重点是记录下蓝⽛的扫描、链接、通讯。
在使⽤蓝⽛模块之前要判断设备是否⽀持蓝⽛模块:1if (!getPackageManager().hasSystemFeature(2 PackageManager.FEATURE_BLUETOOTH_LE)) {3 Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT)4 .show();5 }定义Service,与蓝⽛模块进⾏通讯,在后台运⾏:/** Copyright (C) 2013 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** /licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.njzoff.cushion.broadcast;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.IBinder;import android.util.Log;import java.util.List;import java.util.UUID;/*** Service for managing connection and data communication with a GATT server hosted on a* given Bluetooth LE device.*/public class BluetoothLeService extends Service {private final static String TAG = BluetoothLeService.class.getSimpleName();private BluetoothManager mBluetoothManager;private BluetoothAdapter mBluetoothAdapter;private BluetoothGatt mBluetoothGatt;public final static String ACTION_GATT_CONNECTED ="com.example.bluetooth.le.ACTION_GATT_CONNECTED";public final static String ACTION_GATT_DISCONNECTED ="com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";public final static String ACTION_GATT_SERVICES_DISCOVERED ="com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";public final static String ACTION_DATA_AVAILABLE ="com.example.bluetooth.le.ACTION_DATA_AVAILABLE";public final static String EXTRA_DATA ="com.example.bluetooth.le.EXTRA_DATA";public final static UUID UUID_NOTIFY =UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb");public final static UUID UUID_SERVICE =UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb");public BluetoothGattCharacteristic mNotifyCharacteristic;public void WriteValue(String strValue){mNotifyCharacteristic.setValue(strValue.getBytes());mBluetoothGatt.writeCharacteristic(mNotifyCharacteristic);}public void findService(List<BluetoothGattService> gattServices){Log.i(TAG, "Count is:" + gattServices.size());for (BluetoothGattService gattService : gattServices){Log.i(TAG, gattService.getUuid().toString());Log.i(TAG, UUID_SERVICE.toString());if(gattService.getUuid().toString().equalsIgnoreCase(UUID_SERVICE.toString())){List<BluetoothGattCharacteristic> gattCharacteristics =gattService.getCharacteristics();Log.i(TAG, "Count is:" + gattCharacteristics.size());for (BluetoothGattCharacteristic gattCharacteristic :gattCharacteristics){if(gattCharacteristic.getUuid().toString().equalsIgnoreCase(UUID_NOTIFY.toString())) {Log.i(TAG, gattCharacteristic.getUuid().toString());Log.i(TAG, UUID_NOTIFY.toString());mNotifyCharacteristic = gattCharacteristic;setCharacteristicNotification(gattCharacteristic, true);broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);return;}}}}}// Implements callback methods for GATT events that the app cares about. For example,// connection change and services discovered.private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {@Overridepublic void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {String intentAction;Log.i(TAG, "oldStatus=" + status + " NewStates=" + newState);if(status == BluetoothGatt.GATT_SUCCESS){if (newState == BluetoothProfile.STATE_CONNECTED) {intentAction = ACTION_GATT_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;mBluetoothGatt.close();mBluetoothGatt = null;Log.i(TAG, "Disconnected from GATT server.");broadcastUpdate(intentAction);}}}@Overridepublic void onServicesDiscovered(BluetoothGatt gatt, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {Log.w(TAG, "onServicesDiscovered received: " + status);findService(gatt.getServices());} else {if(mBluetoothGatt.getDevice().getUuids() == null)Log.w(TAG, "onServicesDiscovered received: " + status);}}@Overridepublic void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status) {if (status == BluetoothGatt.GATT_SUCCESS) {broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);}}@Overridepublic void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);Log.e(TAG, "OnCharacteristicWrite");}@Overridepublic void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,int status){Log.e(TAG, "OnCharacteristicWrite");}@Overridepublic void onDescriptorRead(BluetoothGatt gatt,BluetoothGattDescriptor bd,int status) {Log.e(TAG, "onDescriptorRead");}@Overridepublic void onDescriptorWrite(BluetoothGatt gatt,BluetoothGattDescriptor bd,int status) {Log.e(TAG, "onDescriptorWrite");}@Overridepublic void onReadRemoteRssi(BluetoothGatt gatt, int a, int b){Log.e(TAG, "onReadRemoteRssi");}@Overridepublic void onReliableWriteCompleted(BluetoothGatt gatt, int a){Log.e(TAG, "onReliableWriteCompleted");}};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);// This is special handling for the Heart Rate Measurement profile. Data parsing is// carried out as per profile specifications:///gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml // For all other profiles, writes the data formatted in HEX.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());intent.putExtra(EXTRA_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) {// After using a given device, you should make sure that BluetoothGatt.close() is called// such that resources are cleaned up properly. In this particular example, close() is// invoked when the UI is disconnected from the Service.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.*/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()) {mConnectionState = STATE_CONNECTING;return true;} else {return false;}}*/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.if(mBluetoothGatt != null){mBluetoothGatt.close();mBluetoothGatt = null;}mBluetoothGatt = device.connectGatt(this, false, mGattCallback);//mBluetoothGatt.connect();Log.d(TAG, "Trying to create a new connection.");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.*/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.*/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.*/public void readCharacteristic(BluetoothGattCharacteristic characteristic) {if (mBluetoothAdapter == null || mBluetoothGatt == null) {Log.w(TAG, "BluetoothAdapter not initialized");return;}mBluetoothGatt.readCharacteristic(characteristic);}/*** Enables or disables notification on a give characteristic.** @param characteristic Characteristic to act on.* @param enabled If true, enable notification. False otherwise.*/public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,boolean enabled) {if (mBluetoothAdapter == null || mBluetoothGatt == null) {Log.w(TAG, "BluetoothAdapter not initialized");return;}mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);/*// This is specific to Heart Rate Measurement.if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);mBluetoothGatt.writeDescriptor(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.*/public List<BluetoothGattService> getSupportedGattServices() {if (mBluetoothGatt == null) return null;return mBluetoothGatt.getServices();}}定义BluetoothAdapter mBluetoothAdapter;BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter =bluetoothManager .getAdapter(); //取得系统蓝⽛模块适配器// 扫描设备private void scanLeDevice(final boolean enable) {if (enable) {Log.d("SacanLeDevice", "1 step start ScanLedevice");// Stops scanning after a pre-defined scan period.mHandler.postDelayed(new Runnable() {@Overridepublic void run() {if (mScanning) {mScanning = false;mBluetoothAdapter.stopLeScan(mLeScanCallback);//停⽌扫描invalidateOptionsMenu();}}}, SCAN_PERIOD);mScanning = true;// F000E0FF-0451-4000-B000-000000000000liDevices.clear();mHandler.sendEmptyMessage(0);mBluetoothAdapter.startLeScan(mLeScanCallback);//开始扫描设备} else {Log.d("SacanLeDevice", "4 step stop Sacan device");mScanning = false;mBluetoothAdapter.stopLeScan(mLeScanCallback);}}//蓝⽛设备private List<BluetoothDevice> liDevices = new ArrayList<BluetoothDevice>();// 扫描蓝⽛设备的回调private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Overridepublic void onLeScan(final BluetoothDevice device, final int rssi,final byte[] scanRecord) {runOnUiThread(new Runnable() {@Overridepublic void run() {Log.d("SacanLeDevice", "2 step add device");liDevices.add(device);// mLeDeviceListAdapter.addDevice(device);mHandler.sendEmptyMessage(1);}});}};//通过handle取出扫描结果并进⾏其他操作,我这这⾥是判断扫描结果中是否有上次链接的缓存记录,如果有进⾏⾃动重连// Handerpublic final Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 1: // Notify changeLog.d("SacanLeDevice", "3 step cnnect device");if (!CoushionApplication.isconnect && liDevices.size() > 0) {// 如果没有连接,并且已经扫描到蓝⽛设备 SharedPreferences mySharedPreferences = getSharedPreferences("device", Activity.MODE_PRIVATE);String address = mySharedPreferences.getString("DeviceAddress", "");// 获取上次链接的设备地址if (!address.equals("")) {for (int i = 0; i < liDevices.size(); i++) {if (liDevices.get(i).getAddress().equals(address)) { BluetoothLeService.connect(address);//根据地址链接蓝⽛设备break;}}}}break;}}};定义⼀个⼴播接收器,接受设备连接蓝⽛状态的⼀个⼴播:mGattUpdateReceiver = new GattupdateReceiver();mGattUpdateReceiver.setBluetoothConnetinteface(this);registerReceiver(mGattUpdateReceiver,makeGattUpdateIntentFilter());public 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);intentFilter.addAction(BluetoothDevice.ACTION_UUID);return intentFilter;}import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.os.Handler;import android.os.Message;import android.util.Log;public class GattupdateReceiver extends BroadcastReceiver {public static String TAG = "GattupdateReceiver";String data ;private BluetoothConnetListen mBluetoothConnetListen;//实现接⼝private final Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 0: // 连接成功if (mBluetoothConnetListen != null) {mBluetoothConnetListen.SuccessConnect();}break;case 1: // 链接中断if (mBluetoothConnetListen != null) {mBluetoothConnetListen.CancelConnect();}break;case 2: // 可以进⾏数据通信CoushionApplication.isconnect = true;if (mBluetoothConnetListen != null) {mBluetoothConnetListen.onDoThing();}break;case 3: // 接受到数据if (mBluetoothConnetListen != null) {mBluetoothConnetListen.ReceiveData(data);}break;}}};public void setBluetoothConnetinteface(BluetoothConnetListen m) {mBluetoothConnetListen = m;}@Overridepublic void onReceive(Context arg0, Intent intent) {// TODO Auto-generated method stubfinal String action = intent.getAction();Log.d(TAG, "Action==" + action);if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) { //连接成功Log.e(TAG, "Only gatt, just wait");mHandler.sendEmptyMessage(0);} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { //连接失败 mHandler.sendEmptyMessage(1);} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) //可以通信{mHandler.sendEmptyMessage(2);} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { //接受到数据 Log.e(TAG, "RECV DATA");data = intent.getStringExtra(BluetoothLeService.EXTRA_DATA);mHandler.sendEmptyMessage(3);}}}在activity中实现接⼝后 BluetoothConnetListen。
Android Bluetooth 蓝牙设备之间自动配对
Android Bluetooth 学习(3)蓝牙设备之间自动配对0人收藏此文章, 我要收藏发表于6个月前(2013-03-21 12:01) , 已有654次阅读,共0个评论前言(android2.3版本,4.0版本由于是随机获取pin值,没有研究过):1、蓝牙设备之间自动配对,需要两个设备都安装进行配对的apk(网上好多自动配对的帖子都没有说明情况)2、在自动匹配的时候想通过反射调用BluetoothDevice的setPin、createBond、cancelPairingUserInput实现设置密钥、配对请求创建、取消密钥信息输入等。
1)createBond()创建,最终会调到源码的BluetoothService的createBond(String address)方法,通过对源码浅显的了解,createBond主要是写入匹配密钥(BluetoothService的writeDockPin ())以及进入jni注册回调函数onCreatePairedDeviceResult观察匹配结果比如:// Pins did not match, or remote device did not respond to pin// request in time// We rejected pairing, or the remote side rejected pairing. This// happens if either side presses 'cancel' at the pairing dialog.// Not sure if this happens// Other device is not responding at all// already bonded等,在jni中创建了进行匹配的device("CreatePairedDevice"),这时bluetooth会发送一个ACTION_PAIRING_REQUEST的广播,只有当前会出现密钥框的蓝牙设备收到。
android 蓝牙连接通信工作原理
Android 蓝牙连接通信的工作原理可以分为几个主要步骤:1. 开启蓝牙模块:Android设备上的蓝牙功能由BluetoothAdapter类管理。
首先,需要获取BluetoothAdapter的实例,并调用其enable()方法来开启蓝牙模块。
2. 搜索蓝牙设备:开启蓝牙模块后,可以调用BluetoothAdapter的startDiscovery()方法开始搜索附近的蓝牙设备。
搜索过程中,设备会广播其信息,包括蓝牙设备的名称、地址、服务等信息。
3. 建立连接:当搜索到目标设备后,需要创建一个BluetoothDevice对象。
使用该对象调用connectGatt()方法来尝试与蓝牙设备建立连接。
此方法返回一个BluetoothGatt对象,用于后续的GATT通信。
4. GATT通信:GATT(Generic Access Profile)是蓝牙4.0及以上版本中定义的一套协议,用于在蓝牙设备之间传输数据。
通过BluetoothGatt对象,可以进行一系列GATT操作,如读取服务、读取特征值、写入特征值等。
GATT操作通常是异步的,需要通过回调函数来处理结果和状态变化。
5. 数据交换:一旦GATT连接建立,就可以通过BluetoothGatt的readCharacteristic()和writeCharacteristic()方法来读写数据了。
数据交换可以是特征值之间的直接读写,也可以是通过服务端点进行。
6. 断开连接:当通信完成后,应该断开与蓝牙设备的连接以节省能源。
可以调用disconnect()方法来断开连接。
断开连接后,应该释放相关的资源。
在整个过程中,蓝牙通信涉及到多种蓝牙技术,包括经典的蓝牙(Bluetooth Classic)、蓝牙低能耗(Bluetooth LE,也称为BLE)、蓝牙高级(Bluetooth High Speed)等。
不同的技术有不同的通信范围和速度要求。
另外,为了确保通信的安全性,蓝牙通信过程中可能还需要进行配对和认证操作。
Android实现蓝牙(BlueTooth)设备检测连接
Android实现蓝⽛(BlueTooth)设备检测连接⽆论是WIFI还是4G⽹络,建⽴⽹络连接后都是访问互联⽹资源,并不能直接访问局域⽹资源。
⽐如两个⼈在⼀起,A要把⼿机上的视频传给B,通常情况是打开⼿机QQ,通过QQ传送⽂件给对⽅。
不过上传视频很耗流量,如果现场没有可⽤的WIFI,⼿机的数据流量⼜不⾜,那⼜该怎么办呢?为了解决这种邻近传输⽂件的问题,蓝⽛技术应运⽽⽣。
蓝⽛技术是⼀种⽆线技术标准,可实现设备之间的短距离数据交换。
Android为蓝⽛技术提供了4个⼯具类,分别是蓝⽛适配器BluetoothAdapter、蓝⽛设备BluetoothDevice、蓝⽛服务端套接字BluetoothServerSocket和蓝⽛客户端套接字BluetoothSocket。
蓝⽛适配器BluetoothAdapterBluetoothAdapter的作⽤其实跟其它的**Manger差不多,可以把它当作蓝⽛管理器。
下⾯是BluetoothAdapter的常⽤⽅法说明。
getDefaultAdapter:静态⽅法,获取默认的蓝⽛适配器对象;enable:打开蓝⽛功能;disable:关闭蓝⽛功能;isEnable:判断蓝⽛功能是否打开;startDiscovery:开始搜索周围的蓝⽛设备;cancelDiscovery:取消搜索操作;isDiscovering:判断当前是否正在搜索设备;getBondedDevices:获取已绑定的设备列表;setName:设置本机的蓝⽛名称;getName:获取本机的蓝⽛名称;getAddress:获取本机的蓝⽛地址;getRemoteDevice:根据蓝⽛地址获取远程的蓝⽛设备;getState:获取本地蓝⽛适配器的状态;listenUsingRfcommWithServiceRecord:根据名称和UUID创建并返回BluetoothServiceSocket;listenUsingRfcommOn:根据渠道编号创建并返回BluetoothServiceSocket。
Android之Bluetooth(蓝牙)编程实现
//HEXCheckBox = (CheckBox) findViewById(R.id.radioMale); /*****************************************************************/ /*****************************************************************/ /*****************************************************************/ breakButton = (Button) findViewById(R.id.button_break); // 得到当地的蓝牙适配器 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); /*****************************************************************/ /*****************************************************************/ /*****************************************************************/ // 初始化 CheckBox //checkBox_sixteen = (CheckBox) findViewById(R.id.checkBox_sixteen); /*****************************************************************/ /*****************************************************************/ /*****************************************************************/
Android跟蓝牙耳机建立连接有两种方式
Android跟蓝牙耳机建立连接有两种方式Android 跟蓝牙耳机建立连接有两种方式。
1. Android 主动跟蓝牙耳机连BluetoothSettings 中和蓝牙耳机配对上之后,BluetoothHeadsetService 会收到BONDING_CREATED_ACTION,这个时候BluetoothHeadsetService 会主动去和蓝牙耳机建立RFCOMM 连接。
if(action.equals(BluetoothIntent.BONDING_CREATED_AC TION)) {if (mState ==BluetoothHeadset.STATE_DISCONNECTED) {// Lets try and initiate an RFCOMM connectiontry {mBinder.connectHeadset(address, null);} catch (RemoteException e) {}}} RFCOMM 连接的真正实现是在ConnectionThread 中,它分两步,第一步先通过SDPClient 查询蓝牙设备时候支持Headset 和Handsfree profile。
// 1) SDP querySDPClient client = SDPClient.getSDPClient(address);if (DBG) log("Connecting to SDP server (" + address + ")...");if (!client.connectSDPAsync()) {Log.e(TAG, "Failed to start SDP connection to " + address);mConnectingStatusHandler.obtainMessage(SDP_ERROR ).sendToTarget();client.disconnectSDP();return;}if (isInterrupted()) {client.disconnectSDP();return;}if (!client.waitForSDPAsyncConnect(20000)) { // 20 secs if (DBG) log("Failed to make SDP connection to " + address);mConnectingStatusHandler.obtainMessage(SDP_ERROR ).sendToTarget();client.disconnectSDP();return;}if (DBG) log("SDP server connected (" + address + ")");int headsetChannel = client.isHeadset();if (DBG) log("headset channel = " + headsetChannel);int handsfreeChannel = client.isHandsfree();if (DBG) log("handsfree channel = " + handsfreeChannel); client.disconnectSDP();第2步才是去真正建立RFCOMM 连接。
Android获取蓝牙设备列表的方法
Android获取蓝⽛设备列表的⽅法最近换了⼀家公司,主要内容是做关于移动端室内定位的相关sdk,刚进来的时候信⼼满满,誓要⼲出⼀番天地结果进来快⼀个多⽉了,根本没轮到我施展拳脚,给我搁置在⼀旁⾃⼰弄⾃⼰的。
⾏吧,既然是做室内定位的话那⽆⾮就是(gps,蓝⽛,wifi等)这些技术来实现嘛,然后我们就可以有本篇的切⼊点了:android如何获取蓝⽛设备了?我们⼀步⼀步来分析,⾸先蓝⽛属于⼀种短距离的⽆线通信技术,那作为我们android系统是否对此有过封装了?答案那肯定是有了!BluetoothAdapterandroid提供的蓝⽛适配器,既然有了适配器,接下来我们获取蓝⽛列表就有了⼀个切⼝。
⾸先我们获取蓝⽛列表之前,先需要获取蓝⽛相关的权限,我们在AndroidManifest.xml⾥加⼊权限以下权限:<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN" /><uses-permissionandroid:name="android.permission.BLUETOOTH" />接下来我们在检查设备是否有蓝⽛功能bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if (bluetoothAdapter == null) {//通知⽤户当前设备不具有蓝⽛功能return;}如果bluetoothAdapter != null,我们再来检查⽤户是否开启了蓝⽛功能if (!bluetoothAdapter.isEnabled()){ //检查是否开启蓝⽛功能Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivity(intent); //跳转到系统Activity,让⽤户选择开启蓝⽛功能bluetoothAdapter.enable();return;}通过BluetoothAdapter源码我们可以看到该类下⾯定义了很多常量值public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED";public static final String ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED";public static final String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED";public static final String ACTION_LOCAL_NAME_CHANGED = "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED";public static final String ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";public static final String ACTION_REQUEST_ENABLE = "android.bluetooth.adapter.action.REQUEST_ENABLE";public static final String ACTION_SCAN_MODE_CHANGED = "android.bluetooth.adapter.action.SCAN_MODE_CHANGED";不难看出这些应该是适配器给我们配置的⼴播标签,那我们就根据这些状态值来创建⼀个BroadcastReceiver.class⽤来接收蓝⽛适配器给我们发送的消息public class BlueToothBroadcast extends BroadcastReceiver {private List<String> blueToothList;private BlueToothListAdapter blueToothListAdapter;private List<String> stringList = new ArrayList<>;public BlueToothBroadcast(List<String> blueToothList,BlueToothListAdapter blueToothListAdapter) {this.blueToothList = blueToothList;this.blueToothListAdapter= blueToothListAdapter;}@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();switch (action){case BluetoothDevice.ACTION_FOUND://收集蓝⽛信息BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);String mac = (device.getAddress().replace(":", ""));StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("设备名称:" + device.getName() + "\n");stringBuilder.append("mac地址:" + toLowerCase(mac, 0, mac.length()) + "\n");//⽤⼀个新的string集合去对⽐设备名称和mac地址,不能拼接rssi和uuid后再去对⽐if (stringList.indexOf(stringBuilder.toString()) == -1) {// 防⽌重复添加stringList.add(stringBuilder.toString());if (device.getName() != null) {stringBuilder.append("rssi:" + intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI) + "\n");stringBuilder.append("Uuid:" + device.getUuids());blueToothList.add(stringBuilder.toString()); // 获取设备名称和mac地址}}Log.d("searchDevices", "onReceive str: " + blueToothList.toString());break;case BluetoothAdapter.ACTION_DISCOVERY_STARTED://正在扫描break;case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:blueToothListAdapter.notifyDataSetChanged();Toast.makeText(context, "扫描完成", Toast.LENGTH_SHORT).show();break;}}//格式化mac地址public static String toLowerCase(String str, int beginIndex, int endIndex) {return str.replaceFirst(str.substring(beginIndex, endIndex),str.substring(beginIndex, endIndex).toLowerCase(Locale.getDefault()));}}接下来在activity中去注册我们的⼴播(记得在ondestroy中注销⼴播啊)// 注册Receiver来获取蓝⽛设备相关的结果broadcastReceiver = new BlueToothBroadcast(blueToothList,blueToothListAdapterr);IntentFilter intent = new IntentFilter();intent.addAction(BluetoothDevice.ACTION_FOUND); // ⽤BroadcastReceiver来取得搜索结果intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);registerReceiver(broadcastReceiver, intent);最后⼀步,开启蓝⽛发送⼴播,然后在⾃⼰写的适配器上把收集到的list加载上去,完事⼉!这套下来我们的蓝⽛设备列表就获取完成了!快去试试if (!bluetoothAdapter.isDiscovering()) {blueToothList.clear();addPairedDevice();//添加蓝⽛配对设备bluetoothAdapter.startDiscovery();}private void addPairedDevice() {Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();if (pairedDevices != null && pairedDevices.size() > 0) {for (BluetoothDevice device : pairedDevices) {String mac = (device.getAddress().replace(":", ""));StringBuilder stringBuilder = new StringBuilder();stringBuilder.append(getString(R.string.device_name)).append(device.getName()).append("\n");stringBuilder.append(getString(R.string.mac_ip)).append(toLowerCase(mac, 0, mac.length())).append("\n"); stringBuilder.append(getString(R.string.uuid)).append(Arrays.toString(device.getUuids()));blueToothList.add(stringBuilder.toString());}}}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
Android如何实现蓝牙配对连接功能
Android如何实现蓝⽛配对连接功能⽬录本⽂适⽤的范围准备搜索配对连接坑坑坑本⽂适⽤的范围Android蓝⽛部分是很复杂的,也涉及很多名词和功能。
本⽂介绍的配对连接⽅法适⽤于⼀般的蓝⽛⽿机、⾳响等,并不是连接蓝⽛ BLE 或者想⽤蓝⽛来进⾏ Socket 通信的。
先来介绍⼏种名称:Profile:Bluetooth 的⼀个很重要特性,就是所有的 Bluetooth 产品都⽆须实现全部的 Bluetooth 规范。
为了更容易的保持Bluetooth 设备之间的兼容,Bluetooth 规范中定义了 Profile。
Profile 定义了设备如何实现⼀种连接或者应⽤,你可以把Profile 理解为连接层或者应⽤层协。
我们标题中的说的连接其实就是去连接各种 Profile。
下⾯介绍的⼏种都是Android 实现了的 Profile。
A2dp:表⽰蓝⽛⽴体声,和蓝⽛⽿机听歌有关那些,另还有个Avrcp⾳频/视频远程控制配置⽂件,是⽤来听歌时暂停,上下歌曲选择的。
Handset、Handfree:和电话相关,蓝⽛接听、挂断电话。
其他:btservice关于蓝⽛基本操作的⽬录,⼀切由此开始; hdp蓝⽛关于医疗⽅⾯的应⽤;hid:⼈机交互接⼝,蓝⽛⿏标键盘什么的就是这个了;pbap:电话号码簿访问协议(Phonebook Access Profile) ...准备在 AndroidManifest.xml 添加所需的权限<uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />打开蓝⽛mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if (!mBluetoothAdapter.isEnabled()) {Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableIntent, REQUEST_ENABLE_BT);}注册⼴播由于蓝⽛的搜索、配对和连接状态的改变都是系统通过⼴播的⽅式发出来的,所以需要注册这些⼴播来获取状态的改变。
bluetoothgattservercallback 回调方法描述
bluetoothgattservercallback 回调方法描述BluetoothGattServerCallback 是Android 中用于处理蓝牙GATT 服务相关事件的回调接口。
当蓝牙设备作为GATT 服务器时,这个回调接口可以帮助你处理来自客户端的连接、服务和特征读写等请求。
以下是BluetoothGattServerCallback 的一些主要回调方法及其描述:onConnectionStateChange(BluetoothDevice device, int status, int newState)当蓝牙设备连接状态发生变化时,这个方法会被调用。
device:连接的蓝牙设备。
status:连接状态,成功为BluetoothGatt.GATT_SUCCESS。
newState:新的连接状态,如BluetoothProfile.STATE_CONNECTED 或BluetoothProfile.STATE_DISCONNECTED。
onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic)当客户端请求读取某个特征时,这个方法会被调用。
device:发起请求的蓝牙设备。
requestId:请求的唯一标识符。
offset:从特征中哪个位置开始读取。
characteristic:被读取的特征。
onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, byte[] value, boolean needConfirmation)当客户端请求写入某个特征时,这个方法会被调用。
flutter 蓝牙开发例子
flutter 蓝牙开发例子Flutter是一种跨平台的移动应用开发框架,可以用来开发iOS和Android应用。
它提供了丰富的组件和工具,使开发者能够快速构建漂亮且高性能的移动应用。
其中,蓝牙开发是Flutter中的一个重要领域,可以通过蓝牙技术实现设备间的数据传输和通信。
下面将列举10个使用Flutter进行蓝牙开发的例子。
1. 蓝牙设备搜索:使用Flutter的蓝牙插件,可以实现在移动应用中搜索附近的蓝牙设备。
开发者可以通过监听蓝牙设备搜索事件,获取到附近的蓝牙设备的信息,如设备名称、MAC地址等。
2. 蓝牙设备连接:通过Flutter的蓝牙插件,可以实现与蓝牙设备的连接。
开发者可以根据设备的MAC地址或其他唯一标识符,与指定的蓝牙设备建立连接。
3. 蓝牙数据传输:一旦与蓝牙设备建立了连接,就可以通过Flutter 的蓝牙插件实现数据的传输。
开发者可以发送数据到蓝牙设备,或从蓝牙设备接收数据,并进行相应的处理。
4. 蓝牙设备配对:在与蓝牙设备连接之前,通常需要进行设备的配对操作。
通过Flutter的蓝牙插件,可以实现设备的配对功能,使得连接更加安全和可靠。
5. 蓝牙设备断开连接:当不再需要与蓝牙设备通信时,可以通过Flutter的蓝牙插件断开与设备的连接。
这样可以释放资源,避免不必要的耗电。
6. 蓝牙设备状态监听:通过Flutter的蓝牙插件,可以监听蓝牙设备的状态变化。
开发者可以实时获取设备的连接状态、配对状态等信息,并根据需要做出相应的处理。
7. 蓝牙设备服务发现:在与蓝牙设备建立连接后,可以通过Flutter 的蓝牙插件实现设备服务的发现。
开发者可以获取到设备支持的服务和特征值等信息,以便后续的数据交互操作。
8. 蓝牙设备写入特征值:一旦发现蓝牙设备的特征值,就可以通过Flutter的蓝牙插件进行写入操作。
开发者可以向设备发送指令或数据,实现与设备的交互。
9. 蓝牙设备读取特征值:通过Flutter的蓝牙插件,可以读取蓝牙设备的特征值。
unbindbluetoothprofileservice
unbindbluetoothprofileservice unbindBluetoothProfileService是Android系统中的一个方法,用于解除蓝牙配置文件服务的绑定。
在本文中,我们将详细阐述此方法的作用、用法和实际应用案例。
一、引言蓝牙是一种无线通讯技术,广泛应用于各种设备之间的短距离无线通讯。
在Android系统中,蓝牙被用于连接耳机、扬声器、键盘、鼠标等外部设备,以及与其他Android设备进行数据传输。
在使用蓝牙功能时,绑定蓝牙配置文件服务是必要的,而unbindBluetoothProfileService方法则起到解除绑定的作用。
二、unbindBluetoothProfileService方法的作用unbindBluetoothProfileService方法用于解除蓝牙配置文件服务的绑定,即断开与蓝牙设备之间建立的通信连接。
这个方法的主要作用有以下几个方面:1. 节省系统资源:绑定蓝牙配置文件服务会占用一定的系统资源,解除绑定后可以释放这些资源,提高系统的运行效率。
2. 管理蓝牙设备连接:通过unbindBluetoothProfileService方法可以方便地管理蓝牙设备的连接状态,及时断开连接,确保系统与蓝牙设备的正常通信。
3. 修复连接问题:有时候蓝牙设备与Android系统之间的通信可能出现异常,通过解除绑定,再重新进行绑定操作,可以修复一些连接问题。
三、unbindBluetoothProfileService方法的用法要使用unbindBluetoothProfileService方法,我们首先需要了解其使用的一些前提条件和步骤。
下面将一步一步详细介绍如何使用该方法。
1. 获取BluetoothProfile实例:首先,我们需要获取BluetoothProfile 对象的实例。
这可以通过调用BluetoothAdapter的getProfileProxy方法来实现,该方法接受两个参数,分别是Context对象和BluetoothProfile.ServiceListener对象。
Android蓝牙Ble开发之获取心率
Android蓝牙Ble开发之获取心率•最近在研究Android的蓝牙Ble的开发,由于是低功耗蓝牙,以前没有接触过,看过好多博客,大多数都差不多,不过个人有一点心得关于蓝牙获取心率的。
首先就是权限问题了,在AndroidMainfest清单文件中添加一下权限:<uses-permissionandroid:name="android.permission.BLUETOOTH"/><uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/> 这次研究开发的是mio的心率手表所以如果没有设备的大家仅供参考:1、首先判断当前设备是否支持ble:/*** 判断当前设备是否支持ble*/if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {System.out.println("不支持BLE设备");}2、获取蓝牙适配器:mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();3、搜索蓝牙设备:/*** 搜索蓝牙设备** @param enable*/private void scanLeDevice(boolean enable) {// TODO Auto-generated method stubif (enable) {mHandler.postDelayed(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubmScanning = false;mBluetoothAdapter.stopLeScan(callback);}}, 10000);mScanning = true;mBluetoothAdapter.startLeScan(callback);} else {mScanning = false;mBluetoothAdapter.stopLeScan(callback);}}4、搜索蓝牙设备的回调接口:/*** 蓝牙搜索的回调方法*/private BluetoothAdapter.LeScanCallback callback = new LeScanCallback() {public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {System.out.println(device + "****" + device.getName() + "***"+ device.getAddress());runOnUiThread(new Runnable() {public void run() {adapter.addDevice(device);adapter.notifyDataSetChanged();}});}};5、然后搜索到设备之后就是连接蓝牙设备了:lv.setOnItemClickListener(new OnItemClickListener() {private BluetoothGatt gatt;@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {//把搜索到的设备信息放到listview中,然后连接设备BluetoothDevice device = adapter.getDevice(position);//连接设备的方法gatt = device.connectGatt(getApplicationContext(), false,mGattCallback);}});6、获取设备中的各种信息的方法这里主要是获取心率的:private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {private BluetoothGattCharacteristic mCharacteristic;/*** 当连接状态发生改变的时候回调的方法*/@Overridepublic void onConnectionStateChange(BluetoothGatt gatt, int status,int newState) {//判断蓝牙连接状态if (newState == BluetoothProfile.STATE_CONNECTED) {System.out.println("设备已连接");//寻找设备中的服务gatt.discoverServices();} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {System.out.println("设备已断开连接");}}/*** 当服务发现后所调用的方法*/@Overridepublic void onServicesDiscovered(BluetoothGatt gatt, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {System.out.println("Services discovered");//得到心率信息的serviceBluetoothGattService service = gatt.getService(mHeartRateServiceUuid);if (service == null) {System.out.println("没有得到心率服务");} else {System.out.println("得到心率服务");mCharacteristic = service.getCharacteristic(mHeartRateCharacteristicUuid);if (mCharacteristic == null) {System.out.println("不能找到心率");} else {boolean success = gatt.setCharacteristicNotification(mCharacteristic, true);if (!success) {System.out.println("Enabling notification failed!");return;}BluetoothGattDescriptor descriptor = mCharacteristic.getDescriptor(BleDefinedUUIDs.Descriptor.CHAR_CLIENT_C ONFIG);if (descriptor != null) {descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_ VALUE);gatt.writeDescriptor(descriptor);System.out.println("Notification enabled");} else {System.out.println("Could not get descriptor for characteristic! Notification are not enabled.");}}} else {System.out.println("Unable to discover services");}}/*** 当service里边的characteristic发生改变调用*/@Overridepublic void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {//得到心率数据if(characteristic.equals(mCharacteristic)){byte[] raw = mCharacteristic.getValue();System.out.println("心率****="+raw);int index = ((raw[0] & 0x01) == 1) ? 2 : 1;int format = (index == 1) ? BluetoothGattCharacteristic.FORMAT_UINT8 : BluetoothGattCharacteristic.FORMAT_UINT16;int value = mCharacteristic.getIntValue(format, index);final String description = value + " bpm";runOnUiThread(new Runnable() {@Overridepublic void run() {System.out.println("心率:"+description);}});}/* the rest of callbacks are not interested for us */@Overridepublic void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {}@Overridepublic void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {};@Overridepublic void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {};};就这样简单的就能吧蓝牙中的心率得到了;下面看看源码吧:先看一下布局文件:<LinearLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingT op="@dimen/activity_vertical_margin"android:orientation="vertical"tools:context=".MainActivity" ><Buttonandroid:id="@+id/start"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="18dp"android:text="搜索蓝牙设备" /><ListViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/lv"></ListView></LinearLayout>listview的item:<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"><TextView android:id="@+id/device_name"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="24dp"/><TextView android:id="@+id/device_address"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="12dp"/></LinearLayout>BleDefinedUUIDs.java:package com.example.watch;import java.util.UUID;public class BleDefinedUUIDs {public static class Service {final static public UUID HEART_RATE = UUID.fromString("0000180d-0000-1000-8000-00805f9b34fb");};public static class Characteristic {final static public UUID HEART_RATE_MEASUREMENT = UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb");final static public UUID MANUFACTURER_STRING = UUID.fromString("00002a29-0000-1000-8000-00805f9b34fb");final static public UUID MODEL_NUMBER_STRING = UUID.fromString("00002a24-0000-1000-8000-00805f9b34fb");final static public UUID FIRMWARE_REVISION_STRING = UUID.fromString("00002a26-0000-1000-8000-00805f9b34fb");final static public UUID APPEARANCE = UUID.fromString("00002a01-0000-1000-8000-00805f9b34fb");final static public UUID BODY_SENSOR_LOCATION = UUID.fromString("00002a38-0000-1000-8000-00805f9b34fb");final static public UUID BATTERY_LEVEL = UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb");}public static class Descriptor {final static public UUID CHAR_CLIENT_CONFIG = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");}}MianActivity.javapackage com.example.watch;import java.util.ArrayList;import java.util.UUID;import android.os.Bundle;import android.os.Handler;import android.app.Activity;import android.bluetooth.BluetoothAdapter;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.bluetooth.BluetoothAdapter.LeScanCallback;import android.bluetooth.BluetoothDevice;import android.content.Intent;import android.content.pm.PackageManager;import android.text.style.BulletSpan;import youtInflater;import android.view.Menu;import android.view.View;import android.view.ViewGroup;import android.view.View.OnClickListener;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter;import android.widget.Button;import android.widget.ListView;import android.widget.TextView;public class MainActivity extends Activity {private BluetoothAdapter mBluetoothAdapter;private static final int REQUEST_ENABLE_BT = 1;private Handler mHandler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(yout.activity_main);/*** 判断当前设备是否支持ble*/if (!getPackageManager().hasSystemFeature( PackageManager.FEATURE_BLUETOOTH_LE)) { System.out.println("不支持BLE设备");}//得到蓝牙适配器mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(intent, REQUEST_ENABLE_BT);}Button start = (Button) findViewById(R.id.start);lv = (ListView) findViewById(R.id.lv);adapter = new LeDeviceListAdapter();start.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {scanLeDevice(true);lv.setAdapter(adapter);adapter.clear();}});lv.setOnItemClickListener(new OnItemClickListener() {private BluetoothGatt gatt;@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {//把搜索到的设备信息放到listview中,然后连接设备BluetoothDevice device = adapter.getDevice(position);gatt = device.connectGatt(getApplicationContext(), false,mGattCallback);}});}final static private UUID mHeartRateServiceUuid = BleDefinedUUIDs.Service.HEART_RATE;final static private UUID mHeartRateCharacteristicUuid = BleDefinedUUIDs.Characteristic.HEART_RATE_MEASUREMENT;/*** 寻找服务*/private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {private BluetoothGattCharacteristic mCharacteristic;/*** 当连接状态发生改变的时候回调的方法*/@Overridepublic void onConnectionStateChange(BluetoothGatt gatt, int status,int newState) {//判断蓝牙连接状态if (newState == BluetoothProfile.STATE_CONNECTED) {System.out.println("设备已连接");//寻找设备中的服务gatt.discoverServices();} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {System.out.println("设备已断开连接");}}/*** 当服务发现后所调用的方法*/@Overridepublic void onServicesDiscovered(BluetoothGatt gatt, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {System.out.println("Services discovered");//得到心率信息的serviceBluetoothGattService service = gatt.getService(mHeartRateServiceUuid);if (service == null) {System.out.println("没有得到心率服务");} else {System.out.println("得到心率服务");mCharacteristic = service.getCharacteristic(mHeartRateCharacteristicUuid);if (mCharacteristic == null) {System.out.println("不能找到心率");} else {boolean success = gatt.setCharacteristicNotification(mCharacteristic, true);if (!success) {System.out.println("Enabling notification failed!");return;}BluetoothGattDescriptor descriptor = mCharacteristic.getDescriptor(BleDefinedUUIDs.Descriptor.CHAR_CLIENT_C ONFIG);if (descriptor != null) {descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_ VALUE);gatt.writeDescriptor(descriptor);System.out.println("Notification enabled");} else {System.out.println("Could not get descriptor for characteristic! Notification are not enabled.");}}}} else {System.out.println("Unable to discover services");}}/*** 当service里边的characteristic发生改变调用*/@Overridepublic void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {//得到心率数据if(characteristic.equals(mCharacteristic)){byte[] raw = mCharacteristic.getValue();System.out.println("心率****="+raw);int index = ((raw[0] & 0x01) == 1) ? 2 : 1;int format = (index == 1) ? BluetoothGattCharacteristic.FORMAT_UINT8 : BluetoothGattCharacteristic.FORMAT_UINT16;int value = mCharacteristic.getIntValue(format, index);final String description = value + " bpm";runOnUiThread(new Runnable() {@Overridepublic void run() {System.out.println("心率:"+description);}});}}/* the rest of callbacks are not interested for us */@Overridepublic void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {}@Overridepublic void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {};@Overridepublic void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {};};private boolean mScanning;/*** 搜索蓝牙设备** @param enable*/private void scanLeDevice(boolean enable) {// TODO Auto-generated method stubif (enable) {mHandler.postDelayed(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubmScanning = false;mBluetoothAdapter.stopLeScan(callback);}}, 10000);mScanning = true;mBluetoothAdapter.startLeScan(callback);} else {mScanning = false;mBluetoothAdapter.stopLeScan(callback);}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == REQUEST_ENABLE_BT&& resultCode == Activity.RESULT_CANCELED) {finish();return;}super.onActivityResult(requestCode, resultCode, data);}/*** 蓝牙搜索的回调方法*/private BluetoothAdapter.LeScanCallback callback = new LeScanCallback() {public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {System.out.println(device + "****" + device.getName() + "***"+ device.getAddress());runOnUiThread(new Runnable() {adapter.addDevice(device);adapter.notifyDataSetChanged();}});}};private ListView lv;private LeDeviceListAdapter adapter;private class LeDeviceListAdapter extends BaseAdapter { private ArrayList<BluetoothDevice> mLeDevices; private LayoutInflater mInflator;public LeDeviceListAdapter() {super();mLeDevices = new ArrayList<BluetoothDevice>(); mInflator = MainActivity.this.getLayoutInflater();}public void addDevice(BluetoothDevice device) {if (!mLeDevices.contains(device)) {mLeDevices.add(device);}}public BluetoothDevice getDevice(int position) { return mLeDevices.get(position);}mLeDevices.clear();}@Overridepublic int getCount() {return mLeDevices.size();}@Overridepublic Object getItem(int i) {return mLeDevices.get(i);}@Overridepublic long getItemId(int i) {return i;}@Overridepublic View getView(int i, View view, ViewGroup viewGroup) {ViewHolder viewHolder;// General ListView optimization code.if (view == null) {view = mInflator.inflate(yout.listitem_device, null);viewHolder = new ViewHolder();viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);view.setTag(viewHolder);} else {viewHolder = (ViewHolder) view.getT ag();}BluetoothDevice device = mLeDevices.get(i);final String deviceName = device.getName();if (deviceName != null && deviceName.length() > 0) viewHolder.deviceName.setText(deviceName);elseviewHolder.deviceName.setText("未知设备"); viewHolder.deviceAddress.setText(device.getAddress());return view;}}static class ViewHolder {TextView deviceName;TextView deviceAddress;}。
Android获得设备状态信息、Mac地址、IP地址的方法
Android获得设备状态信息、Mac地址、IP地址的⽅法前⾔在APP开发时,经常会遇到要获取⼿机状态信息的场景,像升级时获取版本号,像发⽣异常时要收集⼿机信息等等。
有些软件还要根据Mac地址来判定当前⽤户以前是否登录过。
下⾯将⼀⼀介绍获取这些⼿机状态信息的⽅法。
1 通过build获取⼿机硬件信息运⽤反射获取Build信息,然后从build中得到对应字段的值。
这种情况适⽤于获取所有的build信息。
或者直接调⽤Build类直接拿⾥⾯的字段名,如:android.os.Build.MODEL; // ⼿机型号。
这是为了获取单独某个⼿机信息的⽅法,直接调⽤Build的字段即可拿到对应信息,简单快捷。
别忘了加权限<uses-permission android:name="android.permission.READ_PHONE_STATE"/>下⾯是Build类的字段所对应的信息String BOARD The name of the underlying board, like "goldfish".基板名String BOOTLOADER The system bootloader version number.String BRAND The brand (e.g., carrier) the software is customized for, if any.品牌名String CPU_ABI The name of the instruction set (CPU type + ABI convention) of native code.String CPU_ABI2 The name of the second instruction set (CPU type + ABI convention) of native code.String DEVICE The name of the industrial design.品牌型号名,如⼩⽶4对应cancroString DISPLAY A build ID string meant for displaying to the userString FINGERPRINT A string that uniquely identifies this build.包含制造商,设备名,系统版本等诸多信息String HARDWARE The name of the hardware (from the kernel command line or /proc).String HOSTString ID Either a changelist number, or a label like "M4-rc20".String MANUFACTURER The manufacturer of the product/hardware.String MODEL The end-user-visible name for the end product.String PRODUCT The name of the overall product.String RADIO The radio firmware version number.String SERIAL A hardware serial number, if available.String TAGS Comma-separated tags describing the build, like "unsigned,debug".long TIME 当前时间,毫秒值String TYPE The type of build, like "user" or "eng".String UNKNOWN Value used for when a build property is unknown.String USER//运⽤反射得到build类⾥的字段Field[] fields = Build.class.getDeclaredFields();//遍历字段名数组for (Field field : fields) {try {//将字段都设为public可获取field.setAccessible(true);//filed.get(null)得到的即是设备信息haspmap.put(field.getName(), field.get(null).toString());Log.d("CrashHandler", field.getName() + " : " + field.get(null));} catch (Exception e) {}}下⾯是⼩⽶4对应的设备信息D/CrashHandler: BOARD : MSM8974D/CrashHandler: BOOTLOADER : unknownD/CrashHandler: BRAND : XiaomiD/CrashHandler: CPU_ABI : armeabi-v7aD/CrashHandler: CPU_ABI2 : armeabiD/CrashHandler: DEVICE : cancroD/CrashHandler: DISPLAY : MMB29MD/CrashHandler: FINGERPRINT : Xiaomi/cancro_wc_lte/cancro:6.0.1/MMB29M/V8.1.3.0.MXDCNDI:user/release-keysD/CrashHandler: HARDWARE : qcomD/CrashHandler: HOST : c3-miui-ota-bd43D/CrashHandler: ID : MMB29MD/CrashHandler: IS_DEBUGGABLE : falseD/CrashHandler: MANUFACTURER : XiaomiD/CrashHandler: MODEL : MI 4LTED/CrashHandler: PRODUCT : cancro_wc_lteD/CrashHandler: RADIO : unknown//设备的序列号码-SERIALD/CrashHandler: SERIAL : abcdefghD/CrashHandler: SUPPORTED_32_BIT_ABIS : [ng.String;@76b6d2bD/CrashHandler: SUPPORTED_64_BIT_ABIS : [ng.String;@e42c588D/CrashHandler: SUPPORTED_ABIS : [ng.String;@9cdbb21D/CrashHandler: TAG : BuildD/CrashHandler: TAGS : release-keysD/CrashHandler: TIME : 1478606340000D/CrashHandler: TYPE : userD/CrashHandler: UNKNOWN : unknownD/CrashHandler: USER : builder2.通过getSystemService()来获取Ip地址Context.getSystemService()这个⽅法是⾮常实⽤的⽅法,只须在参数⾥输⼊⼀个String 字符串常量就可得到对应的服务管理⽅法,可以⽤来获取绝⼤部分的系统信息,各个常量对应的含义如下。
Eclipse开发环境中Android应用程序获取蓝牙设备过程研究与实现
achieve these functions in the corresponding development environment.
Key words: Eclipse; Android; Bluetooth device; communication
DOI:10.15954/32-1529/g4.2014.04.008
该类代表的是远程蓝牙设备,同时也需要得 到蓝牙许可。BluetoothDevice 类可创建设备并可 查询如名称、地址、类和连接状态等相关信息。通 过创建 BluetoothDevice 的 BluetoothAdapter 对象, 用于实现对远程蓝牙设备地址的操作。
当使用 BluetoothAdapter 获得蓝牙设备后,通 常 采 用 getRemoteDevice ( ) 方 法 创 建 一 个 已 知 MAC 地 址 的 代 表 设 备,也 可 从 BluetoothAdapter 和 getBondedDevices( ) 方法返回的已绑定的设备 中 得 到 它。 最 后 使 用 createRfcommSocketToServiceRecord( UUID) 方 法 建 立 与 远 程 设 备 通 信 的 BluetoothSocket。
XU Li-xian
( Yangzhou Polytechnic College,Yangzhou 225009,China)
Abstract: Bluetooth technology has been widely used in the short distance wireless communication because of
ADT 即 Android Development Tools,它 在 Eclipse 环境下,为开发人员提供基于 Android 操作 系统进行程序开发的工具服务,如开发工具的升 级下载等。 1. 3 安装 SDK
RKAndroid7.1设置-蓝牙-已断开连接Android6.0直接弹窗
RKAndroid7.1设置-蓝⽛-已断开连接Android6.0直接弹窗⼀. Android7.1 连⼿机蓝⽛显⽰蓝⽛已断开连接1.1. /frameworks/base/packages/SettingsLib/res/values-zh-rCN/strings.xml<string name="bluetooth_disconnected" msgid="6557104142667339895">"已断开连接"</string>1.2.蓝⽛配对 K:\ZK-Rxxx_7.1_RK3399_Firmware\ZK_RXXX_RK3399_ANDROID7.1\packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothSettings.java @Overridepublic void setListening(boolean listening) {BluetoothAdapter defaultAdapter = BluetoothAdapter.getDefaultAdapter();if (defaultAdapter == null) return;if (listening) {mEnabled = defaultAdapter.isEnabled();mConnected =defaultAdapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED;Log.d("gatsby","state aaa -> "+ BluetoothAdapter.STATE_CONNECTED);Log.d("gatsby","state bbb -> "+ defaultAdapter.getConnectionState());mSummaryLoader.setSummary(this, getSummary());mBluetoothManager.getEventManager().registerCallback(this);} else {mBluetoothManager.getEventManager().unregisterCallback(this);}}private CharSequence getSummary() {Log.d("gatsby","!mEnabled -> "+ !mEnabled + " mConnected ->"+mConnected);return mContext.getString(!mEnabled ? R.string.bluetooth_disabled: mConnected ? R.string.bluetooth_connected: R.string.bluetooth_disconnected);}a. Log.d("gatsby","!mEnabled -> "+ !mEnabled + " mConnected ->"+mConnected);mEnabled ? R.string.bluetooth_disabled: mConnected ? R.string.bluetooth_connected: R.string.bluetooth_disconnectedmEnabled ?"disabled" : mConnected ? "bluetooth_connected" : "bluetooth_disconnected";打开蓝⽛开关未连接蓝⽛ !mEnabled -> false mConnected ->falseb.mConnected = defaultAdapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED;defaultAdapter.getConnectionState() -> 0BluetoothAdapter.STATE_CONNECTED -> 21.3.Android检查设备连接状态K:\ZK-Rxxx_7.1_RK3399_Firmware\ZK_RXXX_RK3399_ANDROID7.1\frameworks\base\core\java\android\bluetooth\BluetoothAdapter.java /** The profile is in disconnected state */public static final int STATE_DISCONNECTED = 0;/*** Get the current connection state of the local Bluetooth adapter.* This can be used to check whether the local Bluetooth adapter is connected* to any profile of any other remote Bluetooth Device.** <p> Use this function along with {@link #ACTION_CONNECTION_STATE_CHANGED}* intent to get the connection state of the adapter.** @return One of {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTED},* {@link #STATE_CONNECTING} or {@link #STATE_DISCONNECTED}** @hide*/public int getConnectionState() {if (getState() != STATE_ON) return BluetoothAdapter.STATE_DISCONNECTED;try {mServiceLock.readLock().lock();if (mService != null) return mService.getAdapterConnectionState();} catch (RemoteException e) {Log.e(TAG, "getConnectionState:", e);} finally {mServiceLock.readLock().unlock();}return BluetoothAdapter.STATE_DISCONNECTED;}调⽤BluetoothAdapter中的getConnectionState()⽅法,直接检查是否存在连接状态的蓝⽛设备存在不能检测出⼿机发出的蓝⽛可以检测出蓝⽛⽿机 /** The profile is in disconnected state */public static final int STATE_DISCONNECTED = 0;/** The profile is in connecting state */public static final int STATE_CONNECTING = 1;/** The profile is in connected state */public static final int STATE_CONNECTED = 2;/** The profile is in disconnecting state */public static final int STATE_DISCONNECTING = 3;⼆.Android6.0 蓝⽛直接弹窗 2.1.packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterProperties.javavoid updateFeatureSupport(byte[] val) { --- a/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java+++ b/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java@@ -612,11 +612,11 @@ class AdapterProperties {adapterPropertyChangedCallback received beforeonBluetoothReady */if (mDiscoverableTimeout != 0)- setScanMode(AbstractionLayer.BT_SCAN_MODE_CONNECTABLE);+ setScanMode(AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);else /* if timeout == never (0) at startup */setScanMode(AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);/* though not always required, this keeps NV up-to date on first-boot after flash */- setDiscoverableTimeout(mDiscoverableTimeout);+ setDiscoverableTimeout(0/*mDiscoverableTimeout*/);}}}2.2.packages\apps\Bluetooth\src\com\android\bluetooth\opp\BluetoothOppNotification.java private void updateIncomingFileConfirmNotification() {--- a/packages/apps/Bluetooth/src/com/android/bluetooth/opp/BluetoothOppNotification.java +++ b/packages/apps/Bluetooth/src/com/android/bluetooth/opp/BluetoothOppNotification.java @@ -526,6 +526,15 @@ class BluetoothOppNotification {n.deleteIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);mNotificationMgr.notify(id, n);++ Uri uri = intent.getData();+ Intent in = new Intent(mContext, BluetoothOppIncomingFileConfirmActivity.class); + in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);+ in.setDataAndNormalize(uri);+ mContext.startActivity(in);++ NotificationManager notGatsby = (NotificationManager)mContext+ .getSystemService(Context.NOTIFICATION_SERVICE);}cursor.close();}。