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();
}
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。