最近因为要做实训,智能窗户,所以就写了一个蓝牙通信的APP来控制。所以也不是很深入的了解使用,只是那别人的改改。
1、需要在AndroidManifest.xml中加入一下权限
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!-- 要想改变蓝牙的可发现性以及启用/禁用蓝牙适配器需要加入下面的权限-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
2、检查设备上蓝牙的状态
private BluetoothAdapter buAdapter;
buAdapter = BluetoothAdapter.getDefaultAdapter();
if(buAdapter == null){
//返回null表示设备不支持蓝牙
return;
}
if(buAdapter.isEnabled()){
//设备的蓝牙是打开的
return;
}else {
//方式一
//buAdapter.enable();打开蓝牙设备
//方式二,建议使用
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE);
}
private static final int REQUEST_ENABLE = 1;
private static final int REQUEST_DISCOVERABLE = 2;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
switch (requestCode) {
case REQUEST_ENABLE:
if(resultCode != Activity.RESULT_OK){
showToast("Bluetooth Not Enabled.");
}
break;
case REQUEST_DISCOVERABLE:
break;
default:
break;
}
}
3、搜索模式
private ArrayList<SiriListItem> list;
public class SiriListItem {
String message;
boolean isSiri;
public SiriListItem(String msg, boolean siri) {
message = msg;
isSiri = siri;
}
}
public void find() {
if(btn_find.getText().equals("搜索设备")){
mListView.setVisibility(View.VISIBLE);
//setPr
tv.setVisibility(View.GONE);
progressDialog.setMessage("正在搜索....");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.show();
if(buAdapter.isDiscovering()){
buAdapter.cancelDiscovery();
//btn_find.setText("停止搜索");
}else {
list.clear();
mAdapter.notifyDataSetChanged();
pairedDevices = buAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
list.add(new SiriListItem(device.getName() + "\n" + device.getAddress(), true));
mAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
}else {
list.add(new SiriListItem("No devices have been paired", true));
mAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
}
//开始搜索
buAdapter.startDiscovery();
//btn_find.setText("停止搜索");
}else {
if (serviceOrCilent == ServerOrCilent.CILENT)
{
shutdownClient();
}
else if (serviceOrCilent == ServerOrCilent.SERVICE)
{
shutdownServer();
}
serviceOrCilent=ServerOrCilent.NONE;
showToast("已断开连接!");
btn_find.setText("搜索设备");
}
}
4、设备连接
private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
// Cancel discovery because it's costly and we're about to connect
SiriListItem item = list.get(arg2);
String info = item.message;
String address = info.substring(info.length() - 17);
BlueToothAddress = address;
AlertDialog.Builder StopDialog =new AlertDialog.Builder(MainActivity.this);//定义一个弹出框对象
StopDialog.setTitle("连接");//标题
StopDialog.setMessage(item.message);
StopDialog.setPositiveButton("连接", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
buAdapter.cancelDiscovery();//停止搜索
serviceOrCilent=ServerOrCilent.CILENT;
clientThread clientConnectThread = new clientThread();
clientConnectThread.start();
}
});
StopDialog.setNegativeButton("取消",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
BlueToothAddress = null;
}
});
StopDialog.show();
}
};
5、广播和服务
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
if (device.getBondState() != BluetoothDevice.BOND_BONDED)
{
list.add(new SiriListItem(device.getName() + "\n" + device.getAddress(), false));
mAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
// When discovery is finished, change the Activity title
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
{
setProgressBarIndeterminateVisibility(false);
if (mListView.getCount() == 0)
{
list.add(new SiriListItem("没有发现蓝牙设备", false));
mAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
//btn_find.setText("重新搜索");
}
}
};
@Override
protected void onDestroy() {
super.onDestroy();
// Make sure we're not doing discovery anymore
if (buAdapter != null) {
buAdapter.cancelDiscovery();
}
// Unregister broadcast listeners
this.unregisterReceiver(mReceiver);
}
//开启客户端
private class clientThread extends Thread {
public void run() {
try {
device = buAdapter.getRemoteDevice(BlueToothAddress);
//创建一个Socket连接:只需要服务器在注册时的UUID号
// socket = device.createRfcommSocketToServiceRecord(BluetoothProtocols.OBEX_OBJECT_PUSH_PROTOCOL_UUID);
socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
Message msg2 = new Message();
msg2.obj = "请稍候,正在连接服务器:"+BlueToothAddress;
msg2.what = 1;
LinkDetectedHandler.sendMessage(msg2);
socket.connect();
Message msg = new Message();
msg.obj = "已经连接上" + BlueToothAddress + "服务端!可以发送信息";
msg.what = 0;
LinkDetectedHandler.sendMessage(msg);
//启动接受数据
mreadThread = new readThread();
mreadThread.start();
}
catch (IOException e)
{
Log.e("connect", "", e);
}
}
};
//开启服务器
private class ServerThread extends Thread {
public void run() {
try {
/* 创建一个蓝牙服务器
* 参数分别:服务器名称、UUID */
mserverSocket = buAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
Log.d("server", "wait cilent connect...");
Message msg = new Message();
msg.obj = "请稍候,正在等待客户端的连接...";
msg.what = 3;
LinkDetectedHandler.sendMessage(msg);
/* 接受客户端的连接请求 */
socket = mserverSocket.accept();
Log.d("server", "accept success !");
Message msg2 = new Message();
String info = "客户端已经连接上!可以发送信息。";
msg2.obj = info;
msg.what = 3;
LinkDetectedHandler.sendMessage(msg2);
//启动接受数据
mreadThread = new readThread();
mreadThread.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
/* 停止服务器 */
private void shutdownServer() {
new Thread() {
public void run() {
if(startServerThread != null)
{
startServerThread.interrupt();
startServerThread = null;
}
if(mreadThread != null)
{
mreadThread.interrupt();
mreadThread = null;
}
try {
if(socket != null)
{
socket.close();
socket = null;
}
if (mserverSocket != null)
{
mserverSocket.close();/* 关闭服务器 */
mserverSocket = null;
}
} catch (IOException e) {
Log.e("server", "mserverSocket.close()", e);
}
};
}.start();
}
/* 停止客户端连接 */
private void shutdownClient() {
new Thread() {
public void run() {
if(clientConnectThread!=null)
{
clientConnectThread.interrupt();
clientConnectThread= null;
}
if(mreadThread != null)
{
mreadThread.interrupt();
mreadThread = null;
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
socket = null;
}
};
}.start();
}
//发送数据
private void sendMessageHandle(String msg)
{
if (socket == null)
{
showToast("没有连接");
return;
}
try {
OutputStream os = socket.getOutputStream();
os.write(msg.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
6、读取数据
//读取数据
private class readThread extends Thread {
public void run() {
byte[] buffer = new byte[1024];
int bytes;
InputStream mmInStream = null;
try {
mmInStream = socket.getInputStream();//蓝牙获取的数据
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while (true) {
try {
// String ss = new String();
// Read from the InputStream
bytes = mmInStream.read(buffer);
String buf_data = new String(buffer);
buf_data = buf_data.substring(0, bytes);
if(buf_data != null)
sss += buf_data;
else
return;
if(!sss.contains("#")){
continue;
}
Log.i("接收完毕:", sss);
Message msg = new Message();
msg.obj="";
msg.obj = sss;
sss="";
msg.what = 2;
LinkDetectedHandler.sendMessage(msg);
}
catch (IOException e) {
try {
mmInStream.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
break;
}
}
}
}
public String dataTime(){
// 创建日期对象
Date d = new Date();
//在把一个字符串解析为日期的时候,请注意格式必须和给定的字符串格式匹配
SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日 HH:mm");
String s = sdf.format(d);
return s;
}
7、数据反馈
private Handler LinkDetectedHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
CloudsServe cloudsServe = new CloudsServe(MainActivity.this);
String time = dataTime();
switch (msg.what) {
case 0:
progressDialog.dismiss();
btn_find.setText("断开连接");
showToast("连接成功");
mListView.setVisibility(View.GONE);
tv.setVisibility(View.VISIBLE);
String str2 = (String)msg.obj;
msgArrary2.add(str2);
String s2 = "";
for(String msgStr: msgArrary2){
s2 += msgStr + "\n";
}
tv.setText(s2);
break;
case 1:
progressDialog.setMessage("正在连接....");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.show();
break;
case 2:
mListView.setVisibility(View.GONE);
tv.setVisibility(View.VISIBLE);
String str = (String)msg.obj;
str = str.substring(0,str.length()-1);
Boolean closeOk = str.contains("close windows ok!");
Boolean openOk = str.contains("open windows ok!");
Boolean closeNo = str.contains("close no!");
Boolean openNo = str.contains("open no!");
if(str.contains("rain")){
int start = str.indexOf('=');
String rain = str.substring(start + 1);
showToast(rain);
Integer integer = new Integer(rain);
int nowRain = (int)integer;
String state = "";
if(str.contains("close")){
state = "close";
}else {
state = "open ";
}
if(nowRain < 900){
read("小娜为您播报天气情况,现在是北京时间" + time + "雨水量为" + rain + "最近下过雨,出门记得带雨伞");
}else {
read("小娜为您播报天气情况,现在是北京时间" + time + "雨水量为" + rain + "最近没有下雨,放心去玩吧");
}
cloudsServe.saveDate("三教204", rain,state , time);
Double r = new Double(rain);
insertApi(r, time.substring(time.indexOf(" ")));
}
if(openOk){
int end = str.indexOf('o');
String rain = str.substring(0,end);
read("正在为您打开窗户");
cloudsServe.saveDate("三教204", rain,"open ", time);
Double r = new Double(rain);
insertApi(r, time.substring(time.indexOf(" ")));
}
if(closeOk){
int end = str.indexOf('c');
String rain = str.substring(0,end);
read("正在为您关闭窗户");
cloudsServe.saveDate("三教204", rain,"close", time);
Double r = new Double(rain);
insertApi(r, time.substring(time.indexOf(" ")));
}
if(openNo){
int end = str.indexOf('o');
String rain = str.substring(0,end);
read("现在窗户已经打开了,不能再开了");
cloudsServe.saveDate("三教204", rain,"close", time);
Double r = new Double(rain);
insertApi(r, time.substring(time.indexOf(" ")));
}
if(closeNo){
int end = str.indexOf('c');
String rain = str.substring(0,end);
read("现在窗户已经关闭了,不能再关了");
cloudsServe.saveDate("三教204", rain,"open ", time);
Double r = new Double(rain);
insertApi(r, time.substring(time.indexOf(" ")));
}
msgArrary.add(str);
String s = "";
for(String msgStr: msgArrary){
s += msgStr + "\n";
}
tv.setText(s);
break;
default:
break;
}
}
};
8、相应的初始化
/* 一些常量,代表服务器的名称 */
public static final String PROTOCOL_SCHEME_L2CAP = "btl2cap";
public static final String PROTOCOL_SCHEME_RFCOMM = "btspp";
public static final String PROTOCOL_SCHEME_BT_OBEX = "btgoep";
public static final String PROTOCOL_SCHEME_TCP_OBEX = "tcpobex";
private BluetoothServerSocket mserverSocket = null;
private ServerThread startServerThread = null;
private clientThread clientConnectThread = null;
private BluetoothSocket socket = null;
private BluetoothDevice device = null;
private readThread mreadThread = null;;
private Button btn_device,btn_find,btn_star,btn_open,btn_close,btn_look,btn_voice,btn_clouds,btn_chart;
private TextView tv;
static String BlueToothAddress = "null";
enum ServerOrCilent{
NONE,
SERVICE,
CILENT
};
static ServerOrCilent serviceOrCilent = ServerOrCilent.NONE;
private BluetoothAdapter buAdapter;
Set<BluetoothDevice> pairedDevices;
private ArrayList<SiriListItem> list;
private ListView mListView;
MyAdapetr mAdapter;
Context mContext;
ProgressDialog progressDialog;
ArrayList<String> msgArrary;
ArrayList<String> msgArrary2;
ArrayList<Double> yList;
ArrayList<String> xRawDatas;
//获取蓝牙适配器
buAdapter = BluetoothAdapter.getDefaultAdapter();
list = new ArrayList<SiriListItem>();
mAdapter = new MyAdapetr(this, list);
mListView = (ListView) findViewById(R.id.list);
mListView.setAdapter(mAdapter);
mListView.setFastScrollEnabled(true);
mListView.setOnItemClickListener(mDeviceClickListener);
// Register for broadcasts when a device is discovered
IntentFilter discoveryFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, discoveryFilter);
// Register for broadcasts when discovery has finished
IntentFilter foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, foundFilter);
// Get a set of currently paired devices
Set<BluetoothDevice> pairedDevices = buAdapter.getBondedDevices();
// If there are paired devices, add each one to the ArrayAdapter
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
list.add(new SiriListItem(device.getName() + "\n" + device.getAddress(), true));
mAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
} else {
list.add(new SiriListItem("没有设备已经配对", true));
mAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
public class MyAdapetr extends BaseAdapter{
private ArrayList<SiriListItem> list;
private LayoutInflater mInflater;
public MyAdapetr(Context context, ArrayList<SiriListItem> list){
this.list = list;
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return list.size();
}
public Object getItem(int position) {
return list.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
SiriListItem item=list.get(position);
if(convertView == null){
convertView = mInflater.inflate(R.layout.list_item, null);
viewHolder=new ViewHolder(
(View) convertView.findViewById(R.id.list_child),
(TextView) convertView.findViewById(R.id.chat_msg)
);
convertView.setTag(viewHolder);
}
else{
viewHolder = (ViewHolder)convertView.getTag();
}
if(item.isSiri)
{
viewHolder.child.setBackgroundResource(R.drawable.msgbox_rec);
}
else
{
viewHolder.child.setBackgroundResource(R.drawable.msgbox_send);
}
viewHolder.msg.setText(item.message);
return convertView;
}
class ViewHolder {
protected View child;
protected TextView msg;
public ViewHolder(View child, TextView msg){
this.child = child;
this.msg = msg;
}
}
}
8、arduino模块代码
#include<Stepper.h>
int ASignal = A0;//定义雨水量的模拟引脚
int Do = 7;//传感器的端口
int ledPin = 12;//定义板子的灯
//定义电机的端口号
#define A1 8
#define B1 9
#define C1 10
#define D1 11
//声明布进电机的4步函数
void Phase_A();
void Phase_B();
void Phase_C();
void Phase_D();
void zhengZhuan();
void fanZhuan();
int flag = 1; //初始化窗户为打开状态,0为关闭状态
int flag2 = 3;//初始化开始的模式
void setup() {
//定义引脚的状态,输出,输入状态
pinMode(ASignal, INPUT);
pinMode(12, OUTPUT);
pinMode(Do, INPUT);
pinMode(A1,OUTPUT);
pinMode(B1,OUTPUT);
pinMode(C1,OUTPUT);
pinMode(D1,OUTPUT);
Serial.begin(9600); //发送数据的波特率
}
void loop() {
int sensorValue = analogRead(ASignal); //获取雨水量的模拟量
int n = digitalRead(Do);//读取Do电平,Do为高电平没有水,低电平为有水
if(Serial.available()>0){ //判断是否有蓝牙传输的数据
char read = Serial.read();//获取蓝牙端发送的数据
switch (read) {
case 'z'://启动自动模式
flag2 = 0;
Serial.print("self-motion..#"); //发送数据到用户端
break;
case 'g'://启动关窗
flag2 = 2;
Serial.print("closeing...#");
break;
case 'k'://启动开窗
flag2 = 1;
Serial.print("opening...#");
break;
case 'l'://显示下雨量
Serial.print("rain=");
Serial.print(sensorValue);
Serial.print("#");
delay(1000);
if(flag == 1){
Serial.print("now=");
Serial.print("close#");
}else{
Serial.print("now=");
Serial.print("open#");
}
break;
}
}
/**********************************************
* 进入自动模式
************************************************/
if(flag2 == 0){
delay(1000);
if(n == HIGH && flag == 1){ //高电平,无水,开窗
Serial.print(sensorValue);
Serial.print("open windows ok!#");
digitalWrite(12, LOW);//关灯
zhengZhuan();//开窗
flag = 0;//窗处于开状态
}
if(n == LOW && flag == 0){//低电平,有水,关窗
Serial.print(sensorValue);
Serial.print("close windows ok!#");
delay(1000);
digitalWrite(12, HIGH);
fanZhuan();//关窗
flag = 1;//窗处于关闭状态
}
}
/**********************************************
* 进入开窗模式
************************************************/
if(flag2 == 1){
if(flag == 1){
delay(1000);
Serial.print(sensorValue);
Serial.print("open windows ok!#");
zhengZhuan();//开窗
flag2 = 3;//改变模式
flag =0;//将窗户的状态改变
}else{
delay(1000);
Serial.print(sensorValue);
Serial.print("open no!#");
flag2 = 3;
}
}
/**********************************************
* 进入关窗模式
************************************************/
if(flag2 == 2){
if(flag == 0){
delay(1000);
Serial.print(sensorValue);
Serial.print("close windows ok!#");
fanZhuan();//关窗
flag2 = 3;
flag = 1;
}else{
delay(1000);
Serial.print(sensorValue);
Serial.print("close no!#");
flag2 = 3;
}
}
}
/**********************************************
* 步进电机的正转函数
************************************************/
void zhengZhuan(){
for(int x = 0;x < 150;x++){//设置旋转时间
Phase_D();
delay(5);
Phase_C();
delay(5);
Phase_B();
delay(5);
Phase_A();
delay(5);
}
}
/**********************************************
* 步进电机的反转函数
************************************************/
void fanZhuan(){
for(int x = 0;x < 150;x++){ //设置旋转时间
Phase_A();
delay(5);
Phase_B();
delay(5);
Phase_C();
delay(5);
Phase_D();
delay(5);
}
}
/**********************************************
* 步进电机的四个步骤
************************************************/
void Phase_A(){
digitalWrite(A1,HIGH);
digitalWrite(B1,HIGH);
digitalWrite(C1,HIGH);
digitalWrite(D1,LOW);
}
void Phase_B(){
digitalWrite(A1,HIGH);
digitalWrite(B1,HIGH);
digitalWrite(C1,LOW);
digitalWrite(D1,HIGH);
}
void Phase_C(){
digitalWrite(A1,HIGH);
digitalWrite(B1,LOW);
digitalWrite(C1,HIGH);
digitalWrite(D1,HIGH);
}
void Phase_D(){
digitalWrite(A1,LOW);
digitalWrite(B1,HIGH);
digitalWrite(C1,HIGH);
digitalWrite(D1,HIGH);
}
9、效果图