喂鱼设置状态修改

This commit is contained in:
jia 2024-09-02 19:49:19 +08:00
parent e49b5b2bf4
commit 28adf72331
15 changed files with 1681 additions and 21 deletions

View File

@ -26,5 +26,5 @@ android.enableJetifier=true
android.useAndroidX=true
android.useDeprecatedNdk=true
versionCode=43
versionName=4.11.3
versionCode=45
versionName=4.11.5

View File

@ -194,6 +194,12 @@
android:exported="false"
android:launchMode="singleTop"
android:theme="@style/Transparent" />
<activity
android:name=".BlueTooth2Activity"
android:exported="false"
android:launchMode="singleTop"
android:theme="@style/Transparent" />
<activity
android:name=".NewBindDeviceChoiceActivity"
android:exported="false"

View File

@ -43,7 +43,7 @@ import java.util.ArrayList;
* @date 2016-5-20 下午5:29:10
*/
public class BindTwoDeviceActivity extends BaseActivity {
private ImageView iv_camera, iv_device, iv_more, iv_hot, iv_pet,iv_bluetooth;
private ImageView iv_camera, iv_device, iv_more, iv_hot, iv_pet,iv_bluetooth,iv_bluetooth2;
private int width, height;
private WifiAdmin wifiAdmin;
private String wifissid = "";
@ -82,6 +82,7 @@ public class BindTwoDeviceActivity extends BaseActivity {
iv_hot = findMyViewById(R.id.iv_hot);
iv_pet = findMyViewById(R.id.iv_pet);
iv_bluetooth = findMyViewById(R.id.iv_bluetooth);
iv_bluetooth2 = findMyViewById(R.id.iv_bluetooth2);
//得到屏幕宽度按照比例为控件设置高度
// double f=width/1.432;
// height=(int)f;
@ -100,6 +101,12 @@ public class BindTwoDeviceActivity extends BaseActivity {
iv_hot.setOnClickListener(this);
iv_pet.setOnClickListener(this);
iv_bluetooth.setOnClickListener(this);
iv_bluetooth2.setOnClickListener(this);
if (BuildConfig.DEBUG){
iv_bluetooth.setVisibility(View.VISIBLE);
iv_bluetooth2.setVisibility(View.VISIBLE);
}
}
@Override
@ -249,6 +256,18 @@ public class BindTwoDeviceActivity extends BaseActivity {
});
}
}
break;
case R.id.iv_bluetooth2:{
Intent intent1 = new Intent();
intent1.setClass(BindTwoDeviceActivity.this, BluetoothActivity.class);
intent1.putExtra("devicetype", "bluetooth");
intent1.putExtra("title", "蓝牙插座");
startActivity(intent1);
AnimationUtil.startAnimation(BindTwoDeviceActivity.this);
}
break;
}
}
@ -259,7 +278,7 @@ public class BindTwoDeviceActivity extends BaseActivity {
private void toBlueTooth(){
Intent intent = new Intent();
intent.setClass(BindTwoDeviceActivity.this, BluetoothActivity.class);
intent.setClass(BindTwoDeviceActivity.this, BlueTooth2Activity.class);
intent.putExtra("devicetype", "bluetooth");
intent.putExtra("title", "蓝牙插座");
startActivity(intent);

View File

@ -0,0 +1,697 @@
package com.ifish.activity;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.ifish.baseclass.BaseActivity;
import com.ifish.bluetooth.ClsUtils;
import com.ifish.bluetooth.ConnectThread;
import com.ifish.bluetooth.ConnectedThread;
import com.ifish.bluetooth.LVDevicesAdapter;
import com.ifish.utils.L;
public class BlueTooth2Activity extends BaseActivity implements View.OnClickListener {
private static final String TAG = "BtMain";
private static final int CONNECT_SUCCESS = 0x01;
private static final int CONNECT_FAILURE = 0x02;
private static final int DISCONNECT_SUCCESS = 0x03;
private static final int SEND_SUCCESS = 0x04;
private static final int SEND_FAILURE= 0x05;
private static final int RECEIVE_SUCCESS= 0x06;
private static final int RECEIVE_FAILURE =0x07;
private static final int START_DISCOVERY = 0x08;
private static final int STOP_DISCOVERY = 0x09;
private static final int DISCOVERY_DEVICE = 0x0A;
private static final int DEVICE_BOND_NONE= 0x0B;
private static final int DEVICE_BONDING = 0x0C;
private static final int DEVICE_BONDED = 0x0D;
private Button btSearch;
private TextView tvCurConState;
private TextView tvCurBondState;
private TextView tvName;
private TextView tvAddress;
private Button btConnect;
private Button btDisconnect;
private Button btBound;
private Button btDisBound;
private EditText etSendMsg;
private Button btSend;
private TextView tvSendResult;
private TextView tvReceive;
private LinearLayout llDeviceList;
private LinearLayout llDataSendReceive;
private ListView lvDevices;
private LVDevicesAdapter lvDevicesAdapter;
//蓝牙
private BluetoothAdapter bluetoothAdapter;
private BtBroadcastReceiver btBroadcastReceiver;
//连接设备的UUID
public static final String MY_BLUETOOTH_UUID = "00001101-0000-1000-8000-00805F9B34FB"; //蓝牙通讯
//当前要连接的设备
private BluetoothDevice curBluetoothDevice;
//发起连接的线程
private ConnectThread connectThread;
//管理连接的线程
private ConnectedThread connectedThread;
//当前设备连接状态
private boolean curConnState = false;
//当前设备与系统配对状态
private boolean curBondState = false;
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what){
case START_DISCOVERY:
Log.d(TAG, "开始搜索设备...");
break;
case STOP_DISCOVERY:
Log.d(TAG, "停止搜索设备...");
break;
case DISCOVERY_DEVICE: //扫描到设备
BluetoothDevice bluetoothDevice = (BluetoothDevice) msg.obj;
lvDevicesAdapter.addDevice(bluetoothDevice);
break;
case CONNECT_FAILURE: //连接失败
Log.d(TAG, "连接失败");
tvCurConState.setText("连接失败");
curConnState = false;
break;
case CONNECT_SUCCESS: //连接成功
Log.d(TAG, "连接成功");
tvCurConState.setText("连接成功");
curConnState = true;
llDataSendReceive.setVisibility(View.VISIBLE);
llDeviceList.setVisibility(View.GONE);
break;
case DISCONNECT_SUCCESS:
tvCurConState.setText("断开成功");
curConnState = false;
break;
case SEND_FAILURE: //发送失败
Toast.makeText(BlueTooth2Activity.this, "发送失败", Toast.LENGTH_SHORT).show();
break;
case SEND_SUCCESS: //发送成功
String sendResult = (String) msg.obj;
tvSendResult.setText(sendResult);
break;
case RECEIVE_FAILURE: //接收失败
String receiveError = (String) msg.obj;
tvReceive.setText(receiveError);
break;
case RECEIVE_SUCCESS: //接收成功
String receiveResult = (String) msg.obj;
tvReceive.setText(receiveResult);
break;
case DEVICE_BOND_NONE: //已解除配对
tvCurBondState.setText("解除配对成功");
curBondState = false;
break;
case DEVICE_BONDING: //正在配对
tvCurBondState.setText("正在配对...");
break;
case DEVICE_BONDED: //已配对
tvCurBondState.setText("配对成功");
curBondState = true;
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_blue2);
initTitle("蓝牙选择设备");
//初始化视图
initView();
//初始化监听
iniListener();
//初始化数据
initData();
//初始化蓝牙
initBluetooth();
//初始化蓝牙广播
initBtBroadcast();
}
private void initData() {
lvDevicesAdapter = new LVDevicesAdapter(BlueTooth2Activity.this);
lvDevices.setAdapter(lvDevicesAdapter);
}
private void initView() {
btSearch = findViewById(R.id.bt_search);
tvCurConState = findViewById(R.id.tv_cur_con_state);
tvCurBondState = findViewById(R.id.tv_cur_bond_state);
btConnect = findViewById(R.id.bt_connect);
btDisconnect = findViewById(R.id.bt_disconnect);
btBound = findViewById(R.id.bt_bound);
btDisBound = findViewById(R.id.bt_disBound);
tvName = findViewById(R.id.tv_name);
tvAddress = findViewById(R.id.tv_address);
etSendMsg = findViewById(R.id.et_send_msg);
btSend = findViewById(R.id.bt_to_send);
tvSendResult = findViewById(R.id.tv_send_result);
tvReceive = findViewById(R.id.tv_receive_result);
llDeviceList = findViewById(R.id.ll_device_list);
llDataSendReceive = findViewById(R.id.ll_data_send_receive);
lvDevices = findViewById(R.id.lv_devices);
}
private void iniListener() {
btSearch.setOnClickListener(this);
btConnect.setOnClickListener(this);
btDisconnect.setOnClickListener(this);
btBound.setOnClickListener(this);
btDisBound.setOnClickListener(this);
btSend.setOnClickListener(this);
lvDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@SuppressLint("MissingPermission")
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
BluetoothDevice bluetoothDevice = (BluetoothDevice) lvDevicesAdapter.getItem(i);
tvName.setText(bluetoothDevice.getName());
tvAddress.setText(bluetoothDevice.getAddress());
curBluetoothDevice = bluetoothDevice;
}
});
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt_search: //搜索蓝牙
Toast.makeText(BlueTooth2Activity.this,"",Toast.LENGTH_SHORT).show();
llDataSendReceive.setVisibility(View.GONE);
llDeviceList.setVisibility(View.VISIBLE);
searchBtDevice();
break;
case R.id.bt_connect: //连接蓝牙
if(!curConnState) {
startConnectDevice(curBluetoothDevice, MY_BLUETOOTH_UUID, 10000);
}else{
Toast.makeText(this, "当前设备已连接", Toast.LENGTH_SHORT).show();
}
break;
case R.id.bt_disconnect: //断开连接
if(curConnState) {
clearConnectedThread();
}else{
Toast.makeText(this, "当前设备未连接", Toast.LENGTH_SHORT).show();
}
break;
case R.id.bt_bound: //配对设备
if(!curBondState) {
boundDevice(curBluetoothDevice);
}else{
Toast.makeText(this, "当前设备已经与系统蓝牙建立配对", Toast.LENGTH_SHORT).show();
}
break;
case R.id.bt_disBound: //解除配对
if(curBondState) {
disBoundDevice(curBluetoothDevice);
}else{
Toast.makeText(this, "当前设备尚未与系统蓝牙建立配对", Toast.LENGTH_SHORT).show();
}
break;
case R.id.bt_to_send: //发送数据
if(curConnState){
String sendMsg = etSendMsg.getText().toString();
if(sendMsg.isEmpty()){
Toast.makeText(this, "发送数据为空!", Toast.LENGTH_SHORT).show();
return;
}
sendData(sendMsg,true); //以16进制字符串形式发送数据
}else{
Toast.makeText(this, "请先连接当前设备", Toast.LENGTH_SHORT).show();
}
break;
}
}
////////////////////////////////// 搜索设备 /////////////////////////////////////////////////
@SuppressLint("MissingPermission")
private void searchBtDevice() {
if (bluetoothAdapter.isDiscovering()) { //当前正在搜索设备...
return;
}
//开始搜索
bluetoothAdapter.startDiscovery();
}
////////////////////////////////// 配对/接触配对设备 ////////////////////////////////////////////
/**
* 执行绑定 反射
* @param bluetoothDevice 蓝牙设备
* @return true 执行绑定 false 未执行绑定
*/
public boolean boundDevice(BluetoothDevice bluetoothDevice){
if(bluetoothDevice == null){
Log.e(TAG,"boundDevice-->bluetoothDevice == null");
return false;
}
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && false) {
L.i(bluetoothDevice.getName()+"jjia--------1--------type="+bluetoothDevice.getType());
return bluetoothDevice.createBond();
}else {
L.i(bluetoothDevice.getName()+"jjia--------2--------type="+bluetoothDevice.getType());
// return ClsUtils.createBond(BluetoothDevice.class,bluetoothDevice);
return ClsUtils.connn(bluetoothDevice,MY_BLUETOOTH_UUID);
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
/**
* 执行解绑 反射
* @param bluetoothDevice 蓝牙设备
* @return true 执行解绑 false未执行解绑
*/
public boolean disBoundDevice(BluetoothDevice bluetoothDevice){
if(bluetoothDevice == null){
Log.e(TAG,"disBoundDevice-->bluetoothDevice == null");
return false;
}
try {
return ClsUtils.removeBond(BluetoothDevice.class,bluetoothDevice);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
////////////////////////////////// 连接设备 ///////////////////////////////////////////////
/**
* 开始连接设备
* @param bluetoothDevice 蓝牙设备
* @param uuid 发起连接的UUID
* @param conOutTime 连接超时时间
*/
public void startConnectDevice(final BluetoothDevice bluetoothDevice, String uuid, long conOutTime){
if(bluetoothDevice == null){
Log.e(TAG,"startConnectDevice-->bluetoothDevice == null");
return;
}
if(bluetoothAdapter == null){
Log.e(TAG,"startConnectDevice-->bluetooth3Adapter == null");
return;
}
//发起连接
connectThread = new ConnectThread(bluetoothAdapter,curBluetoothDevice,uuid);
connectThread.setOnBluetoothConnectListener(new ConnectThread.OnBluetoothConnectListener() {
@SuppressLint("MissingPermission")
@Override
public void onStartConn() {
Log.d(TAG,"startConnectDevice-->开始连接..." + bluetoothDevice.getName() + "-->" + bluetoothDevice.getAddress());
}
@Override
public void onConnSuccess(BluetoothSocket bluetoothSocket) {
//移除连接超时
mHandler.removeCallbacks(connectOuttimeRunnable);
Log.d(TAG,"startConnectDevice-->移除连接超时");
Log.w(TAG,"startConnectDevice-->连接成功");
Message message = new Message();
message.what = CONNECT_SUCCESS;
mHandler.sendMessage(message);
//标记当前连接状态为true
curConnState = true;
//管理连接收发数据
managerConnectSendReceiveData(bluetoothSocket);
}
@Override
public void onConnFailure(String errorMsg) {
Log.e(TAG,"startConnectDevice-->" + errorMsg);
Message message = new Message();
message.what = CONNECT_FAILURE;
mHandler.sendMessage(message);
//标记当前连接状态为false
curConnState = false;
//断开管理连接
clearConnectedThread();
}
});
connectThread.start();
//设置连接超时时间
mHandler.postDelayed(connectOuttimeRunnable,conOutTime);
}
//连接超时
private Runnable connectOuttimeRunnable = new Runnable() {
@Override
public void run() {
Log.e(TAG,"startConnectDevice-->连接超时" );
Message message = new Message();
message.what = CONNECT_FAILURE;
mHandler.sendMessage(message);
//标记当前连接状态为false
curConnState = false;
//断开管理连接
clearConnectedThread();
}
};
////////////////////////////////////// 断开连接 //////////////////////////////////////////////
/**
* 断开已有的连接
*/
public void clearConnectedThread(){
Log.d(TAG,"clearConnectedThread-->即将断开");
//connectedThread断开已有连接
if(connectedThread == null){
Log.e(TAG,"clearConnectedThread-->connectedThread == null");
return;
}
connectedThread.terminalClose(connectThread);
//等待线程运行完后再断开
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
connectedThread.cancel(); //释放连接
connectedThread = null;
}
},10);
Log.w(TAG,"clearConnectedThread-->成功断开连接");
Message message = new Message();
message.what = DISCONNECT_SUCCESS;
mHandler.sendMessage(message);
}
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// 管理已有连接收发数据 //////////////////////////////////
/**
* 管理已建立的连接收发数据
* @param bluetoothSocket 已建立的连接
*/
public void managerConnectSendReceiveData(BluetoothSocket bluetoothSocket){
//管理已有连接
connectedThread = new ConnectedThread(bluetoothSocket);
connectedThread.start();
connectedThread.setOnSendReceiveDataListener(new ConnectedThread.OnSendReceiveDataListener() {
@Override
public void onSendDataSuccess(byte[] data) {
Log.w(TAG,"发送数据成功,长度" + data.length + "->" + bytes2HexString(data,data.length));
Message message = new Message();
message.what = SEND_SUCCESS;
message.obj = "发送数据成功,长度" + data.length + "->" + bytes2HexString(data,data.length);
mHandler.sendMessage(message);
}
@Override
public void onSendDataError(byte[] data,String errorMsg) {
Log.e(TAG,"发送数据出错,长度" + data.length + "->" + bytes2HexString(data,data.length));
Message message = new Message();
message.what = SEND_FAILURE;
message.obj = "发送数据出错,长度" + data.length + "->" + bytes2HexString(data,data.length);
mHandler.sendMessage(message);
}
@Override
public void onReceiveDataSuccess(byte[] buffer) {
Log.w(TAG,"成功接收数据,长度" + buffer.length + "->" + bytes2HexString(buffer,buffer.length));
Message message = new Message();
message.what = RECEIVE_SUCCESS;
message.obj = "成功接收数据,长度" + buffer.length + "->" + bytes2HexString(buffer,buffer.length);
mHandler.sendMessage(message);
}
@Override
public void onReceiveDataError(String errorMsg) {
Log.e(TAG,"接收数据出错:" + errorMsg);
Message message = new Message();
message.what = RECEIVE_FAILURE;
message.obj = "接收数据出错:" + errorMsg;
mHandler.sendMessage(message);
}
});
}
///////////////////////////////// 发送数据 /////////////////////////////////////////////////
/**
* 发送数据
* @param data 要发送的数据 字符串
* @param isHex 是否是16进制字符串
* @return true 发送成功 false 发送失败
*/
public boolean sendData(String data,boolean isHex){
if(connectedThread == null){
Log.e(TAG,"sendData:string -->connectedThread == null");
return false;
}
if(data == null || data.length() == 0){
Log.e(TAG,"sendData:string-->要发送的数据为空");
return false;
}
if(isHex){ //是16进制字符串
data.replace(" ",""); //取消空格
//检查16进制数据是否合法
if(data.length() % 2 != 0){
//不合法最后一位自动填充0
String lasts = "0" + data.charAt(data.length() - 1);
data = data.substring(0,data.length() - 2) + lasts;
}
Log.d(TAG,"sendData:string -->准备写入:" + data); //加空格显示
return connectedThread.write(hexString2Bytes(data));
}
//普通字符串
Log.d(TAG,"sendData:string -->准备写入:" + data);
return connectedThread.write(data.getBytes());
}
//////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////// 数据类型转换 //////////////////////////////////////////////
/**
* 字节数组-->16进制字符串
* @param b 字节数组
* @param length 字节数组长度
* @return 16进制字符串 有空格类似0A D5 CD 8F BD E5 F8
*/
public static String bytes2HexString(byte[] b, int length) {
StringBuffer result = new StringBuffer();
String hex;
for (int i = 0; i < length; i++) {
hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
result.append(hex.toUpperCase()).append(" ");
}
return result.toString();
}
/**
* hexString2Bytes
* 16进制字符串-->字节数组
* @param src 16进制字符串
* @return 字节数组
*/
public static byte[] hexString2Bytes(String src) {
int l = src.length() / 2;
byte[] ret = new byte[l];
for (int i = 0; i < l; i++) {
ret[i] = (byte) Integer
.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();
}
return ret;
}
///////////////////////////////////////////////////////////////////////////////////////////////
/**
* 初始化蓝牙
*/
@SuppressLint("MissingPermission")
private void initBluetooth() {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this, "当前手机设备不支持蓝牙", Toast.LENGTH_SHORT).show();
} else {
//手机设备支持蓝牙判断蓝牙是否已开启
if (bluetoothAdapter.isEnabled()) {
Toast.makeText(this, "手机蓝牙已开启", Toast.LENGTH_SHORT).show();
} else {
//蓝牙没有打开去打开蓝牙推荐使用第二种打开蓝牙方式
//第一种方式直接打开手机蓝牙没有任何提示
// bluetoothAdapter.enable(); //BLUETOOTH_ADMIN权限
//第二种方式友好提示用户打开蓝牙
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBtIntent);
}
}
}
/**
* 初始化蓝牙广播
*/
private void initBtBroadcast() {
//注册广播接收
btBroadcastReceiver = new BtBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); //开始扫描
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//扫描结束
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);//搜索到设备
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); //配对状态监听
registerReceiver(btBroadcastReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
//注销广播接收
unregisterReceiver(btBroadcastReceiver);
}
/**
* 蓝牙广播接收器
*/
private class BtBroadcastReceiver extends BroadcastReceiver {
@SuppressLint("MissingPermission")
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (TextUtils.equals(action, BluetoothAdapter.ACTION_DISCOVERY_STARTED)) { //开启搜索
Log.d(TAG,"开启搜索...");
Message message = new Message();
message.what = START_DISCOVERY;
mHandler.sendMessage(message);
} else if (TextUtils.equals(action, BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {//完成搜素
Log.d(TAG,"停止搜索...");
Message message = new Message();
message.what = STOP_DISCOVERY;
mHandler.sendMessage(message);
} else if (TextUtils.equals(action, BluetoothDevice.ACTION_FOUND)) { //3.0搜索到设备
//蓝牙设备
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//信号强度
int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
Log.w(TAG, "扫描到设备:" + bluetoothDevice.getName() + "-->" + bluetoothDevice.getAddress());
Message message = new Message();
message.what = DISCOVERY_DEVICE;
message.obj = bluetoothDevice;
mHandler.sendMessage(message);
}else if(TextUtils.equals(action,BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int bondSate = bluetoothDevice.getBondState();
L.i(bluetoothDevice.getName()+"jjia----------------bondSate="+bondSate);
switch(bondSate) {
case BluetoothDevice.BOND_NONE:
Log.d(TAG, "已解除配对");
Message message1 = new Message();
message1.what = DEVICE_BOND_NONE;
mHandler.sendMessage(message1);
break;
case BluetoothDevice.BOND_BONDING:
Log.d(TAG, "正在配对...");
Message message2 = new Message();
message2.what = DEVICE_BONDING;
mHandler.sendMessage(message2);
break;
case BluetoothDevice.BOND_BONDED:
Log.d(TAG, "已配对");
Message message3 = new Message();
message3.what = DEVICE_BONDED;
mHandler.sendMessage(message3);
break;
}
}
}
}
}

View File

@ -18,6 +18,7 @@ import android.widget.TextView;
import com.ifish.adapter.BlueToothController;
import com.ifish.baseclass.BaseActivity;
import com.ifish.bluetooth.ClsUtils;
import com.ifish.utils.BlueToothUtil;
import com.ifish.utils.L;
import com.ifish.utils.ToastUtil;
@ -26,7 +27,7 @@ import com.ifish.utils.ToastUtil;
public class BluetoothActivity extends BaseActivity {
BlueToothController blueToothController = new BlueToothController();
public static final String MY_BLUETOOTH_UUID = "00001101-0000-1000-8000-00805F9B34FB"; //蓝牙通讯
IntentFilter foundFilter = null;
TextView name ;
Button tv_pair;
@ -50,7 +51,14 @@ public class BluetoothActivity extends BaseActivity {
@Override
public void onClick(View view) {
if (bluetoothDevice!=null){
BlueToothUtil.Companion.boundDevice(bluetoothDevice);
try {
L.i("jjia---------getBondState----"+bluetoothDevice.getBondState());
ClsUtils.createBond1( bluetoothDevice);
} catch (Exception e) {
throw new RuntimeException(e);
}
// BlueToothUtil.Companion.boundDevice(bluetoothDevice,MY_BLUETOOTH_UUID);
}
}
});
@ -75,7 +83,7 @@ public class BluetoothActivity extends BaseActivity {
if (!TextUtils.isEmpty(deviceName) &&
(
// deviceName.contains("ifishly") ||
deviceName.equals("ifishly-fee0")
deviceName.startsWith("ifishly")
// deviceName.contains("LE-Bose")
)

View File

@ -416,22 +416,22 @@ public class FeedFishSettingActivity extends BaseActivity {
}else if(v == add_rel_setting){ //添加关联设备
showTimeSelected();
}else if(v == rl_xunhuan_bang){ //循环泵
showOpenOrCloseDialog(4,R.drawable.xunhuanbang,"循环泵",event.isLight_status1());
showOpenOrCloseDialog(4,R.drawable.xunhuanbang,"循环泵",event.isLight_status4());
}else if(v == rl_zengyang_bang){ //增氧泵
String type = Commons.DEVICE.get(Commons.DevicePosition).type;
if(Device.TYPE_5F.equals(type)){ //海水
showOpenOrCloseDialog(1,R.drawable.addobang,"蛋分器",event.isLight_status2());
showOpenOrCloseDialog(1,R.drawable.addobang,"蛋分器",event.isLight_status1());
}else{ //淡水
showOpenOrCloseDialog(1,R.drawable.addobang,"增氧泵",event.isLight_status2());
showOpenOrCloseDialog(1,R.drawable.addobang,"增氧泵",event.isLight_status1());
}
}else if(v == rl_light1){ //灯光1
showOpenOrCloseDialog(2,R.drawable.linght1,"灯光1",event.isLight_status3());
showOpenOrCloseDialog(2,R.drawable.linght1,"灯光1",event.isLight_status2());
}else if(v == rl_light2){ //灯光2
showOpenOrCloseDialog(3,R.drawable.linght2,"灯光2",event.isLight_status4());
showOpenOrCloseDialog(3,R.drawable.linght2,"灯光2",event.isLight_status3());
}else if(v == rl_zaolangbang){ //造浪泵
showOpenOrCloseDialog(6,R.drawable.zaolangbang,"造浪泵",event.isLight_status5());
showOpenOrCloseDialog(6,R.drawable.zaolangbang,"造浪泵",event.isLight_status6());
}else if(v == rl_shajun_light){ //杀菌灯
showOpenOrCloseDialog(5,R.drawable.shajundeng,"杀菌灯",event.isLight_status6());
showOpenOrCloseDialog(5,R.drawable.shajundeng,"杀菌灯",event.isLight_status5());
}
}

View File

@ -28,13 +28,10 @@ public class BlueToothController {
}
@SuppressLint("MissingPermission")
public void open(Activity activity) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
ToastUtil.show(activity,"");
return;
}
// Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
activity.startActivityForResult(intent, 11);
}

View File

@ -0,0 +1,197 @@
package com.ifish.bluetooth;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
import com.ifish.utils.L;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
public class ClsUtils {
public static BluetoothDevice remoteDevice = null;
/**
* 与设备配对 参考源码platform/packages/apps/Settings.git
* /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
*/
@SuppressLint("MissingPermission")
static public boolean connn(BluetoothDevice btDevice,String uuid){
try {
BluetoothSocket socket = btDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(uuid));
socket.connect();
return true;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
static public boolean createBond1(BluetoothDevice btDevice)
throws Exception {
Method createBondMethod = btDevice.getClass().getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
@SuppressWarnings("unchecked")
static public boolean createBond(@SuppressWarnings("rawtypes") Class btClass, BluetoothDevice btDevice)
throws Exception {
Method createBondMethod = btClass.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
//自动配对设置Pin值
static public boolean autoBond(Class btClass,BluetoothDevice device,String strPin) throws Exception {
Method autoBondMethod = btClass.getMethod("setPin",new Class[]{byte[].class});
Boolean result = (Boolean)autoBondMethod.invoke(device,new Object[]{strPin.getBytes()});
return result;
}
static public void setPairingConfirmation(BluetoothDevice device){
try {
Field field = device.getClass().getDeclaredField("sService");
field.setAccessible(true);
Object service = field.get(device);
Method method = service.getClass().getDeclaredMethod("setPairingConfirmation",
BluetoothDevice.class, boolean.class);
method.setAccessible(true);
method.invoke(service, device, true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* 与设备解除配对 参考源码platform/packages/apps/Settings.git
* /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
*/
@SuppressWarnings("unchecked")
static public boolean removeBond(Class btClass, BluetoothDevice btDevice)
throws Exception {
Method removeBondMethod = btClass.getMethod("removeBond");
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
@SuppressWarnings("unchecked")
static public boolean setPin(Class btClass, BluetoothDevice btDevice,
String str) throws Exception {
try {
Method removeBondMethod = btClass.getDeclaredMethod("setPin",
new Class[]
{byte[].class});
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice,
new Object[]
{str.getBytes()});
} catch (SecurityException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
} catch (IllegalArgumentException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
// 取消用户输入
//cancelPairingUserInput取消用户输入密钥框
// 个人觉得一般情况下不要和
// setPinsetPasskeysetPairingConfirmation setRemoteOutOfBandData一起用
// 这几个方法都会remove掉map里面的key:value也就是互斥的
@SuppressWarnings("unchecked")
static public boolean cancelPairingUserInput(Class btClass,
BluetoothDevice device)
throws Exception {
Method createBondMethod = btClass.getMethod("cancelPairingUserInput");
// cancelBondProcess()
Boolean returnValue = (Boolean) createBondMethod.invoke(device);
return returnValue.booleanValue();
}
// 取消配对
@SuppressWarnings("unchecked")
static public boolean cancelBondProcess(Class btClass,
BluetoothDevice device)
throws Exception {
Method createBondMethod = btClass.getMethod("cancelBondProcess");
Boolean returnValue = (Boolean) createBondMethod.invoke(device);
return returnValue.booleanValue();
}
/**
* @param clsShow
*/
@SuppressWarnings("unchecked")
static public void printAllInform(Class clsShow) {
try {
// 取得所有方法
Method[] hideMethod = clsShow.getMethods();
int i = 0;
for (; i < hideMethod.length; i++) {
//Log.e("method name", hideMethod.getName() + ";and the i is:"
// + i);
}
// 取得所有常量
Field[] allFields = clsShow.getFields();
for (i = 0; i < allFields.length; i++) {
//Log.e("Field name", allFields.getName());
}
} catch (SecurityException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
} catch (IllegalArgumentException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Clears the internal cache and forces a refresh of the services from the * remote device.
*/
public static boolean refreshDeviceCache(BluetoothGatt mBluetoothGatt) {
if (mBluetoothGatt != null) {
try {
BluetoothGatt localBluetoothGatt = mBluetoothGatt;
Method localMethod = localBluetoothGatt.getClass().getMethod("refresh", new Class[0]);
if (localMethod != null) {
boolean bool = ((Boolean) localMethod.invoke(localBluetoothGatt, new Object[0])).booleanValue();
return bool;
}
} catch (Exception localException) {
Log.i("Config", "An exception occured while refreshing device");
}
}
return false;
}
}

View File

@ -0,0 +1,136 @@
package com.ifish.bluetooth;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
import java.io.IOException;
import java.util.UUID;
/**
* 发起蓝牙连接
*/
public class ConnectThread extends Thread {
private static final String TAG = "ConnectThread";
private final BluetoothAdapter mBluetoothAdapter;
private BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothAdapter bluetoothAdapter,BluetoothDevice bluetoothDevice,String uuid) {
this.mBluetoothAdapter = bluetoothAdapter;
this.mmDevice = bluetoothDevice;
//使用一个临时变量等会赋值给mmSocket
//因为mmSocket是静态的
BluetoothSocket tmp = null ;
if(mmSocket != null){
Log.e(TAG,"ConnectThread-->mmSocket != null先去释放");
try {
mmSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Log.d(TAG,"ConnectThread-->mmSocket != null已释放");
//1获取BluetoothSocket
try {
//建立安全的蓝牙连接会弹出配对框
tmp = mmDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
} catch (IOException e) {
Log.e(TAG,"ConnectThread-->获取BluetoothSocket异常!" + e.getMessage());
}
mmSocket = tmp;
if(mmSocket != null){
Log.w(TAG,"ConnectThread-->已获取BluetoothSocket");
}
}
@Override
public void run(){
//连接之前先取消发现设备否则会大幅降低连接尝试的速度并增加连接失败的可能性
if(mBluetoothAdapter == null){
Log.e(TAG,"ConnectThread:run-->mBluetoothAdapter == null");
return;
}
//取消发现设备
if(mBluetoothAdapter.isDiscovering()){
mBluetoothAdapter.cancelDiscovery();
}
if(mmSocket == null){
Log.e(TAG,"ConnectThread:run-->mmSocket == null");
return;
}
//2通过socket去连接设备
try {
Log.d(TAG,"ConnectThread:run-->去连接...");
if(onBluetoothConnectListener != null){
onBluetoothConnectListener.onStartConn(); //开始去连接回调
}
mmSocket.connect(); //connect()为阻塞调用连接失败或 connect() 方法超时大约 12 秒之后它将会引发异常
if(onBluetoothConnectListener != null){
onBluetoothConnectListener.onConnSuccess(mmSocket); //连接成功回调
Log.w(TAG,"ConnectThread:run-->连接成功");
}
} catch (IOException e) {
Log.e(TAG,"ConnectThread:run-->连接异常!" + e.getMessage());
if(onBluetoothConnectListener != null){
onBluetoothConnectListener.onConnFailure("连接异常:" + e.getMessage());
}
//释放
cancel();
}
}
/**
* 释放
*/
public void cancel() {
try {
if (mmSocket != null && mmSocket.isConnected()) {
Log.d(TAG,"ConnectThread:cancel-->mmSocket.isConnected() = " + mmSocket.isConnected());
mmSocket.close();
mmSocket = null;
return;
}
if (mmSocket != null) {
mmSocket.close();
mmSocket = null;
}
Log.d(TAG,"ConnectThread:cancel-->关闭已连接的套接字释放资源");
} catch (IOException e) {
Log.e(TAG,"ConnectThread:cancel-->关闭已连接的套接字释放资源异常!" + e.getMessage());
}
}
private OnBluetoothConnectListener onBluetoothConnectListener;
public void setOnBluetoothConnectListener(OnBluetoothConnectListener onBluetoothConnectListener) {
this.onBluetoothConnectListener = onBluetoothConnectListener;
}
//连接状态监听者
public interface OnBluetoothConnectListener{
void onStartConn(); //开始连接
void onConnSuccess(BluetoothSocket bluetoothSocket); //连接成功
void onConnFailure(String errorMsg); //连接失败
}
}

View File

@ -0,0 +1,206 @@
package com.ifish.bluetooth;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
/**
* 管理连接
* 1发送数据
* 2接收数据
*/
public class ConnectedThread extends Thread{
private static final String TAG = "ConnectedThread";
private BluetoothSocket mmSocket;
private InputStream mmInStream;
private OutputStream mmOutStream;
//是否是主动断开
private boolean isStop = false;
//发起蓝牙连接的线程
private ConnectThread connectThread;
public void terminalClose(ConnectThread connectThread){
isStop = true;
this.connectThread = connectThread;
}
public ConnectedThread(BluetoothSocket socket){
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
//使用临时对象获取输入和输出流因为成员流是静态类型
//1获取 InputStream OutputStream
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG,"ConnectedThread-->获取InputStream 和 OutputStream异常!");
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
if(mmInStream != null){
Log.d(TAG,"ConnectedThread-->已获取InputStream");
}
if(mmOutStream != null){
Log.d(TAG,"ConnectedThread-->已获取OutputStream");
}
}
public void run(){
//最大缓存区 存放流
byte[] buffer = new byte[1024 * 2]; //buffer store for the stream
//从流的read()方法中读取的字节数
int bytes = 0; //bytes returned from read()
//持续监听输入流直到发生异常
while(!isStop){
try {
if(mmInStream == null){
Log.e(TAG,"ConnectedThread:run-->输入流mmInStream == null");
break;
}
//先判断是否有数据有数据再读取
if(mmInStream.available() != 0){
//2接收数据
bytes = mmInStream.read(buffer); //(mmInStream)输入流中(读取内容)读取的一定数量字节数,并将它们存储到缓冲区buffer数组中bytes为实际读取的字节数
byte[] b = Arrays.copyOf(buffer,bytes); //存放实际读取的数据内容
Log.w(TAG,"ConnectedThread:run-->收到消息,长度" + b.length + "->" + bytes2HexString(b, b.length)); //有空格的16进制字符串
if(onSendReceiveDataListener != null){
onSendReceiveDataListener.onReceiveDataSuccess(b); //成功收到消息
}
}
} catch (IOException e) {
Log.e(TAG,"ConnectedThread:run-->接收消息异常!" + e.getMessage());
if(onSendReceiveDataListener != null){
onSendReceiveDataListener.onReceiveDataError("接收消息异常:" + e.getMessage()); //接收消息异常
}
//关闭流和socket
boolean isClose = cancel();
if(isClose){
Log.e(TAG,"ConnectedThread:run-->接收消息异常,成功断开连接!");
}
break;
}
}
//关闭流和socket
boolean isClose = cancel();
if(isClose){
Log.d(TAG,"ConnectedThread:run-->接收消息结束,断开连接!");
}
}
//发送数据
public boolean write(byte[] bytes){
try {
if(mmOutStream == null){
Log.e(TAG, "mmOutStream == null");
return false;
}
//发送数据
mmOutStream.write(bytes);
Log.d(TAG, "写入成功:"+ bytes2HexString(bytes, bytes.length));
if(onSendReceiveDataListener != null){
onSendReceiveDataListener.onSendDataSuccess(bytes); //发送数据成功回调
}
return true;
} catch (IOException e) {
Log.e(TAG, "写入失败:"+ bytes2HexString(bytes, bytes.length));
if(onSendReceiveDataListener != null){
onSendReceiveDataListener.onSendDataError(bytes,"写入失败"); //发送数据失败回调
}
return false;
}
}
/**
* 释放
* @return true 断开成功 false 断开失败
*/
public boolean cancel(){
try {
if(mmInStream != null){
mmInStream.close(); //关闭输入流
}
if(mmOutStream != null){
mmOutStream.close(); //关闭输出流
}
if(mmSocket != null){
mmSocket.close(); //关闭socket
}
if(connectThread != null){
connectThread.cancel();
}
connectThread = null;
mmInStream = null;
mmOutStream = null;
mmSocket = null;
Log.w(TAG,"ConnectedThread:cancel-->成功断开连接");
return true;
} catch (IOException e) {
// 任何一部分报错都将强制关闭socket连接
mmInStream = null;
mmOutStream = null;
mmSocket = null;
Log.e(TAG, "ConnectedThread:cancel-->断开连接异常!" + e.getMessage());
return false;
}
}
/**
* 字节数组-->16进制字符串
* @param b 字节数组
* @param length 字节数组长度
* @return 16进制字符串 有空格类似0A D5 CD 8F BD E5 F8
*/
public static String bytes2HexString(byte[] b, int length) {
StringBuffer result = new StringBuffer();
String hex;
for (int i = 0; i < length; i++) {
hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
result.append(hex.toUpperCase()).append(" ");
}
return result.toString();
}
private OnSendReceiveDataListener onSendReceiveDataListener;
public void setOnSendReceiveDataListener(OnSendReceiveDataListener onSendReceiveDataListener) {
this.onSendReceiveDataListener = onSendReceiveDataListener;
}
//收发数据监听者
public interface OnSendReceiveDataListener{
void onSendDataSuccess(byte[] data); //发送数据结束
void onSendDataError(byte[] data, String errorMsg); //发送数据出错
void onReceiveDataSuccess(byte[] buffer); //接收到数据
void onReceiveDataError(String errorMsg); //接收数据出错
}
}

View File

@ -0,0 +1,115 @@
package com.ifish.bluetooth;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.ifish.activity.R;
import java.util.ArrayList;
import java.util.List;
/**
* 搜索到的设备列表适配器
*/
public class LVDevicesAdapter extends BaseAdapter {
private Context context;
private List<BluetoothDevice> list;
public LVDevicesAdapter(Context context) {
this.context = context;
list = new ArrayList<>();
}
@Override
public int getCount() {
return list == null ? 0 : list.size();
}
@Override
public Object getItem(int i) {
if(list == null){
return null;
}
return list.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
DeviceViewHolder viewHolder;
if(view == null){
view = LayoutInflater.from(context).inflate(R.layout.layout_lv_devices_item,null);
viewHolder = new DeviceViewHolder();
viewHolder.tvDeviceName = view.findViewById(R.id.tv_device_name);
viewHolder.tvDeviceAddress = view.findViewById(R.id.tv_device_address);
view.setTag(viewHolder);
}else{
viewHolder = (DeviceViewHolder) view.getTag();
}
if(list.get(i).getName() == null){
viewHolder.tvDeviceName.setText("NULL");
}else{
viewHolder.tvDeviceName.setText(list.get(i).getName());
}
viewHolder.tvDeviceAddress.setText(list.get(i).getAddress());
return view;
}
/**
* 初始化所有设备列表
* @param bluetoothDevices
*/
public void addAllDevice(List<BluetoothDevice> bluetoothDevices){
if(list != null){
list.clear();
}
for (BluetoothDevice bluetoothDevice : bluetoothDevices) {
list.add(bluetoothDevice);
}
notifyDataSetChanged();
}
/**
* 添加列表子项
* @param bluetoothDevice
*/
public void addDevice(BluetoothDevice bluetoothDevice){
if(list == null){
return;
}
if(!list.contains(bluetoothDevice)){
list.add(bluetoothDevice);
}
notifyDataSetChanged(); //刷新
}
/**
* 清空列表
*/
public void clear(){
if(list != null){
list.clear();
}
notifyDataSetChanged(); //刷新
}
class DeviceViewHolder {
TextView tvDeviceName;
TextView tvDeviceAddress;
}
}

View File

@ -8,10 +8,10 @@ class BlueToothUtil {
companion object{
@SuppressLint("MissingPermission")
fun boundDevice(devicex: BluetoothDevice?){
fun boundDevice(devicex: BluetoothDevice?,ii:String){
var method = BluetoothDevice::class.java.getMethod("createBond")
method.invoke(devicex)
var clientSocket = devicex!!.createRfcommSocketToServiceRecord(UUID.fromString(devicex.address))
var clientSocket = devicex!!.createRfcommSocketToServiceRecord(UUID.fromString(ii))
clientSocket.connect()
}

View File

@ -57,6 +57,16 @@
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/device_petdevice"
android:visibility="gone"
android:scaleType="fitXY" />
<ImageView
android:id="@+id/iv_bluetooth2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:visibility="gone"
android:src="@drawable/device_petdevice"
android:scaleType="fitXY" />
<ImageView
android:id="@+id/iv_more"

View File

@ -0,0 +1,245 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".BlueTooth2Activity"
android:focusableInTouchMode="true">
<include
android:id="@+id/in_daohang"
layout="@layout/title_layout" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/ll_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/bt_search"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:text="搜索"
android:textColor="#FFFFFF"
android:textSize="14sp"
android:background="@color/blue"/>
<TextView
android:id="@+id/tv_cur_con_state"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@color/colorPrimary"/>
<TextView
android:id="@+id/tv_cur_bond_state"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@color/colorPrimary"/>
</LinearLayout>
<LinearLayout
android:layout_toRightOf="@+id/ll_search"
android:layout_marginLeft="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:hint="设备名"
android:textColor="@color/white"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:background="@color/blue"/>
<TextView
android:id="@+id/tv_address"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:hint="设备地址"
android:textColor="@color/white"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:background="@color/blue"/>
<LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/bt_connect"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:text="连接"
android:textColor="#FFFFFF"
android:textSize="14sp"
android:background="@color/blue"/>
<Button
android:id="@+id/bt_disconnect"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:text="断开"
android:textColor="#FFFFFF"
android:textSize="14sp"
android:background="@color/blue"/>
</LinearLayout>
<LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/bt_bound"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:text="配对"
android:textColor="#FFFFFF"
android:textSize="14sp"
android:background="@color/blue"/>
<Button
android:id="@+id/bt_disBound"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:text="解除配对"
android:textColor="#FFFFFF"
android:textSize="14sp"
android:background="@color/blue"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
<!--搜索设备列表-->
<LinearLayout
android:id="@+id/ll_device_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:visibility="visible">
<ListView
android:id="@+id/lv_devices"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
<!--数据收发-->
<LinearLayout
android:id="@+id/ll_data_send_receive"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="设置要发送的数据(十六进制字符串形式)"
android:textColor="@color/colorPrimary"/>
<EditText
android:id="@+id/et_send_msg"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="#333333"
android:padding="10dp"
android:hint="在此输入要发送的数据"
android:background="@color/blue"/>
<Button
android:id="@+id/bt_to_send"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:text="发送"
android:textColor="#FFFFFF"
android:textSize="14sp"
android:background="@color/blue"/>
<TextView
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="显示接收的数据操作结果(发送成功/发送失败)"
android:textColor="@color/colorPrimary"/>
<ScrollView
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/blue">
<TextView
android:id="@+id/tv_send_result"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:textSize="14sp"
android:hint="此处显示发送数据操作结果"
android:textColor="@color/colorPrimary"/>
</ScrollView>
<TextView
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="显示接收的数据(以十六进制字符串显示)"
android:textColor="@color/colorPrimary"/>
<ScrollView
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/blue">
<TextView
android:id="@+id/tv_receive_result"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:textSize="14sp"
android:hint="此处显示发送数据操作结果"
android:textColor="@color/colorPrimary"/>
</ScrollView>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_device_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textColor="@color/colorPrimary"
android:textSize="16sp"/>
<TextView
android:id="@+id/tv_device_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textColor="@color/colorPrimary"
android:textSize="16sp"/>
</LinearLayout>