Android实现一对一蓝牙聊天APP
学习了,三天的Android蓝牙开发,开始是一头雾水,看着别人讲的Google官方的demo感觉很容易,所有自己也尝试写一个很简单的聊天demo.可是想的很简单,自己做起来也花了,将近一天的时间才搞定这个基本的流程设计.下面是几点心得后面再贴代码
1)写一个简单的demo也好,记得一定需要有总体的流程,才开始抠代码
2)既然是demo毕竟就是新的知识,代码中间的log点一定\不能少,这是你快速调试的利器
3)还是thinkinginjava里面的那句话,思考什么是可变的,什么是不可变的,然后分开,这样来实现代码的封装,感觉很不错了.只是现在感觉还是很难想明白
4)开始思考以面向对象的流程处理问题,需要怎么弄,也是封装代码的一种思想
蓝牙聊天的基本功能:
1.实现一对一蓝牙连接
2.实现一对一聊天
很简单的功能,思路看着也很清晰,可是深入去写,才知道,水还是深度的,java不熟的话.
此处基本的如何打开蓝牙不在复述,请自行百度.
思路:
1)初始化,打开手机的蓝牙,开始蓝牙服务器线程,等待连接
2)配对,获取某台手机的蓝牙address地址.
3)开启连接线程连接手机蓝牙
4)连接成功后,开启,蓝牙聊天的线程,进行聊天的通讯.
上面四步是主要思路,其中存在着几个细节的地方,就是在开发中某些逻辑问题,线程间的安全问题,也是需要好好处理的.让我感受比较深的地方是,一对一聊天,相当于,首相每台机器都可能作为服务器在进行通讯,所以一开始开启了两个服务监听,一旦有一个接入进来,这里需要弄清楚哪个是接入对象,哪个是被接入对象,没有作为服务端的,可以把服务端线程关闭掉。
下面贴点代码
/** *客户端启动连接线程 *通过蓝牙的mac地址获取连接 *@authorAdministrator * */ privateclassConnectThreadextendsThread{ privateBluetoothDevicemDevice; privateBluetoothSocketbtSocket=null; publicConnectThread(Stringaddress){ //TODOAuto-generatedconstructorstub mDevice=mBluetoothAdapter.getRemoteDevice(address); } @Override publicvoidrun(){ //TODOAuto-generatedmethodstub connect(mDevice); } privatevoidconnect(BluetoothDevicebtDev){ MethodcreMethod; try{ creMethod=BluetoothDevice.class.getMethod("createBond"); creMethod.invoke(btDev); }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } try{ btSocket=btDev.createRfcommSocketToServiceRecord(MYUUID); System.out.println("========"+"startconnect"); Log.d("BlueToothTestActivity","开始连接..."); btSocket.connect(); mClientSocket=btSocket; isConnected=true; mHandler.sendEmptyMessage(SUCCESS_SERVICE_BEGIN_TALKING); //作为客户端关闭服务端等待的链接 if(acceptThread!=null){ acceptThread.close(); } startTalk(); }catch(IOExceptione){ //TODOAuto-generatedcatchblock System.out.println("????????????????closesocket"); close(); System.out.println(e.toString()); e.printStackTrace(); } } privatevoidclose(){ if(btSocket!=null){ try{ btSocket.close(); mHandler.sendEmptyMessage(FAILED_SERVICE_SOCRCKET); }catch(IOExceptione1){ //TODOAuto-generatedcatchblock e1.printStackTrace(); } } } }
/** *服务端的设计 *每个蓝牙的客户端先要开启服务端等待接入 *@authorAdministrator * */ privateclassAcceptThreadextendsThread{ privatefinalBluetoothServerSocketmmServerSocket; publicAcceptThread(){ //UseatemporaryobjectthatislaterassignedtommServerSocket, //becausemmServerSocketisfinal BluetoothServerSockettmp=null; try{ //MY_UUIDistheapp'sUUIDstring,alsousedbytheclient //code tmp=mBluetoothAdapter.listenUsingRfcommWithServiceRecord("Fisrt",MYUUID); }catch(IOExceptione){ mHandler.sendEmptyMessage(FAILED_SERVICE_SOCRCKET); } mmServerSocket=tmp; } publicvoidrun(){ BluetoothSocketsocket=null; //Keeplisteninguntilexceptionoccursorasocketisreturned while(isRun){ try{ socket=mmServerSocket.accept(); mHandler.sendEmptyMessage(SUCCESS_SERVICE_SOCRCKET); Log.e("TAG","==========serverstart===="); }catch(IOExceptione){ mHandler.sendEmptyMessage(FAILED_SERVICE_SOCRCKET); close(); } //Ifaconnectionwasaccepted if(socket!=null){ //服务端连接成功,启动聊天线程,通过同一个socket防止多线程赋值出现空值的问题 isConnected=true; mClientSocket=socket; mTalkThread=newTalkThread(); mTalkThread.start(); //Doworktomanagetheconnection(inaseparatethread) //多线程操作小心不安全性 synchronized(BlueConnectService.this){ //close(); } } } } publicvoidclose(){ isRun=false; try{ mmServerSocket.close(); }catch(IOExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } }
/** *设计连接成功后的聊天线程1.建立流,打通连接2.发送和接收数据3.显示数据 *需要注意的是聊天的时候,需要同一个socket建立连接才能获取对应的输入输出流 */ privateclassTalkThreadextendsThread{ privatefinalBluetoothSockettalkSocket; privatefinalInputStreammIs; privatefinalOutputStreammOs; privatebooleanisRunning=true; publicTalkThread(){ //TODOAuto-generatedconstructorstub talkSocket=mClientSocket; if(talkSocket==null){ System.out.println("=================talkThreaderro"); //return; } InputStreamis=null; OutputStreamos=null; try{ is=talkSocket.getInputStream(); os=talkSocket.getOutputStream(); }catch(IOExceptione){ //TODOAuto-generatedcatchblock try{ System.out.println("????????????????closesocket"); talkSocket.close(); CloseUtil.closeStream(is,os); }catch(IOExceptione1){ //TODOAuto-generatedcatchblock e1.printStackTrace(); } e.printStackTrace(); } mIs=is; mOs=os; } @Override publicvoidrun(){ //TODOAuto-generatedmethodstub super.run(); byte[]buffer=newbyte[1024]; intlen; while(isRunning){ try{ len=mIs.read(buffer); mHandler.obtainMessage(READ_MESSAGE,len,-1,buffer).sendToTarget(); }catch(IOExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); try{ isRunning=false; isConnected=false; System.out.println("????????????????closesocket"); talkSocket.close(); //需要重启服务器 //启动服务器 }catch(IOExceptione1){ //TODOAuto-generatedcatchblock e1.printStackTrace(); } CloseUtil.closeStream(mIs,mOs); } } } publicvoidwrite(byte[]bytes){ try{ mOs.write(bytes); mHandler.obtainMessage(WRITE_MESSAGE,bytes.length,-1,bytes).sendToTarget(); }catch(IOExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。