项目中的“蓝牙”

之前写过一篇关于蓝牙的文章,我把它称为译文,就是把官方的BluetoothChat那个程序拿过来说android中的蓝牙的操作。因为项目要用到蓝牙,所以这方面的文章看得也不少,不过果然文章都是大同小异,基本都是那个蓝牙聊天程序的照抄,然后修改一下而已。所以当我做这个项目的时候,就很头痛,因为没有多少可以参考的资料,所以一直研究那个聊天程序,现在算是,彻底弄懂了蓝牙的所有操作部分。当然我这篇文章不是想说那个程序,我是想说说我那个项目中的蓝牙操作,希望能给点不一样的蓝牙资料,供做项目的学习,也算是一种思路吧。

直接说我那个项目对蓝牙的要求。这是一个轨道磨耗检测上位机程序,和下位机通信用的蓝牙。协议部分是这样的,首先在登陆进去的activity里面建立蓝牙连接,重点和核心是在整个程序的运行中要保证连接一直存在,也许你们不懂,这么说吧,就是我这里面有很多操作的activity,拿测量这一项来说,首先是用户选择线路的这个activity,然后才是测量的10个值的显示activity,还有测量值的绘图activity,这只是测量,还有数据库查询等等。为什么说这是重点呢?想想那个蓝牙聊天程序,它其实只是在主activity那里实现通信的,当然我相信你不会提议每个activity都建立一次连接这么傻的问题。协议还没说完,建立连接只是第一步,建立连接之后,在测量activity,我们要给下位机发送开始测量的指令码,然后下位机把这段指令码回发,当接收到这段指令码,才开始发送测量数据指令,然后返回的就是数据。这里有两点,第一,上位机是一直在发送测量数据指令,(隔100ms,下位机接收和发送有延时);第二,接收到的数据要CRC校验,校验通过才能显示在界面上,错误数据要抛弃。

上面说了很多,表达能力不行,直接简单的上图说吧。

第一副图是登陆界面进去的第一个activity,蓝牙是在这里面建立连接,并一直保持,在整个程序的运行中。第二幅图是线路检测里面的第二个界面,要把下位机上的这些数据都要读出来,因为下位机是一直在测量,所以显示也是动态变化的。之前我模仿蓝牙聊天程序在第二幅图的界面做了蓝牙建立,很简单就成功了,可以和下位机通信,要求都满足,但是问题在于,每次用户换一个地点测量新数据,就要重现连接一次设备,然后才能开始测量。这么麻烦,作为成品是不能忍受的,所以也就要求:一次连接,保证不退出程序就可以一直使用蓝牙,这是这篇文章的重点。

首先在第一副图建立蓝牙连接不难做到,参考蓝牙聊天程序都可以实现。在以后的过程中都要保持连接,我把它理解为,我们在第一副图那个界面实例化的bluetoothservice的一个实例在以后的任何一个activity中都要用到,所以我用的方法是把这个实例变成“全局变量”,也就是保存在application中的变量,然后我在测量这个activity中要用到蓝牙,所以拿出这个全局变量,就保证了这个连接是一次连接,以后每个activity都是可用的。这里不深说全局变量,其实也没什么特别,也算是android数据传递的一种方法。给出部分程序:

public class MyApp extends Application {

	private String correct13 = "0";
	private String correct25 = "0";
	private String correct48 = "0";
	private String correct65 = "0";
	private BluetoothService mChatService = null;

	public String[] getcorrect(){
		String[] str = new String[5];
		str[0] = correct13;
		str[1] = correct25;
		str[3] = correct48;
		str[4] = correct65;
		return str;
	};

	public void setcorrect(String[] str){
		this.correct13 = str[0];
		this.correct25 = str[1];
		this.correct48 = str[3];
		this.correct65 = str[4];
	}

	public BluetoothService getservice(){
		return mChatService;
	}

	public void setservice(BluetoothService service){
		this.mChatService = service;
	}

}

第一副图那个activity中设置这个service,在测量那个activity中获取这个service。

MyApp app = (MyApp)getApplicationContext();
		app.setservice(mChatService);
MyApp app = (MyApp)getApplicationContext();
		mChatService = app.getservice();

接下来说的是数据传输。上面的设置成全局变量只能保证发送指令是没有问题的,但是接收读取数据,这个是有问题的。因为handler传递的数据是传到第一副图的那个activity中的,而不是测量那个activity中。但是显示却是在测量那个activity中显示,这就是问题所在,这么说应该能懂。至于为什么传递的下位机的数据是到第一个activity而不是测量那个activity,这个其实很简单,因为是在第一个activity中实例化的service,看蓝牙聊天程序就知道实例化时是要传入context和handler的,这个handler是在第一个activity中申明的,所以,只能传给第一个activity。

那能不能也用全局变量把第一个activity里面的handler的数据变成全局的呢?其实是不行的,因为这是一个动态的数据显示,就是下位机一直在发送数据,而不是发一次,handler更新了数据,但是不能更新全局变量里面的数据,所以做不到在测量activity里面获取到动态数据。

对于上面分析,其实可以明白重点就是怎么动态传递数据这个问题,何不考虑broadcastreceiver呢?是的,我用的就是广播机制,把handler的数据广播出去,接收到下位机数据就广播一次,然后在测量activity里面接收广播,然后把数据处理显示出来,思路就是这样。部分代码如下:

public void send(byte[] readBuf){

		    Intent intent = new Intent("android.intent.action.MY_BROADCAST");
		    intent.putExtra("data", readBuf);
		    sendBroadcast(intent);
		    Log.i("chz", "发了");

		}

这是发送广播。

//广播
  	 public class myReceiver extends BroadcastReceiver{

		public void onReceive(Context context, Intent intent) {

			readBuf = intent.getByteArrayExtra("data");
			Log.i("chz", "收到了");
			String kaishicl = new String(bytesHexTobytes(readBuf));
			if(kaishicl.equals("01060001FFFFD9BA000000000000000000000000000000")){
			            	mHander.post(mRunnable);
			}else{
			//construct a string from the valid bytes in the buffer
			 byte[] newbytes = new byte[readBuf.length - 2];//获取不含校验位的字节数组
			 System.arraycopy(readBuf, 0, newbytes, 0, readBuf.length - 2);
			 String read = new String(bytesHexTobytes(newbytes));
			 String checkMessage = CRC16M.getBufHexStr(CRC16M.getSendBuf(read));//得到生成的校验后字符串
			 String readMessage = new String(bytesHexTobytes(readBuf));

			 if(checkMessage.equals(readMessage)){//比较两个字符串是否相等

			String guangliangdaichoice = guangliangdai.getSelectedItem().toString();
			if(guangliangdaichoice.equals("光亮带位置(mm)")){
			      //光亮带位置
			     String guangliangdaiweizhiets = showlight(readBuf[17],readBuf[18]);
			     guangliangdaiet.setText(guangliangdaiweizhiets);
			}else{
			      //光亮带宽度
			     Cursor cursor = sqlitedb.rawQuery("select * from data", null);
			     int id = 1;
			     while(cursor.moveToNext()){
			     id++;
			    };
			    Cursor cur = sqlitedb.rawQuery("select * from data where id = " + Integer.toString(id-1), null);
			    String temp = "";
			    while(cur.moveToNext()){
			    	   temp += cur.getString(13);
			    }

			    String value = showlight(readBuf[17],readBuf[18]);
			    double former = Double.parseDouble(temp);
			    double laster = Double.parseDouble(value);
			    String guangliangdaikuanduets = String.valueOf((double)(Math.round((laster - former)*100)/100.0));
			    guangliangdaiet.setText(guangliangdaikuanduets);
			    }
			    display(readBuf);
			    }else{
			         Log.i("chz","校验错误!");
			    }
	         	}

		}
  	 }

这是广播的操作,还好这个操作不是耗时的,所以无所谓。

	IntentFilter filter = new IntentFilter();
        filter.addAction("android.intent.action.MY_BROADCAST");
        this.registerReceiver(myreceiver, filter);

这个添加一个过滤器获取确定的广播。

嗯,其实我这里只是提供一个思路来解决遇到的问题,相信大家也会有自己的方法和思路。

项目中的“蓝牙”

时间: 2024-08-04 17:40:08

项目中的“蓝牙”的相关文章

用java写一个远程视频监控系统,实时监控(类似直播)我想用RPT协议,不知道怎么把RPT协议集成到项目中

我最近在用java写一个远程视频监控系统,实时监控(类似直播)我想用RPT协议,不知道怎么把RPT协议集成到项目中,第一次写项目,写过这类项目的多多提意见,哪方面的意见都行,有代码或者demo的求赏给我,谢谢

DotNet项目中的一些常用验证操作

在项目中需要对用户输入的信息,以及一些方法生成的结果进行验证,一般在项目中较多的采用js插件或js来进行有关信息的校验,但是从项目安全性的角度进行考虑,可对系统进行js注入. 如果在后台对用户输入的信息进行验证会相对的安全,在出现信息验证不合法时,可以直接在程序中抛出异常,终止程序的运行. 现在提供几种较为常用的验证方法,可以减少在项目中开发时间和错误性: 1.判断域名:         /// <summary>         /// 普通的域名         /// </summ

javaWeb项目中如何实现在线查看pdf文件

最近有需求要实现在网页直接查看pdf,word,excel文件.但是实际当中并没有很好的开源插件供我们使用,确实有一些付费的插件不错,也很好用,但是对于我来说都不适合. 现在只是单纯的找到了围魏救赵的方法. 就是先实现显示pdf文件,其他文件用别的方式去转成pdf.虽然这个方法确实不好,但是也是没有办法的办法了,如果以后能有更好的,那就再发布别的吧. 这里我就直接介绍pdf的显示方法. 直接上干货. 首先在E:\tomcat8\webapps这个目录下面拷贝下面这个文件 http://yunpa

Python+Selenium进行UI自动化测试项目中,常用的小技巧2:读取配置文件(configparser,.ini文件)

在自动化测试项目中,可能会碰到一些经常使用的但 很少变化的配置信息,下面就来介绍使用configparser来读取配置信息config.ini 读取的信息(config.ini)如下: [config]platformName=AndroidappPackage=com.sheinsideappActivity=.module.GuideActivitybaseUrl=http://0.0.0.0:4723/wd/hubfindElementTimes=10[cmd]openAppium=nod

团队项目中个人的定位及计划

我们团队在这一次的移动APP开发计划中准备做一个针对上海地区大学分数线进行专业推荐的APP,根据前几章的学习,团队中的成员将会被初步分为开发人员.测试人员以及PM(program manager).我在这次的软件开发中担任开发人员的职务. 在开发开始的阶段,全员首先一起明确这次APP的主题,一起分析好这款APP将要实现怎样的功能,将要面向哪些受众:对于市面上的同类软件,我们还能添加哪些实用的功能.首先将会尽可能地将上海地区内高校近几年的分数线.每个系的最低录取分数统计好录入系统中,再根据考生相应

160504项目中的error

在学习时,曾经遇到将同组的项目导入时出现红叉的情况.但是没有发现具体错误.开始以为是build path 的问题,于是在Libraries中将相关Jar包重新检查并添加了一遍,但并没有解决问题.后来仔细检查后才发现,是一个很简单的问题,之前都想复杂了.JDK版本不一样,把JDK7换掉重新装JDK8,再把相关配置好,红叉就解决大半. 作为菜鸟程序员,有时候一个很小的问题就能造成很大影响.而经验不足时,更不知道从何入手.为了能顺利编写项目,更为了能在编写项目时能解决出现的问题和错误而不是不知所措,就

准备在新项目中使用pgsql

pgsql大象数据库 是我最近在关注的一款开源数据库,可以自由修改,没那么多限制,准备在新项目中使用 http://blog.163.com/[email protected]/blog/static/16387704020141229159715/

Android 百度地图开发(一)--- 申请API Key和在项目中显示百度地图

标签: Android百度地图API Key  分类: Android 百度地图开发(2)  最近自己想研究下地图,本来想研究google Map,但是申请API key比较坑爹,于是从百度地图入手,其实他们的用法都差不多,本篇文章就带领大家在自己的Android项目中加入百度地图的功能,接下来我会写一系列关于百度地图的文章,欢迎大家到时候关注!   一 申请API key 在使用百度地图之前,我们必须去申请一个百度地图的API key,申请地址http://lbsyun.baidu.com/a

设置tableview的滚动范围--iOS开发系列---项目中成长的知识三

设置tableview的滚动范围 有时候tableview的footerview上的内容需要向上拖动界面一定距离才能够看见, 项目中因为我需要在footerviw上添加一个按钮,而这个按钮又因为这个原因点不中,所以找到了解决办法! 添加如下方法即可 -(void)scrollViewDidScroll:(UIScrollView *)scrollView { self.tableView.contentSize = CGSizeMake(0,MZT_SCREEN_HEIGHT); }