权限:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
//不需要进行动态授权
代码:
ListView list_divice;
List<String> list_infos= new ArrayList<String>();
BluetoothAdapter btAdapt;
BlueToothDeviceAdapter<String> myAdapter;
//初始化
list_divice= (ListView) this.findViewById(R.id.lvDevices);
myAdapter= new BlueToothDeviceAdapter(this, list_infos);
list_divice.setAdapter(adtDevices);
list_divice.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (btAdapt.getState() != BluetoothAdapter.STATE_ON) {// 如果蓝牙还没开启
Toast.makeText(context, "请开启蓝牙", 1000).show();
return;
}
if (btAdapt.isDiscovering())
btAdapt.cancelDiscovery();
String str = lstDevices.get(position);
if (str == null | str.equals(""))
return;
String[] values = str.split("\\|");
String address = values[1];
Log.e(Common.TAG, values[1]);
try {
Intent intMain = new Intent(context, BlueToothDeviceActivity.class);
Bundle bd = new Bundle();
bd.putString("NAME", values[0]);
bd.putString("MAC", values[1]);
intMain.putExtras(bd);
context.startActivity(intMain);
} catch (Exception e) {
Log.d("Common.TAG", "Error connected to: " + address);
e.printStackTrace();
}
});
btAdapt = BluetoothAdapter.getDefaultAdapter();
if (btAdapt == null) {
Toast.makeText(getBaseContext(), "您的机器上没有发现蓝牙适配器,本程序将不能运行!", Toast.LENGTH_SHORT).show();
this.finish();
}
// 注册Receiver来获取蓝牙设备相关的结果
IntentFilter intent = new IntentFilter();
intent.addAction(BluetoothDevice.ACTION_FOUND); // 用BroadcastReceiver来取得搜索结果
intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(searchDevices, intent);
addPairedDevice();
private BroadcastReceiver searchDevices = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_FOUND)) { //found device
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String str = device.getName() + "|" + device.getAddress();
if (lstDevices.indexOf(str) == -1)// 防止重复添加
lstDevices.add(str); // 获取设备名称和mac地址
adtDevices.notifyDataSetChanged();
} else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
btnDis.setText("正在扫描");
btnDis.setTextColor(Color.RED);
} else if (action
.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
btnDis.setText("扫描设备");
btnDis.setTextColor(Color.BLACK);
Toast.makeText(getBaseContext(), "扫描完成,点击列表中的设备来尝试连接", Toast.LENGTH_SHORT).show();
}
}
};
private void addPairedDevice() // 增加配对设备
{
Set<BluetoothDevice> pairedDevices = btAdapt.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
String str = device.getName() + "|" + device.getAddress();
lstDevices.add(str);
adtDevices.notifyDataSetChanged();
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
android.os.Process.killProcess(android.os.Process.myPid());
}
// 按钮点击事件:
if (v == btnDis)// 搜索设备
{
if (btAdapt.getState() != BluetoothAdapter.STATE_ON) {// 如果蓝牙还没开启
Toast.makeText(getBaseContext(), "请先开启蓝牙", Toast.LENGTH_SHORT).show();
return;
}
if (!btAdapt.isDiscovering()) {
lstDevices.clear();
addPairedDevice();
btAdapt.startDiscovery();
}
2、showdetail.activity
public class showDetail extends Activity {
public static String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
private InputStream mmInStream;
private OutputStream mmOutStream;
ScrollView svResult;
private static final String TAG="showDetail";
Button btnExit, btnAll;
Button btn02, btn03, btn04, btn05, btn06, btn07, btn08, btn09, btn10,
btn11;
TextView tvTitle, tvLog,tv_shousuo,tv_shuzhang,tv_maibo;
BluetoothAdapter btAdapt = null;
BluetoothSocket btSocket = null;
Boolean bConnect = false;
String strName = null;
String strAddress = null;
int nNeed = 0;
byte[] bRecv = new byte[1024];
int nRecved = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.detail);
svResult = (ScrollView) findViewById(R.id.svResult);
btnExit = (Button) this.findViewById(R.id.btnExit);
btnExit.setOnClickListener(new ClickEvent());
btnAll = (Button) this.findViewById(R.id.btnAll);
btnAll.setOnClickListener(new ClickEvent());
btn02 = (Button) this.findViewById(R.id.btn02);
btn02.setOnClickListener(new ClickEvent());
btn02.setId(0);
btn03 = (Button) this.findViewById(R.id.btn03);
btn03.setOnClickListener(new ClickEvent());
btn03.setId(0);
btn04 = (Button) this.findViewById(R.id.btn04);
btn04.setOnClickListener(new ClickEvent());
btn04.setId(0);
btn05 = (Button) this.findViewById(R.id.btn05);
btn05.setOnClickListener(new ClickEvent());
btn05.setId(0);
btn06 = (Button) this.findViewById(R.id.btn06);
btn06.setOnClickListener(new ClickEvent());
btn06.setId(0);
btn07 = (Button) this.findViewById(R.id.btn07);
btn07.setOnClickListener(new ClickEvent());
btn07.setId(0);
btn08 = (Button) this.findViewById(R.id.btn08);
btn08.setOnClickListener(new ClickEvent());
btn08.setId(0);
btn09 = (Button) this.findViewById(R.id.btn09);
btn09.setOnClickListener(new ClickEvent());
btn09.setId(0);
btn10 = (Button) this.findViewById(R.id.btn10);
btn10.setOnClickListener(new ClickEvent());
btn10.setId(0);
btn11 = (Button) this.findViewById(R.id.btn11);
btn11.setOnClickListener(new ClickEvent());
btn11.setId(0);
tvTitle = (TextView) this.findViewById(R.id.tvTitle);
tvLog = (TextView) this.findViewById(R.id.tvLog);
tv_maibo=findViewById(R.id.tv_maibo);
tv_shousuo=findViewById(R.id.tv_shousuo);
tv_shuzhang=findViewById(R.id.tv_shuzhang);
Bundle bunde = this.getIntent().getExtras();
strName = bunde.getString("NAME");
strAddress = bunde.getString("MAC");
tvTitle.setText(strName);
tvLog.append(strName + "......\n");
btAdapt = BluetoothAdapter.getDefaultAdapter();
if (btAdapt == null) {
tvLog.append("本机无蓝牙,连接失败\n");
finish();
return;
}
if (btAdapt.getState() != BluetoothAdapter.STATE_ON) {
tvLog.append("本机蓝牙状态不正常,连接失败\n");
finish();
return;
}
IntentFilter intent = new IntentFilter();
intent.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
intent.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
registerReceiver(connectDevices, intent);
setButtonEnable(false);
mHandler.sendEmptyMessageDelayed(Common.MESSAGE_CONNECT, 1000);
}
@SuppressLint("ResourceType")
public void setButtonColor(Button btn, Boolean bOn) {
if (bOn) {
btn.setTextColor(Color.GREEN);
btn.setId(1);
} else {
btn.setTextColor(Color.BLACK);
btn.setId(0);
}
}
public void setButtonEnable(Boolean bOn) {
if (bOn) {
btn02.setEnabled(true);
btn03.setEnabled(true);
btn04.setEnabled(true);
btn05.setEnabled(true);
btn06.setEnabled(true);
btn07.setEnabled(true);
btn08.setEnabled(true);
btn09.setEnabled(true);
btn10.setEnabled(true);
btn11.setEnabled(true);
btnAll.setEnabled(true);
} else {
btn02.setEnabled(false);
btn03.setEnabled(false);
btn04.setEnabled(false);
btn05.setEnabled(false);
btn06.setEnabled(false);
btn07.setEnabled(false);
btn08.setEnabled(false);
btn09.setEnabled(false);
btn10.setEnabled(false);
btn11.setEnabled(false);
btnAll.setEnabled(false);
}
}
// Hander
public final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Common.MESSAGE_CONNECT:
new Thread(new Runnable() {
public void run() {
InputStream tmpIn;
OutputStream tmpOut;
try {
UUID uuid = UUID.fromString(SPP_UUID);
BluetoothDevice btDev = btAdapt
.getRemoteDevice(strAddress);
btSocket = btDev
.createRfcommSocketToServiceRecord(uuid);
btSocket.connect();
tmpIn = btSocket.getInputStream();
tmpOut = btSocket.getOutputStream();
} catch (Exception e) {
Log.d(Common.TAG, "Error connected to: "
+ strAddress);
bConnect = false;
mmInStream = null;
mmOutStream = null;
btSocket = null;
e.printStackTrace();
mHandler.sendEmptyMessage(Common.MESSAGE_CONNECT_LOST);
return;
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
mHandler.sendEmptyMessage(Common.MESSAGE_CONNECT_SUCCEED);
}
}).start();
break;
case Common.MESSAGE_CONNECT_SUCCEED:
addLog("连接成功");
setButtonEnable(true);
bConnect = true;
new Thread(new Runnable() {
public void run() {
byte[] bufRecv = new byte[1024];
int nRecv = 0;
while (bConnect) {
try {
/**1、start,防止数据流分多次被读出**/
if(mmInStream.available()>0 == false){
continue;
}else{
Thread.sleep(200);
}
/**1、end**/
nRecv = mmInStream.read(bufRecv);
// if (nRecv < 1) {
// Thread.sleep(100);
// continue;
// }
// System.arraycopy(bufRecv, 0, bRecv, nRecved, nRecv);
// System.arraycopy(bufRecv, 0, bRecv, 0, nRecv);
// nRecved += nRecv;
// if(nRecved < nNeed)
// {
// Thread.sleep(100);
// continue;
// }
// mHandler.obtainMessage(Common.MESSAGE_RECV, nNeed, -1, null).sendToTarget();
byte[] content=new byte[nRecv];
System.arraycopy(bufRecv,0,content,0,nRecv);
// A0 00 00 68 4B 45 00 F8 A0 00 00 68 4B 45 00 F8
String contentString=bytesToString(content);
Message msg=new Message();
msg.what=Common.MESSAGE_RECV;
msg.obj=contentString;
mHandler.sendMessage(msg);
} catch (Exception e) {
Log.e(Common.TAG, "Recv thread:" + e.getMessage());
mHandler.sendEmptyMessage(Common.MESSAGE_EXCEPTION_RECV);
break;
}
}
Log.e(Common.TAG, "Exit while");
}
}).start();
break;
case Common.MESSAGE_EXCEPTION_RECV:
mHandler.sendEmptyMessage(Common.MESSAGE_CONNECT_SUCCEED);
Log.e("TAG", "handleMessag已重新连接 " );
break;
case Common.MESSAGE_CONNECT_LOST:
addLog("连接异常,请退出本界面后重新连接");
try {
if (mmInStream != null)
mmInStream.close();
if (mmOutStream != null)
mmOutStream.close();
if (btSocket != null)
btSocket.close();
} catch (IOException e) {
Log.e(Common.TAG, "Close Error");
e.printStackTrace();
} finally {
mmInStream = null;
mmOutStream = null;
btSocket = null;
bConnect = false;
setButtonEnable(false);
}
break;
case Common.MESSAGE_WRITE:
break;
case Common.MESSAGE_READ:
break;
case Common.MESSAGE_RECV:
Log.e(TAG, "MESSAGE_RECV: " );
String content= (String) msg.obj;
Log.e(TAG, "handleMessage content: "+content );
// size=48,包含空格
setNumber(content);
// Boolean bOn = false;
// String strRecv = bytesToString(bRecv, msg.arg1);
// addLog("接收数据: " + strRecv);
// if (msg.arg1 == 9) {
// if (strRecv.indexOf("OK+Set:") != 0) {
// addLog("接收数据错误" + String.valueOf(strRecv.indexOf("OK+Set:")));
// return;
// }
// if (strRecv.charAt(strRecv.length() - 1) == '1') {
// bOn = true;
// }
// switch (strRecv.charAt(strRecv.length() - 2)) {
// case '2':
// setButtonColor(btn02, bOn);
// break;
// case '3':
// setButtonColor(btn03, bOn);
// break;
// case '4':
// setButtonColor(btn04, bOn);
// break;
// case '5':
// setButtonColor(btn05, bOn);
// break;
// case '6':
// setButtonColor(btn06, bOn);
// break;
// case '7':
// setButtonColor(btn07, bOn);
// break;
// case '8':
// setButtonColor(btn08, bOn);
// break;
// case '9':
// setButtonColor(btn09, bOn);
// break;
// case 'A':
// setButtonColor(btn10, bOn);
// break;
// case 'B':
// setButtonColor(btn11, bOn);
// break;
// }
// } else // nLength == 17
// {
// if (strRecv.indexOf("OK+PIO:") != 0) {
// addLog("接收数据错误" + String.valueOf(strRecv.indexOf("OK+PIO:")));
// return;
// }
// for (int i = 7; i < 17; i++) {
// bOn = false;
// if (strRecv.charAt(i) == '1') {
// bOn = true;
// }
// switch (i) {
// case 7:
// setButtonColor(btn02, bOn);
// break;
// case 8:
// setButtonColor(btn03, bOn);
// break;
// case 9:
// setButtonColor(btn04, bOn);
// break;
// case 10:
// setButtonColor(btn05, bOn);
// break;
// case 11:
// setButtonColor(btn06, bOn);
// break;
// case 12:
// setButtonColor(btn07, bOn);
// break;
// case 13:
// setButtonColor(btn08, bOn);
// break;
// case 14:
// setButtonColor(btn09, bOn);
// break;
// case 15:
// setButtonColor(btn10, bOn);
// break;
// case 16:
// setButtonColor(btn11, bOn);
// break;
// }
// }
// }
break;
case Common.MESSAGE_TOAST:
Toast.makeText(getApplicationContext(),
msg.getData().getString(Common.TOAST),
Toast.LENGTH_SHORT).show();
break;
}
}
};
public void setNumber(String content){
// A0 00 00 68 4B 45 00 F8 A0 00 00 68 4B 45 00 F8
// 收缩压: 104mmHg(对应 00 68); (68为16进制,转10进制为104)
// 舒张压: 78mmHg (对应 4B); (4B为16进制,转10进制为75)
// 脉搏:69bpm。 (对应 45); (45为16进制,转10进制为69)
String shousuo=content.substring(9,11);
int shousuoInt=Integer.valueOf(shousuo,16);
tv_shousuo.setText(shousuoInt+"mmHg");
String shuzhang=content.substring(12,14);
int shuzhangInt=Integer.valueOf(shuzhang,16);
tv_shuzhang.setText(shuzhangInt+"mmHg");
String maibo=content.substring(15,17);
int maiboInt=Integer.valueOf(maibo,16);//16进制转10进制
tv_maibo.setText(maiboInt+"bpm");
// addLog("接收数据: " + content);
}
private BroadcastReceiver connectDevices = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(Common.TAG, "Receiver:" + action);
if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
}
}
};
@Override
protected void onDestroy() {
this.unregisterReceiver(connectDevices);
Log.e(Common.TAG, "Free detail");
super.onDestroy();
}
/* DEMO版较为简单,在编写您的应用时,请将此函数放到线程中执行,以免UI不响应 */
public void send(Button btn, String strPio) {
String strValue = "0";
if (btn.getId() == 0)
strValue = "1";
if (!bConnect)
return;
try {
if (mmOutStream == null)
return;
if (strPio.equals("?")) {
nNeed = 17;
nRecved = 0;
mmOutStream.write(("AT+PIO" + strPio).getBytes());
addLog("发送AT+PIO" + strPio);
} else {
nNeed = 9;
nRecved = 0;
mmOutStream.write(("AT+PIO" + strPio + strValue).getBytes());
addLog("发送AT+PIO" + strPio + strValue);
}
} catch (Exception e) {
Toast.makeText(this, "发送指令失败!", Toast.LENGTH_SHORT).show();
return;
}
}
// 按钮事件
class ClickEvent implements View.OnClickListener {
@Override
public void onClick(View v) {
if (v == btnExit) {
closeAndExit();
return;
} else if (v == btnAll) {
// get status
send(btnAll, "?");
} else if (v == btn02) {
send(btn02, "2");
} else if (v == btn03) {
send(btn03, "3");
} else if (v == btn04) {
send(btn04, "4");
} else if (v == btn05) {
send(btn05, "5");
} else if (v == btn06) {
send(btn06, "6");
} else if (v == btn07) {
send(btn07, "7");
} else if (v == btn08) {
send(btn08, "8");
} else if (v == btn09) {
send(btn09, "9");
} else if (v == btn10) {
send(btn10, "A");
} else if (v == btn11) {
send(btn11, "B");
}
}
}
public void closeAndExit() {
if (bConnect) {
bConnect = false;
try {
Thread.sleep(100);
if (mmInStream != null)
mmInStream.close();
if (mmOutStream != null)
mmOutStream.close();
if (btSocket != null)
btSocket.close();
} catch (Exception e) {
Log.e(Common.TAG, "Close error...");
e.printStackTrace();
}
}
finish();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
closeAndExit();
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
public static String bytesToString(byte[] b, int length) {
// Log.e(TAG, "length: "+length );
StringBuffer result = new StringBuffer("");
for (int i = 0; i < length; i++) {
result.append((char) (b[i]));
}
return result.toString();
}
public void addLog(String str) {
tvLog.append(str + "\n");
svResult.post(new Runnable() {
public void run() {
svResult.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
public static int bytesToInt(byte[] src) {
return src[3] & 0xFF |
(src[2] & 0xFF) << 8 |
(src[1] & 0xFF) << 16 |
(src[0] & 0xFF) << 24;
}
/**
* 字节数组转化为标准的16进制字符串
*
* @param bytes 字节数组数据
* @return 字符串
*/
public static String bytesToString(byte[] bytes) {
final char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[bytes.length * 2];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
int v = bytes[i] & 0xFF;
hexChars[i * 2] = hexArray[v >>> 4];
hexChars[i * 2 + 1] = hexArray[v & 0x0F];
sb.append(hexChars[i * 2]);
sb.append(hexChars[i * 2 + 1]);
sb.append(' ');
}
return sb.toString();
}
/**
* 将十六进制byte数组转换层字符串
*/
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
// stringBuilder.append("0x" + hv.toUpperCase(Locale.CHINA) + " ");//为了方便显示,采用拼接16进制格式显示
stringBuilder.append(hv.toUpperCase(Locale.CHINA) + " ");//为了方便显示,采用拼接16进制格式显示
// if (i == 4 || i == 5 || i == 6 || i == 7) {
// Log.e("zwc", "111: " +"0x"+hv.toUpperCase(Locale.CHINA) + " " + " 222"+src[i]);
// }
}
return stringBuilder.toString();
}
}
3、commo
public class Common {
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
public static final int MESSAGE_CONNECT = 6;
public static final int MESSAGE_CONNECT_SUCCEED = 7;
public static final int MESSAGE_CONNECT_LOST = 8;
public static final int MESSAGE_RECV = 10;
public static final int MESSAGE_EXCEPTION_RECV = 11;
public static final String TOAST = "toast";
public static final String TAG = "BlueToothTool";
}