Android 蓝牙开发实例--蓝牙聊天程序的设计和实现 Android 蓝牙开发实例--蓝牙聊天程序的设计和实现
转自:http://blog.csdn.net/dlutbrucezhang/article/details/8963696
作者在这里介绍的这个实例是Google SDK中提供的一个蓝牙聊天程序,简单但信息量巨大,非常适合初学者学习蓝牙方面的知识。
在学习这个实例前请读者仔细阅读并理解Socket的工作原理和实现机制,作者的这篇博客中有详细的介绍:
http://blog.csdn.net/dlutbrucezhang/article/details/8577810
在Android1.x的时候,相关API非常不完善,还不能简单的使用Bluetooth开发,有一个开源项目可以帮助程序员使用、开发蓝牙,支持直接方法bluetooth协议栈。在Android2以后,框架提供了一些官方API来进行蓝牙的通信,但目前的程序也比较不完善。本文主要讨论Android2后的Bluetooth通信的API使用方法。
首先看聊天室的效果图:
蓝牙设备连接的过程如下图所示:
下面这张图展示的是蓝牙聊天的时序图:
接下来将贴出源码并对源码做出详细的解释说明:
BluetoothChat.java
例程的主Activity。onCreate()得到本地BluetoothAdapter设备,检查是否支持。onStart()中检查是否启用蓝牙,并请求启用,然后执行setupChat()。setupChat()中先对界面中的控件进行初始化增加点击监听器等,然创建BluetoothChatService对象,该对象在整个应用过程中存在,并执行蓝牙连接建立、消息发送接受等实际的行为。
- importandroid.app.Activity;
- importandroid.bluetooth.BluetoothAdapter;
- importandroid.bluetooth.BluetoothDevice;
- importandroid.content.Intent;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.util.Log;
- importandroid.view.KeyEvent;
- importandroid.view.Menu;
- importandroid.view.MenuInflater;
- importandroid.view.MenuItem;
- importandroid.view.View;
- importandroid.view.Window;
- importandroid.view.View.OnClickListener;
- importandroid.view.inputmethod.EditorInfo;
- importandroid.widget.ArrayAdapter;
- importandroid.widget.Button;
- importandroid.widget.EditText;
- importandroid.widget.ListView;
- importandroid.widget.TextView;
- importandroid.widget.Toast;
- /**
- *ThisisthemainActivitythatdisplaysthecurrentchatsession.
- */
- publicclassBluetoothChatextendsActivity{
- //Debugging
- privatestaticfinalStringTAG="BluetoothChat";
- privatestaticfinalbooleanD=true;
- //MessagetypessentfromtheBluetoothChatServiceHandler
- publicstaticfinalintMESSAGE_STATE_CHANGE=1;
- publicstaticfinalintMESSAGE_READ=2;
- publicstaticfinalintMESSAGE_WRITE=3;
- publicstaticfinalintMESSAGE_DEVICE_NAME=4;
- publicstaticfinalintMESSAGE_TOAST=5;
- //KeynamesreceivedfromtheBluetoothChatServiceHandler
- publicstaticfinalStringDEVICE_NAME="device_name";
- publicstaticfinalStringTOAST="toast";
- //Intentrequestcodes
- privatestaticfinalintREQUEST_CONNECT_DEVICE=1;
- privatestaticfinalintREQUEST_ENABLE_BT=2;
- //LayoutViews
- privateTextViewmTitle;
- privateListViewmConversationView;
- privateEditTextmOutEditText;
- privateButtonmSendButton;
- //Nameoftheconnecteddevice
- privateStringmConnectedDeviceName=null;
- //Arrayadapterfortheconversationthread
- privateArrayAdapter<String>mConversationArrayAdapter;
- //Stringbufferforoutgoingmessages
- privateStringBuffermOutStringBuffer;
- //LocalBluetoothadapter
- privateBluetoothAdaptermBluetoothAdapter=null;
- //Memberobjectforthechatservices
- privateBluetoothChatServicemChatService=null;
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- if(D)Log.e(TAG,"+++ONCREATE+++");
- //Setupthewindowlayout
- requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
- setContentView(R.layout.main);
- getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.custom_title);
- //Setupthecustomtitle
- mTitle=(TextView)findViewById(R.id.title_left_text);
- mTitle.setText(R.string.app_name);
- mTitle=(TextView)findViewById(R.id.title_right_text);
- //GetlocalBluetoothadapter
- mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
- //Iftheadapterisnull,thenBluetoothisnotsupported
- if(mBluetoothAdapter==null){
- Toast.makeText(this,"Bluetoothisnotavailable",Toast.LENGTH_LONG).show();
- finish();
- return;
- }
- }
- @Override
- publicvoidonStart(){
- super.onStart();
- if(D)Log.e(TAG,"++ONSTART++");
- //IfBTisnoton,requestthatitbeenabled.
- //setupChat()willthenbecalledduringonActivityResult
- if(!mBluetoothAdapter.isEnabled()){
- IntentenableIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
- startActivityForResult(enableIntent,REQUEST_ENABLE_BT);
- //Otherwise,setupthechatsession
- }else{
- if(mChatService==null)setupChat();
- }
- }
- @Override
- publicsynchronizedvoidonResume(){
- super.onResume();
- if(D)Log.e(TAG,"+ONRESUME+");
- //PerformingthischeckinonResume()coversthecaseinwhichBTwas
- //notenabledduringonStart(),sowewerepausedtoenableit...
- //onResume()willbecalledwhenACTION_REQUEST_ENABLEactivityreturns.
- if(mChatService!=null){
- //OnlyifthestateisSTATE_NONE,doweknowthatwehaven'tstartedalready
- if(mChatService.getState()==BluetoothChatService.STATE_NONE){
- //StarttheBluetoothchatservices
- mChatService.start();
- }
- }
- }
- privatevoidsetupChat(){
- Log.d(TAG,"setupChat()");
- //Initializethearrayadapterfortheconversationthread
- mConversationArrayAdapter=newArrayAdapter<String>(this,R.layout.message);
- mConversationView=(ListView)findViewById(R.id.in);
- mConversationView.setAdapter(mConversationArrayAdapter);
- //Initializethecomposefieldwithalistenerforthereturnkey
- mOutEditText=(EditText)findViewById(R.id.edit_text_out);
- mOutEditText.setOnEditorActionListener(mWriteListener);
- //Initializethesendbuttonwithalistenerthatforclickevents
- mSendButton=(Button)findViewById(R.id.button_send);
- mSendButton.setOnClickListener(newOnClickListener(){
- publicvoidonClick(Viewv){
- //Sendamessageusingcontentoftheedittextwidget
- TextViewview=(TextView)findViewById(R.id.edit_text_out);
- Stringmessage=view.getText().toString();
- sendMessage(message);
- }
- });
- //InitializetheBluetoothChatServicetoperformbluetoothconnections
- mChatService=newBluetoothChatService(this,mHandler);
- //Initializethebufferforoutgoingmessages
- mOutStringBuffer=newStringBuffer("");
- }
- @Override
- publicsynchronizedvoidonPause(){
- super.onPause();
- if(D)Log.e(TAG,"-ONPAUSE-");
- }
- @Override
- publicvoidonStop(){
- super.onStop();
- if(D)Log.e(TAG,"--ONSTOP--");
- }
- @Override
- publicvoidonDestroy(){
- super.onDestroy();
- //StoptheBluetoothchatservices
- if(mChatService!=null)mChatService.stop();
- if(D)Log.e(TAG,"---ONDESTROY---");
- }
- privatevoidensureDiscoverable(){
- if(D)Log.d(TAG,"ensurediscoverable");
- if(mBluetoothAdapter.getScanMode()!=
- BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){
- IntentdiscoverableIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
- discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);
- startActivity(discoverableIntent);
- }
- }
- /**
- *Sendsamessage.
- *@parammessageAstringoftexttosend.
- */
- privatevoidsendMessage(Stringmessage){
- //Checkthatwe'reactuallyconnectedbeforetryinganything
- if(mChatService.getState()!=BluetoothChatService.STATE_CONNECTED){
- Toast.makeText(this,R.string.not_connected,Toast.LENGTH_SHORT).show();
- return;
- }
- //Checkthatthere'sactuallysomethingtosend
- if(message.length()>0){
- //GetthemessagebytesandtelltheBluetoothChatServicetowrite
- byte[]send=message.getBytes();
- mChatService.write(send);
- //Resetoutstringbuffertozeroandcleartheedittextfield
- mOutStringBuffer.setLength(0);
- mOutEditText.setText(mOutStringBuffer);
- }
- }
- //TheactionlistenerfortheEditTextwidget,tolistenforthereturnkey
- privateTextView.OnEditorActionListenermWriteListener=
- newTextView.OnEditorActionListener(){
- publicbooleanonEditorAction(TextViewview,intactionId,KeyEventevent){
- //Iftheactionisakey-upeventonthereturnkey,sendthemessage
- if(actionId==EditorInfo.IME_NULL&&event.getAction()==KeyEvent.ACTION_UP){
- Stringmessage=view.getText().toString();
- sendMessage(message);
- }
- if(D)Log.i(TAG,"ENDonEditorAction");
- returntrue;
- }
- };
- //TheHandlerthatgetsinformationbackfromtheBluetoothChatService
- privatefinalHandlermHandler=newHandler(){
- @Override
- publicvoidhandleMessage(Messagemsg){
- switch(msg.what){
- caseMESSAGE_STATE_CHANGE:
- if(D)Log.i(TAG,"MESSAGE_STATE_CHANGE:"+msg.arg1);
- switch(msg.arg1){
- caseBluetoothChatService.STATE_CONNECTED:
- mTitle.setText(R.string.title_connected_to);
- mTitle.append(mConnectedDeviceName);
- mConversationArrayAdapter.clear();
- break;
- caseBluetoothChatService.STATE_CONNECTING:
- mTitle.setText(R.string.title_connecting);
- break;
- caseBluetoothChatService.STATE_LISTEN:
- caseBluetoothChatService.STATE_NONE:
- mTitle.setText(R.string.title_not_connected);
- break;
- }
- break;
- caseMESSAGE_WRITE:
- byte[]writeBuf=(byte[])msg.obj;
- //constructastringfromthebuffer
- StringwriteMessage=newString(writeBuf);
- mConversationArrayAdapter.add("Me:"+writeMessage);
- break;
- caseMESSAGE_READ:
- byte[]readBuf=(byte[])msg.obj;
- //constructastringfromthevalidbytesinthebuffer
- StringreadMessage=newString(readBuf,0,msg.arg1);
- mConversationArrayAdapter.add(mConnectedDeviceName+":"+readMessage);
- break;
- caseMESSAGE_DEVICE_NAME:
- //savetheconnecteddevice'sname
- mConnectedDeviceName=msg.getData().getString(DEVICE_NAME);
- Toast.makeText(getApplicationContext(),"Connectedto"
- +mConnectedDeviceName,Toast.LENGTH_SHORT).show();
- break;
- caseMESSAGE_TOAST:
- Toast.makeText(getApplicationContext(),msg.getData().getString(TOAST),
- Toast.LENGTH_SHORT).show();
- break;
- }
- }
- };
- publicvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
- if(D)Log.d(TAG,"onActivityResult"+resultCode);
- switch(requestCode){
- caseREQUEST_CONNECT_DEVICE:
- //WhenDeviceListActivityreturnswithadevicetoconnect
- if(resultCode==Activity.RESULT_OK){
- //GetthedeviceMACaddress
- Stringaddress=data.getExtras()
- .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
- //GettheBLuetoothDeviceobject
- BluetoothDevicedevice=mBluetoothAdapter.getRemoteDevice(address);
- //Attempttoconnecttothedevice
- mChatService.connect(device);
- }
- break;
- caseREQUEST_ENABLE_BT:
- //WhentherequesttoenableBluetoothreturns
- if(resultCode==Activity.RESULT_OK){
- //Bluetoothisnowenabled,sosetupachatsession
- setupChat();
- }else{
- //UserdidnotenableBluetoothoranerroroccured
- Log.d(TAG,"BTnotenabled");
- Toast.makeText(this,R.string.bt_not_enabled_leaving,Toast.LENGTH_SHORT).show();
- finish();
- }
- }
- }
- @Override
- publicbooleanonCreateOptionsMenu(Menumenu){
- MenuInflaterinflater=getMenuInflater();
- inflater.inflate(R.menu.option_menu,menu);
- returntrue;
- }
- @Override
- publicbooleanonOptionsItemSelected(MenuItemitem){
- switch(item.getItemId()){
- caseR.id.scan:
- //LaunchtheDeviceListActivitytoseedevicesanddoscan
- IntentserverIntent=newIntent(this,DeviceListActivity.class);
- startActivityForResult(serverIntent,REQUEST_CONNECT_DEVICE);
- returntrue;
- caseR.id.discoverable:
- //Ensurethisdeviceisdiscoverablebyothers
- ensureDiscoverable();
- returntrue;
- }
- returnfalse;
- }
- }
BluetoothChatService.java
public synchronized void start():
开启mAcceptThread线程,由于样例程序是仅2人的聊天过程,故之前先检测mConnectThread和mConnectedThread是否运行,运行则先退出这些线程。
public synchronized voidconnect(BluetoothDevice device):
取消CONNECTING和CONNECTED状态下的相关线程,然后运行新的mConnectThread线程。
public synchronized voidconnected(BluetoothSocket socket, BluetoothDevice device):
开启一个ConnectedThread来管理对应的当前连接。之前先取消任意现存的mConnectThread、mConnectedThread、mAcceptThread线程,然后开启新mConnectedThread,传入当前刚刚接受的socket连接。最后通过Handler来通知UI连接OK。
public synchronized void stop():
停止所有相关线程,设当前状态为NONE。
public void write(byte[] out):
在STATE_CONNECTED状态下,调用mConnectedThread里的write方法,写入byte。
private void connectionFailed():
连接失败的时候处理,通知ui,并设为STATE_LISTEN状态。
private void connectionLost():
当连接失去的时候,设为STATE_LISTEN状态并通知ui。
内部类:
private class AcceptThread extendsThread:
创建监听线程,准备接受新连接。使用阻塞方式,调用BluetoothServerSocket.accept()。提供cancel方法关闭socket。
private class ConnectThread extendsThread:
这是定义的连接线程,专门用来对外发出连接对方蓝牙的请求和处理流程。构造函数里通过BluetoothDevice.createRfcommSocketToServiceRecord(),从待连接的device产生BluetoothSocket.然后在run方法中connect,成功后调用BluetoothChatSevice的connected()方法。定义cancel()在关闭线程时能够关闭相关socket。
private class ConnectedThread extendsThread:
这个是双方蓝牙连接后一直运行的线程。构造函数中设置输入输出流。Run方法中使用阻塞模式的InputStream.read()循环读取输入流,然后post到UI线程中更新聊天消息。也提供了write()将聊天消息写入输出流传输至对方,传输成功后回写入UI线程。最后cancel()关闭连接的socket。
- importjava.io.IOException;
- importjava.io.InputStream;
- importjava.io.OutputStream;
- importjava.util.UUID;
- importandroid.annotation.SuppressLint;
- importandroid.bluetooth.BluetoothAdapter;
- importandroid.bluetooth.BluetoothDevice;
- importandroid.bluetooth.BluetoothServerSocket;
- importandroid.bluetooth.BluetoothSocket;
- importandroid.content.Context;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.util.Log;
- /**
- *ThisclassdoesalltheworkforsettingupandmanagingBluetooth
- *connectionswithotherdevices.Ithasathreadthatlistensfor
- *incomingconnections,athreadforconnectingwithadevice,anda
- *threadforperformingdatatransmissionswhenconnected.
- */
- @SuppressLint("NewApi")
- publicclassBluetoothChatService{
- //Debugging
- privatestaticfinalStringTAG="BluetoothChatService";
- privatestaticfinalbooleanD=true;
- //NamefortheSDPrecordwhencreatingserversocket
- privatestaticfinalStringNAME="BluetoothChat";
- //UniqueUUIDforthisapplication
- privatestaticfinalUUIDMY_UUID=UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
- //Memberfields
- privatefinalBluetoothAdaptermAdapter;
- privatefinalHandlermHandler;
- privateAcceptThreadmAcceptThread;
- privateConnectThreadmConnectThread;
- privateConnectedThreadmConnectedThread;
- privateintmState;
- //Constantsthatindicatethecurrentconnectionstate
- publicstaticfinalintSTATE_NONE=0;//we'redoingnothing
- publicstaticfinalintSTATE_LISTEN=1;//nowlisteningforincomingconnections
- publicstaticfinalintSTATE_CONNECTING=2;//nowinitiatinganoutgoingconnection
- publicstaticfinalintSTATE_CONNECTED=3;//nowconnectedtoaremotedevice
- /**
- *Constructor.PreparesanewBluetoothChatsession.
- *@paramcontextTheUIActivityContext
- *@paramhandlerAHandlertosendmessagesbacktotheUIActivity
- */
- publicBluetoothChatService(Contextcontext,Handlerhandler){
- mAdapter=BluetoothAdapter.getDefaultAdapter();
- mState=STATE_NONE;
- mHandler=handler;
- }
- /**
- *Setthecurrentstateofthechatconnection
- *@paramstateAnintegerdefiningthecurrentconnectionstate
- */
- privatesynchronizedvoidsetState(intstate){
- if(D)Log.d(TAG,"setState()"+mState+"->"+state);
- mState=state;
- //GivethenewstatetotheHandlersotheUIActivitycanupdate
- mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE,state,-1).sendToTarget();
- }
- /**
- *Returnthecurrentconnectionstate.*/
- publicsynchronizedintgetState(){
- returnmState;
- }
- /**
- *Startthechatservice.SpecificallystartAcceptThreadtobegina
- *sessioninlistening(server)mode.CalledbytheActivityonResume()*/
- publicsynchronizedvoidstart(){
- if(D)Log.d(TAG,"start");
- //Cancelanythreadattemptingtomakeaconnection
- if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}
- //Cancelanythreadcurrentlyrunningaconnection
- if(mConnectedThread!=null){mConnectedThread.cancel();mConnectedThread=null;}
- //StartthethreadtolistenonaBluetoothServerSocket
- if(mAcceptThread==null){
- mAcceptThread=newAcceptThread();
- mAcceptThread.start();
- }
- setState(STATE_LISTEN);
- }
- /**
- *StarttheConnectThreadtoinitiateaconnectiontoaremotedevice.
- *@paramdeviceTheBluetoothDevicetoconnect
- */
- publicsynchronizedvoidconnect(BluetoothDevicedevice){
- if(D)Log.d(TAG,"connectto:"+device);
- //Cancelanythreadattemptingtomakeaconnection
- if(mState==STATE_CONNECTING){
- if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}
- }
- //Cancelanythreadcurrentlyrunningaconnection
- if(mConnectedThread!=null){mConnectedThread.cancel();mConnectedThread=null;}
- //Startthethreadtoconnectwiththegivendevice
- mConnectThread=newConnectThread(device);
- mConnectThread.start();
- setState(STATE_CONNECTING);
- }
- /**
- *StarttheConnectedThreadtobeginmanagingaBluetoothconnection
- *@paramsocketTheBluetoothSocketonwhichtheconnectionwasmade
- *@paramdeviceTheBluetoothDevicethathasbeenconnected
- */
- publicsynchronizedvoidconnected(BluetoothSocketsocket,BluetoothDevicedevice){
- if(D)Log.d(TAG,"connected");
- //Cancelthethreadthatcompletedtheconnection
- if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}
- //Cancelanythreadcurrentlyrunningaconnection
- if(mConnectedThread!=null){mConnectedThread.cancel();mConnectedThread=null;}
- //Canceltheacceptthreadbecauseweonlywanttoconnecttoonedevice
- if(mAcceptThread!=null){mAcceptThread.cancel();mAcceptThread=null;}
- //Startthethreadtomanagetheconnectionandperformtransmissions
- mConnectedThread=newConnectedThread(socket);
- mConnectedThread.start();
- //SendthenameoftheconnecteddevicebacktotheUIActivity
- Messagemsg=mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME);
- Bundlebundle=newBundle();
- bundle.putString(BluetoothChat.DEVICE_NAME,device.getName());
- msg.setData(bundle);
- mHandler.sendMessage(msg);
- setState(STATE_CONNECTED);
- }
- /**
- *Stopallthreads
- */
- publicsynchronizedvoidstop(){
- if(D)Log.d(TAG,"stop");
- if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}
- if(mConnectedThread!=null){mConnectedThread.cancel();mConnectedThread=null;}
- if(mAcceptThread!=null){mAcceptThread.cancel();mAcceptThread=null;}
- setState(STATE_NONE);
- }
- /**
- *WritetotheConnectedThreadinanunsynchronizedmanner
- *@paramoutThebytestowrite
- *@seeConnectedThread#write(byte[])
- */
- publicvoidwrite(byte[]out){
- //Createtemporaryobject
- ConnectedThreadr;
- //SynchronizeacopyoftheConnectedThread
- synchronized(this){
- if(mState!=STATE_CONNECTED)return;
- r=mConnectedThread;
- }
- //Performthewriteunsynchronized
- r.write(out);
- }
- /**
- *IndicatethattheconnectionattemptfailedandnotifytheUIActivity.
- */
- privatevoidconnectionFailed(){
- setState(STATE_LISTEN);
- //SendafailuremessagebacktotheActivity
- Messagemsg=mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
- Bundlebundle=newBundle();
- bundle.putString(BluetoothChat.TOAST,"Unabletoconnectdevice");
- msg.setData(bundle);
- mHandler.sendMessage(msg);
- }
- /**
- *IndicatethattheconnectionwaslostandnotifytheUIActivity.
- */
- privatevoidconnectionLost(){
- setState(STATE_LISTEN);
- //SendafailuremessagebacktotheActivity
- Messagemsg=mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
- Bundlebundle=newBundle();
- bundle.putString(BluetoothChat.TOAST,"Deviceconnectionwaslost");
- msg.setData(bundle);
- mHandler.sendMessage(msg);
- }
- /**
- *Thisthreadrunswhilelisteningforincomingconnections.Itbehaves
- *likeaserver-sideclient.Itrunsuntilaconnectionisaccepted
- *(oruntilcancelled).
- */
- @SuppressLint("NewApi")
- privateclassAcceptThreadextendsThread{
- //Thelocalserversocket
- privatefinalBluetoothServerSocketmmServerSocket;
- publicAcceptThread(){
- BluetoothServerSockettmp=null;
- //Createanewlisteningserversocket
- try{
- //开启监听
- tmp=mAdapter.listenUsingRfcommWithServiceRecord(NAME,MY_UUID);
- }catch(IOExceptione){
- Log.e(TAG,"listen()failed",e);
- }
- mmServerSocket=tmp;
- }
- publicvoidrun(){
- if(D)Log.d(TAG,"BEGINmAcceptThread"+this);
- setName("AcceptThread");
- BluetoothSocketsocket=null;
- //Listentotheserversocketifwe'renotconnected
- while(mState!=STATE_CONNECTED){
- try{
- //Thisisablockingcallandwillonlyreturnona
- //successfulconnectionoranexception
- socket=mmServerSocket.accept();
- }catch(IOExceptione){
- Log.e(TAG,"accept()failed",e);
- break;
- }
- //Ifaconnectionwasaccepted
- if(socket!=null){
- synchronized(BluetoothChatService.this){
- switch(mState){
- caseSTATE_LISTEN:
- caseSTATE_CONNECTING:
- //Situationnormal.Starttheconnectedthread.
- connected(socket,socket.getRemoteDevice());
- break;
- caseSTATE_NONE:
- caseSTATE_CONNECTED:
- //Eithernotreadyoralreadyconnected.Terminatenewsocket.
- try{
- socket.close();
- }catch(IOExceptione){
- Log.e(TAG,"Couldnotcloseunwantedsocket",e);
- }
- break;
- }
- }
- }
- }
- if(D)Log.i(TAG,"ENDmAcceptThread");
- }
- publicvoidcancel(){
- if(D)Log.d(TAG,"cancel"+this);
- try{
- mmServerSocket.close();
- }catch(IOExceptione){
- Log.e(TAG,"close()ofserverfailed",e);
- }
- }
- }
- /**
- *Thisthreadrunswhileattemptingtomakeanoutgoingconnection
- *withadevice.Itrunsstraightthrough;theconnectioneither
- *succeedsorfails.
- */
- privateclassConnectThreadextendsThread{
- privatefinalBluetoothSocketmmSocket;
- privatefinalBluetoothDevicemmDevice;
- publicConnectThread(BluetoothDevicedevice){
- mmDevice=device;
- BluetoothSockettmp=null;
- //GetaBluetoothSocketforaconnectionwiththe
- //givenBluetoothDevice
- try{
- tmp=device.createRfcommSocketToServiceRecord(MY_UUID);
- }catch(IOExceptione){
- Log.e(TAG,"create()failed",e);
- }
- mmSocket=tmp;
- }
- publicvoidrun(){
- Log.i(TAG,"BEGINmConnectThread");
- setName("ConnectThread");
- //Alwayscanceldiscoverybecauseitwillslowdownaconnection
- mAdapter.cancelDiscovery();
- //MakeaconnectiontotheBluetoothSocket
- try{
- //Thisisablockingcallandwillonlyreturnona
- //successfulconnectionoranexception
- mmSocket.connect();
- }catch(IOExceptione){
- connectionFailed();
- //Closethesocket
- try{
- mmSocket.close();
- }catch(IOExceptione2){
- Log.e(TAG,"unabletoclose()socketduringconnectionfailure",e2);
- }
- //Starttheserviceovertorestartlisteningmode
- BluetoothChatService.this.start();
- return;
- }
- //ResettheConnectThreadbecausewe'redone
- synchronized(BluetoothChatService.this){
- mConnectThread=null;
- }
- //Starttheconnectedthread
- connected(mmSocket,mmDevice);
- }
- publicvoidcancel(){
- try{
- mmSocket.close();
- }catch(IOExceptione){
- Log.e(TAG,"close()ofconnectsocketfailed",e);
- }
- }
- }
- /**
- *Thisthreadrunsduringaconnectionwitharemotedevice.
- *Ithandlesallincomingandoutgoingtransmissions.
- */
- privateclassConnectedThreadextendsThread{
- privatefinalBluetoothSocketmmSocket;
- privatefinalInputStreammmInStream;
- privatefinalOutputStreammmOutStream;
- publicConnectedThread(BluetoothSocketsocket){
- Log.d(TAG,"createConnectedThread");
- mmSocket=socket;
- InputStreamtmpIn=null;
- OutputStreamtmpOut=null;
- //GettheBluetoothSocketinputandoutputstreams
- try{
- tmpIn=socket.getInputStream();
- tmpOut=socket.getOutputStream();
- }catch(IOExceptione){
- Log.e(TAG,"tempsocketsnotcreated",e);
- }
- mmInStream=tmpIn;
- mmOutStream=tmpOut;
- }
- publicvoidrun(){
- Log.i(TAG,"BEGINmConnectedThread");
- byte[]buffer=newbyte[1024];
- intbytes;
- //KeeplisteningtotheInputStreamwhileconnected
- while(true){
- try{
- //ReadfromtheInputStream
- bytes=mmInStream.read(buffer);
- //SendtheobtainedbytestotheUIActivity
- mHandler.obtainMessage(BluetoothChat.MESSAGE_READ,bytes,-1,buffer)
- .sendToTarget();
- }catch(IOExceptione){
- Log.e(TAG,"disconnected",e);
- connectionLost();
- break;
- }
- }
- }
- /**
- *WritetotheconnectedOutStream.
- *@parambufferThebytestowrite
- */
- publicvoidwrite(byte[]buffer){
- try{
- mmOutStream.write(buffer);
- //SharethesentmessagebacktotheUIActivity
- mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE,-1,-1,buffer)
- .sendToTarget();
- }catch(IOExceptione){
- Log.e(TAG,"Exceptionduringwrite",e);
- }
- }
- publicvoidcancel(){
- try{
- mmSocket.close();
- }catch(IOExceptione){
- Log.e(TAG,"close()ofconnectsocketfailed",e);
- }
- }
- }
- }
DeviceListActivity.java
该类包含UI和操作的Activity类,作用是得到系统默认蓝牙设备的已配对设备列表,以及搜索出的未配对的新设备的列表。然后提供点击后发出连接设备请求的功能。
- importjava.util.Set;
- importandroid.annotation.SuppressLint;
- importandroid.app.Activity;
- importandroid.bluetooth.BluetoothAdapter;
- importandroid.bluetooth.BluetoothDevice;
- importandroid.content.BroadcastReceiver;
- importandroid.content.Context;
- importandroid.content.Intent;
- importandroid.content.IntentFilter;
- importandroid.os.Bundle;
- importandroid.util.Log;
- importandroid.view.View;
- importandroid.view.Window;
- importandroid.view.View.OnClickListener;
- importandroid.widget.AdapterView;
- importandroid.widget.ArrayAdapter;
- importandroid.widget.Button;
- importandroid.widget.ListView;
- importandroid.widget.TextView;
- importandroid.widget.AdapterView.OnItemClickListener;
- /**
- *ThisActivityappearsasadialog.Itlistsanypaireddevicesand
- *devicesdetectedintheareaafterdiscovery.Whenadeviceischosen
- *bytheuser,theMACaddressofthedeviceissentbacktotheparent
- *ActivityintheresultIntent.
- */
- @SuppressLint("NewApi")
- publicclassDeviceListActivityextendsActivity{
- //Debugging
- privatestaticfinalStringTAG="DeviceListActivity";
- privatestaticfinalbooleanD=true;
- //ReturnIntentextra
- publicstaticStringEXTRA_DEVICE_ADDRESS="device_address";
- //Memberfields
- privateBluetoothAdaptermBtAdapter;
- privateArrayAdapter<String>mPairedDevicesArrayAdapter;
- privateArrayAdapter<String>mNewDevicesArrayAdapter;
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- //Setupthewindow
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
- setContentView(R.layout.device_list);
- //SetresultCANCELEDincasetheuserbacksout
- setResult(Activity.RESULT_CANCELED);
- //Initializethebuttontoperformdevicediscovery
- ButtonscanButton=(Button)findViewById(R.id.button_scan);
- scanButton.setOnClickListener(newOnClickListener(){
- publicvoidonClick(Viewv){
- doDiscovery();
- v.setVisibility(View.GONE);
- }
- });
- //Initializearrayadapters.Oneforalreadypaireddevicesand
- //onefornewlydiscovereddevices
- mPairedDevicesArrayAdapter=newArrayAdapter<String>(this,R.layout.device_name);
- mNewDevicesArrayAdapter=newArrayAdapter<String>(this,R.layout.device_name);
- //FindandsetuptheListViewforpaireddevices
- ListViewpairedListView=(ListView)findViewById(R.id.paired_devices);
- pairedListView.setAdapter(mPairedDevicesArrayAdapter);
- pairedListView.setOnItemClickListener(mDeviceClickListener);
- //FindandsetuptheListViewfornewlydiscovereddevices
- ListViewnewDevicesListView=(ListView)findViewById(R.id.new_devices);
- newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
- newDevicesListView.setOnItemClickListener(mDeviceClickListener);
- //Registerforbroadcastswhenadeviceisdiscovered
- IntentFilterfilter=newIntentFilter(BluetoothDevice.ACTION_FOUND);
- this.registerReceiver(mReceiver,filter);
- //Registerforbroadcastswhendiscoveryhasfinished
- filter=newIntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
- this.registerReceiver(mReceiver,filter);
- //GetthelocalBluetoothadapter
- mBtAdapter=BluetoothAdapter.getDefaultAdapter();
- //Getasetofcurrentlypaireddevices
- Set<BluetoothDevice>pairedDevices=mBtAdapter.getBondedDevices();
- //Iftherearepaireddevices,addeachonetotheArrayAdapter
- if(pairedDevices.size()>0){
- findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
- for(BluetoothDevicedevice:pairedDevices){
- mPairedDevicesArrayAdapter.add(device.getName()+"\n"+device.getAddress());
- }
- }else{
- StringnoDevices=getResources().getText(R.string.none_paired).toString();
- mPairedDevicesArrayAdapter.add(noDevices);
- }
- }
- @Override
- protectedvoidonDestroy(){
- super.onDestroy();
- //Makesurewe'renotdoingdiscoveryanymore
- if(mBtAdapter!=null){
- mBtAdapter.cancelDiscovery();
- }
- //Unregisterbroadcastlisteners
- this.unregisterReceiver(mReceiver);
- }
- /**
- *StartdevicediscoverwiththeBluetoothAdapter
- */
- privatevoiddoDiscovery(){
- if(D)Log.d(TAG,"doDiscovery()");
- //Indicatescanninginthetitle
- setProgressBarIndeterminateVisibility(true);
- setTitle(R.string.scanning);
- //Turnonsub-titlefornewdevices
- findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
- //Ifwe'realreadydiscovering,stopit
- if(mBtAdapter.isDiscovering()){
- mBtAdapter.cancelDiscovery();
- }
- //RequestdiscoverfromBluetoothAdapter
- mBtAdapter.startDiscovery();
- }
- //Theon-clicklistenerforalldevicesintheListViews
- privateOnItemClickListenermDeviceClickListener=newOnItemClickListener(){
- publicvoidonItemClick(AdapterView<?>av,Viewv,intarg2,longarg3){
- //Canceldiscoverybecauseit'scostlyandwe'reabouttoconnect
- mBtAdapter.cancelDiscovery();
- //GetthedeviceMACaddress,whichisthelast17charsintheView
- Stringinfo=((TextView)v).getText().toString();
- Stringaddress=info.substring(info.length()-17);
- //CreatetheresultIntentandincludetheMACaddress
- Intentintent=newIntent();
- intent.putExtra(EXTRA_DEVICE_ADDRESS,address);
- //SetresultandfinishthisActivity
- setResult(Activity.RESULT_OK,intent);
- finish();
- }
- };
- //TheBroadcastReceiverthatlistensfordiscovereddevicesand
- //changesthetitlewhendiscoveryisfinished
- privatefinalBroadcastReceivermReceiver=newBroadcastReceiver(){
- @Override
- publicvoidonReceive(Contextcontext,Intentintent){
- Stringaction=intent.getAction();
- //Whendiscoveryfindsadevice
- if(BluetoothDevice.ACTION_FOUND.equals(action)){
- //GettheBluetoothDeviceobjectfromtheIntent
- BluetoothDevicedevice=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- //Ifit'salreadypaired,skipit,becauseit'sbeenlistedalready
- if(device.getBondState()!=BluetoothDevice.BOND_BONDED){
- mNewDevicesArrayAdapter.add(device.getName()+"\n"+device.getAddress());
- }
- //Whendiscoveryisfinished,changetheActivitytitle
- }elseif(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
- setProgressBarIndeterminateVisibility(false);
- setTitle(R.string.select_device);
- if(mNewDevicesArrayAdapter.getCount()==0){
- StringnoDevices=getResources().getText(R.string.none_found).toString();
- mNewDevicesArrayAdapter.add(noDevices);
- }
- }
- }
- };
- }
作者在这里介绍的这个实例是Google SDK中提供的一个蓝牙聊天程序,简单但信息量巨大,非常适合初学者学习蓝牙方面的知识。
在学习这个实例前请读者仔细阅读并理解Socket的工作原理和实现机制,作者的这篇博客中有详细的介绍:
http://blog.csdn.net/dlutbrucezhang/article/details/8577810
在Android1.x的时候,相关API非常不完善,还不能简单的使用Bluetooth开发,有一个开源项目可以帮助程序员使用、开发蓝牙,支持直接方法bluetooth协议栈。在Android2以后,框架提供了一些官方API来进行蓝牙的通信,但目前的程序也比较不完善。本文主要讨论Android2后的Bluetooth通信的API使用方法。
首先看聊天室的效果图:
蓝牙设备连接的过程如下图所示:
下面这张图展示的是蓝牙聊天的时序图:
接下来将贴出源码并对源码做出详细的解释说明:
BluetoothChat.java
例程的主Activity。onCreate()得到本地BluetoothAdapter设备,检查是否支持。onStart()中检查是否启用蓝牙,并请求启用,然后执行setupChat()。setupChat()中先对界面中的控件进行初始化增加点击监听器等,然创建BluetoothChatService对象,该对象在整个应用过程中存在,并执行蓝牙连接建立、消息发送接受等实际的行为。
- importandroid.app.Activity;
- importandroid.bluetooth.BluetoothAdapter;
- importandroid.bluetooth.BluetoothDevice;
- importandroid.content.Intent;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.util.Log;
- importandroid.view.KeyEvent;
- importandroid.view.Menu;
- importandroid.view.MenuInflater;
- importandroid.view.MenuItem;
- importandroid.view.View;
- importandroid.view.Window;
- importandroid.view.View.OnClickListener;
- importandroid.view.inputmethod.EditorInfo;
- importandroid.widget.ArrayAdapter;
- importandroid.widget.Button;
- importandroid.widget.EditText;
- importandroid.widget.ListView;
- importandroid.widget.TextView;
- importandroid.widget.Toast;
- /**
- *ThisisthemainActivitythatdisplaysthecurrentchatsession.
- */
- publicclassBluetoothChatextendsActivity{
- //Debugging
- privatestaticfinalStringTAG="BluetoothChat";
- privatestaticfinalbooleanD=true;
- //MessagetypessentfromtheBluetoothChatServiceHandler
- publicstaticfinalintMESSAGE_STATE_CHANGE=1;
- publicstaticfinalintMESSAGE_READ=2;
- publicstaticfinalintMESSAGE_WRITE=3;
- publicstaticfinalintMESSAGE_DEVICE_NAME=4;
- publicstaticfinalintMESSAGE_TOAST=5;
- //KeynamesreceivedfromtheBluetoothChatServiceHandler
- publicstaticfinalStringDEVICE_NAME="device_name";
- publicstaticfinalStringTOAST="toast";
- //Intentrequestcodes
- privatestaticfinalintREQUEST_CONNECT_DEVICE=1;
- privatestaticfinalintREQUEST_ENABLE_BT=2;
- //LayoutViews
- privateTextViewmTitle;
- privateListViewmConversationView;
- privateEditTextmOutEditText;
- privateButtonmSendButton;
- //Nameoftheconnecteddevice
- privateStringmConnectedDeviceName=null;
- //Arrayadapterfortheconversationthread
- privateArrayAdapter<String>mConversationArrayAdapter;
- //Stringbufferforoutgoingmessages
- privateStringBuffermOutStringBuffer;
- //LocalBluetoothadapter
- privateBluetoothAdaptermBluetoothAdapter=null;
- //Memberobjectforthechatservices
- privateBluetoothChatServicemChatService=null;
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- if(D)Log.e(TAG,"+++ONCREATE+++");
- //Setupthewindowlayout
- requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
- setContentView(R.layout.main);
- getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.custom_title);
- //Setupthecustomtitle
- mTitle=(TextView)findViewById(R.id.title_left_text);
- mTitle.setText(R.string.app_name);
- mTitle=(TextView)findViewById(R.id.title_right_text);
- //GetlocalBluetoothadapter
- mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
- //Iftheadapterisnull,thenBluetoothisnotsupported
- if(mBluetoothAdapter==null){
- Toast.makeText(this,"Bluetoothisnotavailable",Toast.LENGTH_LONG).show();
- finish();
- return;
- }
- }
- @Override
- publicvoidonStart(){
- super.onStart();
- if(D)Log.e(TAG,"++ONSTART++");
- //IfBTisnoton,requestthatitbeenabled.
- //setupChat()willthenbecalledduringonActivityResult
- if(!mBluetoothAdapter.isEnabled()){
- IntentenableIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
- startActivityForResult(enableIntent,REQUEST_ENABLE_BT);
- //Otherwise,setupthechatsession
- }else{
- if(mChatService==null)setupChat();
- }
- }
- @Override
- publicsynchronizedvoidonResume(){
- super.onResume();
- if(D)Log.e(TAG,"+ONRESUME+");
- //PerformingthischeckinonResume()coversthecaseinwhichBTwas
- //notenabledduringonStart(),sowewerepausedtoenableit...
- //onResume()willbecalledwhenACTION_REQUEST_ENABLEactivityreturns.
- if(mChatService!=null){
- //OnlyifthestateisSTATE_NONE,doweknowthatwehaven'tstartedalready
- if(mChatService.getState()==BluetoothChatService.STATE_NONE){
- //StarttheBluetoothchatservices
- mChatService.start();
- }
- }
- }
- privatevoidsetupChat(){
- Log.d(TAG,"setupChat()");
- //Initializethearrayadapterfortheconversationthread
- mConversationArrayAdapter=newArrayAdapter<String>(this,R.layout.message);
- mConversationView=(ListView)findViewById(R.id.in);
- mConversationView.setAdapter(mConversationArrayAdapter);
- //Initializethecomposefieldwithalistenerforthereturnkey
- mOutEditText=(EditText)findViewById(R.id.edit_text_out);
- mOutEditText.setOnEditorActionListener(mWriteListener);
- //Initializethesendbuttonwithalistenerthatforclickevents
- mSendButton=(Button)findViewById(R.id.button_send);
- mSendButton.setOnClickListener(newOnClickListener(){
- publicvoidonClick(Viewv){
- //Sendamessageusingcontentoftheedittextwidget
- TextViewview=(TextView)findViewById(R.id.edit_text_out);
- Stringmessage=view.getText().toString();
- sendMessage(message);
- }
- });
- //InitializetheBluetoothChatServicetoperformbluetoothconnections
- mChatService=newBluetoothChatService(this,mHandler);
- //Initializethebufferforoutgoingmessages
- mOutStringBuffer=newStringBuffer("");
- }
- @Override
- publicsynchronizedvoidonPause(){
- super.onPause();
- if(D)Log.e(TAG,"-ONPAUSE-");
- }
- @Override
- publicvoidonStop(){
- super.onStop();
- if(D)Log.e(TAG,"--ONSTOP--");
- }
- @Override
- publicvoidonDestroy(){
- super.onDestroy();
- //StoptheBluetoothchatservices
- if(mChatService!=null)mChatService.stop();
- if(D)Log.e(TAG,"---ONDESTROY---");
- }
- privatevoidensureDiscoverable(){
- if(D)Log.d(TAG,"ensurediscoverable");
- if(mBluetoothAdapter.getScanMode()!=
- BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){
- IntentdiscoverableIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
- discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);
- startActivity(discoverableIntent);
- }
- }
- /**
- *Sendsamessage.
- *@parammessageAstringoftexttosend.
- */
- privatevoidsendMessage(Stringmessage){
- //Checkthatwe'reactuallyconnectedbeforetryinganything
- if(mChatService.getState()!=BluetoothChatService.STATE_CONNECTED){
- Toast.makeText(this,R.string.not_connected,Toast.LENGTH_SHORT).show();
- return;
- }
- //Checkthatthere'sactuallysomethingtosend
- if(message.length()>0){
- //GetthemessagebytesandtelltheBluetoothChatServicetowrite
- byte[]send=message.getBytes();
- mChatService.write(send);
- //Resetoutstringbuffertozeroandcleartheedittextfield
- mOutStringBuffer.setLength(0);
- mOutEditText.setText(mOutStringBuffer);
- }
- }
- //TheactionlistenerfortheEditTextwidget,tolistenforthereturnkey
- privateTextView.OnEditorActionListenermWriteListener=
- newTextView.OnEditorActionListener(){
- publicbooleanonEditorAction(TextViewview,intactionId,KeyEventevent){
- //Iftheactionisakey-upeventonthereturnkey,sendthemessage
- if(actionId==EditorInfo.IME_NULL&&event.getAction()==KeyEvent.ACTION_UP){
- Stringmessage=view.getText().toString();
- sendMessage(message);
- }
- if(D)Log.i(TAG,"ENDonEditorAction");
- returntrue;
- }
- };
- //TheHandlerthatgetsinformationbackfromtheBluetoothChatService
- privatefinalHandlermHandler=newHandler(){
- @Override
- publicvoidhandleMessage(Messagemsg){
- switch(msg.what){
- caseMESSAGE_STATE_CHANGE:
- if(D)Log.i(TAG,"MESSAGE_STATE_CHANGE:"+msg.arg1);
- switch(msg.arg1){
- caseBluetoothChatService.STATE_CONNECTED:
- mTitle.setText(R.string.title_connected_to);
- mTitle.append(mConnectedDeviceName);
- mConversationArrayAdapter.clear();
- break;
- caseBluetoothChatService.STATE_CONNECTING:
- mTitle.setText(R.string.title_connecting);
- break;
- caseBluetoothChatService.STATE_LISTEN:
- caseBluetoothChatService.STATE_NONE:
- mTitle.setText(R.string.title_not_connected);
- break;
- }
- break;
- caseMESSAGE_WRITE:
- byte[]writeBuf=(byte[])msg.obj;
- //constructastringfromthebuffer
- StringwriteMessage=newString(writeBuf);
- mConversationArrayAdapter.add("Me:"+writeMessage);
- break;
- caseMESSAGE_READ:
- byte[]readBuf=(byte[])msg.obj;
- //constructastringfromthevalidbytesinthebuffer
- StringreadMessage=newString(readBuf,0,msg.arg1);
- mConversationArrayAdapter.add(mConnectedDeviceName+":"+readMessage);
- break;
- caseMESSAGE_DEVICE_NAME:
- //savetheconnecteddevice'sname
- mConnectedDeviceName=msg.getData().getString(DEVICE_NAME);
- Toast.makeText(getApplicationContext(),"Connectedto"
- +mConnectedDeviceName,Toast.LENGTH_SHORT).show();
- break;
- caseMESSAGE_TOAST:
- Toast.makeText(getApplicationContext(),msg.getData().getString(TOAST),
- Toast.LENGTH_SHORT).show();
- break;
- }
- }
- };
- publicvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
- if(D)Log.d(TAG,"onActivityResult"+resultCode);
- switch(requestCode){
- caseREQUEST_CONNECT_DEVICE:
- //WhenDeviceListActivityreturnswithadevicetoconnect
- if(resultCode==Activity.RESULT_OK){
- //GetthedeviceMACaddress
- Stringaddress=data.getExtras()
- .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
- //GettheBLuetoothDeviceobject
- BluetoothDevicedevice=mBluetoothAdapter.getRemoteDevice(address);
- //Attempttoconnecttothedevice
- mChatService.connect(device);
- }
- break;
- caseREQUEST_ENABLE_BT:
- //WhentherequesttoenableBluetoothreturns
- if(resultCode==Activity.RESULT_OK){
- //Bluetoothisnowenabled,sosetupachatsession
- setupChat();
- }else{
- //UserdidnotenableBluetoothoranerroroccured
- Log.d(TAG,"BTnotenabled");
- Toast.makeText(this,R.string.bt_not_enabled_leaving,Toast.LENGTH_SHORT).show();
- finish();
- }
- }
- }
- @Override
- publicbooleanonCreateOptionsMenu(Menumenu){
- MenuInflaterinflater=getMenuInflater();
- inflater.inflate(R.menu.option_menu,menu);
- returntrue;
- }
- @Override
- publicbooleanonOptionsItemSelected(MenuItemitem){
- switch(item.getItemId()){
- caseR.id.scan:
- //LaunchtheDeviceListActivitytoseedevicesanddoscan
- IntentserverIntent=newIntent(this,DeviceListActivity.class);
- startActivityForResult(serverIntent,REQUEST_CONNECT_DEVICE);
- returntrue;
- caseR.id.discoverable:
- //Ensurethisdeviceisdiscoverablebyothers
- ensureDiscoverable();
- returntrue;
- }
- returnfalse;
- }
- }
BluetoothChatService.java
public synchronized void start():
开启mAcceptThread线程,由于样例程序是仅2人的聊天过程,故之前先检测mConnectThread和mConnectedThread是否运行,运行则先退出这些线程。
public synchronized voidconnect(BluetoothDevice device):
取消CONNECTING和CONNECTED状态下的相关线程,然后运行新的mConnectThread线程。
public synchronized voidconnected(BluetoothSocket socket, BluetoothDevice device):
开启一个ConnectedThread来管理对应的当前连接。之前先取消任意现存的mConnectThread、mConnectedThread、mAcceptThread线程,然后开启新mConnectedThread,传入当前刚刚接受的socket连接。最后通过Handler来通知UI连接OK。
public synchronized void stop():
停止所有相关线程,设当前状态为NONE。
public void write(byte[] out):
在STATE_CONNECTED状态下,调用mConnectedThread里的write方法,写入byte。
private void connectionFailed():
连接失败的时候处理,通知ui,并设为STATE_LISTEN状态。
private void connectionLost():
当连接失去的时候,设为STATE_LISTEN状态并通知ui。
内部类:
private class AcceptThread extendsThread:
创建监听线程,准备接受新连接。使用阻塞方式,调用BluetoothServerSocket.accept()。提供cancel方法关闭socket。
private class ConnectThread extendsThread:
这是定义的连接线程,专门用来对外发出连接对方蓝牙的请求和处理流程。构造函数里通过BluetoothDevice.createRfcommSocketToServiceRecord(),从待连接的device产生BluetoothSocket.然后在run方法中connect,成功后调用BluetoothChatSevice的connected()方法。定义cancel()在关闭线程时能够关闭相关socket。
private class ConnectedThread extendsThread:
这个是双方蓝牙连接后一直运行的线程。构造函数中设置输入输出流。Run方法中使用阻塞模式的InputStream.read()循环读取输入流,然后post到UI线程中更新聊天消息。也提供了write()将聊天消息写入输出流传输至对方,传输成功后回写入UI线程。最后cancel()关闭连接的socket。
- importjava.io.IOException;
- importjava.io.InputStream;
- importjava.io.OutputStream;
- importjava.util.UUID;
- importandroid.annotation.SuppressLint;
- importandroid.bluetooth.BluetoothAdapter;
- importandroid.bluetooth.BluetoothDevice;
- importandroid.bluetooth.BluetoothServerSocket;
- importandroid.bluetooth.BluetoothSocket;
- importandroid.content.Context;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.util.Log;
- /**
- *ThisclassdoesalltheworkforsettingupandmanagingBluetooth
- *connectionswithotherdevices.Ithasathreadthatlistensfor
- *incomingconnections,athreadforconnectingwithadevice,anda
- *threadforperformingdatatransmissionswhenconnected.
- */
- @SuppressLint("NewApi")
- publicclassBluetoothChatService{
- //Debugging
- privatestaticfinalStringTAG="BluetoothChatService";
- privatestaticfinalbooleanD=true;
- //NamefortheSDPrecordwhencreatingserversocket
- privatestaticfinalStringNAME="BluetoothChat";
- //UniqueUUIDforthisapplication
- privatestaticfinalUUIDMY_UUID=UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
- //Memberfields
- privatefinalBluetoothAdaptermAdapter;
- privatefinalHandlermHandler;
- privateAcceptThreadmAcceptThread;
- privateConnectThreadmConnectThread;
- privateConnectedThreadmConnectedThread;
- privateintmState;
- //Constantsthatindicatethecurrentconnectionstate
- publicstaticfinalintSTATE_NONE=0;//we'redoingnothing
- publicstaticfinalintSTATE_LISTEN=1;//nowlisteningforincomingconnections
- publicstaticfinalintSTATE_CONNECTING=2;//nowinitiatinganoutgoingconnection
- publicstaticfinalintSTATE_CONNECTED=3;//nowconnectedtoaremotedevice
- /**
- *Constructor.PreparesanewBluetoothChatsession.
- *@paramcontextTheUIActivityContext
- *@paramhandlerAHandlertosendmessagesbacktotheUIActivity
- */
- publicBluetoothChatService(Contextcontext,Handlerhandler){
- mAdapter=BluetoothAdapter.getDefaultAdapter();
- mState=STATE_NONE;
- mHandler=handler;
- }
- /**
- *Setthecurrentstateofthechatconnection
- *@paramstateAnintegerdefiningthecurrentconnectionstate
- */
- privatesynchronizedvoidsetState(intstate){
- if(D)Log.d(TAG,"setState()"+mState+"->"+state);
- mState=state;
- //GivethenewstatetotheHandlersotheUIActivitycanupdate
- mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE,state,-1).sendToTarget();
- }
- /**
- *Returnthecurrentconnectionstate.*/
- publicsynchronizedintgetState(){
- returnmState;
- }
- /**
- *Startthechatservice.SpecificallystartAcceptThreadtobegina
- *sessioninlistening(server)mode.CalledbytheActivityonResume()*/
- publicsynchronizedvoidstart(){
- if(D)Log.d(TAG,"start");
- //Cancelanythreadattemptingtomakeaconnection
- if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}
- //Cancelanythreadcurrentlyrunningaconnection
- if(mConnectedThread!=null){mConnectedThread.cancel();mConnectedThread=null;}
- //StartthethreadtolistenonaBluetoothServerSocket
- if(mAcceptThread==null){
- mAcceptThread=newAcceptThread();
- mAcceptThread.start();
- }
- setState(STATE_LISTEN);
- }
- /**
- *StarttheConnectThreadtoinitiateaconnectiontoaremotedevice.
- *@paramdeviceTheBluetoothDevicetoconnect
- */
- publicsynchronizedvoidconnect(BluetoothDevicedevice){
- if(D)Log.d(TAG,"connectto:"+device);
- //Cancelanythreadattemptingtomakeaconnection
- if(mState==STATE_CONNECTING){
- if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}
- }
- //Cancelanythreadcurrentlyrunningaconnection
- if(mConnectedThread!=null){mConnectedThread.cancel();mConnectedThread=null;}
- //Startthethreadtoconnectwiththegivendevice
- mConnectThread=newConnectThread(device);
- mConnectThread.start();
- setState(STATE_CONNECTING);
- }
- /**
- *StarttheConnectedThreadtobeginmanagingaBluetoothconnection
- *@paramsocketTheBluetoothSocketonwhichtheconnectionwasmade
- *@paramdeviceTheBluetoothDevicethathasbeenconnected
- */
- publicsynchronizedvoidconnected(BluetoothSocketsocket,BluetoothDevicedevice){
- if(D)Log.d(TAG,"connected");
- //Cancelthethreadthatcompletedtheconnection
- if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}
- //Cancelanythreadcurrentlyrunningaconnection
- if(mConnectedThread!=null){mConnectedThread.cancel();mConnectedThread=null;}
- //Canceltheacceptthreadbecauseweonlywanttoconnecttoonedevice
- if(mAcceptThread!=null){mAcceptThread.cancel();mAcceptThread=null;}
- //Startthethreadtomanagetheconnectionandperformtransmissions
- mConnectedThread=newConnectedThread(socket);
- mConnectedThread.start();
- //SendthenameoftheconnecteddevicebacktotheUIActivity
- Messagemsg=mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME);
- Bundlebundle=newBundle();
- bundle.putString(BluetoothChat.DEVICE_NAME,device.getName());
- msg.setData(bundle);
- mHandler.sendMessage(msg);
- setState(STATE_CONNECTED);
- }
- /**
- *Stopallthreads
- */
- publicsynchronizedvoidstop(){
- if(D)Log.d(TAG,"stop");
- if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}
- if(mConnectedThread!=null){mConnectedThread.cancel();mConnectedThread=null;}
- if(mAcceptThread!=null){mAcceptThread.cancel();mAcceptThread=null;}
- setState(STATE_NONE);
- }
- /**
- *WritetotheConnectedThreadinanunsynchronizedmanner
- *@paramoutThebytestowrite
- *@seeConnectedThread#write(byte[])
- */
- publicvoidwrite(byte[]out){
- //Createtemporaryobject
- ConnectedThreadr;
- //SynchronizeacopyoftheConnectedThread
- synchronized(this){
- if(mState!=STATE_CONNECTED)return;
- r=mConnectedThread;
- }
- //Performthewriteunsynchronized
- r.write(out);
- }
- /**
- *IndicatethattheconnectionattemptfailedandnotifytheUIActivity.
- */
- privatevoidconnectionFailed(){
- setState(STATE_LISTEN);
- //SendafailuremessagebacktotheActivity
- Messagemsg=mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
- Bundlebundle=newBundle();
- bundle.putString(BluetoothChat.TOAST,"Unabletoconnectdevice");
- msg.setData(bundle);
- mHandler.sendMessage(msg);
- }
- /**
- *IndicatethattheconnectionwaslostandnotifytheUIActivity.
- */
- privatevoidconnectionLost(){
- setState(STATE_LISTEN);
- //SendafailuremessagebacktotheActivity
- Messagemsg=mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
- Bundlebundle=newBundle();
- bundle.putString(BluetoothChat.TOAST,"Deviceconnectionwaslost");
- msg.setData(bundle);
- mHandler.sendMessage(msg);
- }
- /**
- *Thisthreadrunswhilelisteningforincomingconnections.Itbehaves
- *likeaserver-sideclient.Itrunsuntilaconnectionisaccepted
- *(oruntilcancelled).
- */
- @SuppressLint("NewApi")
- privateclassAcceptThreadextendsThread{
- //Thelocalserversocket
- privatefinalBluetoothServerSocketmmServerSocket;
- publicAcceptThread(){
- BluetoothServerSockettmp=null;
- //Createanewlisteningserversocket
- try{
- //开启监听
- tmp=mAdapter.listenUsingRfcommWithServiceRecord(NAME,MY_UUID);
- }catch(IOExceptione){
- Log.e(TAG,"listen()failed",e);
- }
- mmServerSocket=tmp;
- }
- publicvoidrun(){
- if(D)Log.d(TAG,"BEGINmAcceptThread"+this);
- setName("AcceptThread");
- BluetoothSocketsocket=null;
- //Listentotheserversocketifwe'renotconnected
- while(mState!=STATE_CONNECTED){
- try{
- //Thisisablockingcallandwillonlyreturnona
- //successfulconnectionoranexception
- socket=mmServerSocket.accept();
- }catch(IOExceptione){
- Log.e(TAG,"accept()failed",e);
- break;
- }
- //Ifaconnectionwasaccepted
- if(socket!=null){
- synchronized(BluetoothChatService.this){
- switch(mState){
- caseSTATE_LISTEN:
- caseSTATE_CONNECTING:
- //Situationnormal.Starttheconnectedthread.
- connected(socket,socket.getRemoteDevice());
- break;
- caseSTATE_NONE:
- caseSTATE_CONNECTED:
- //Eithernotreadyoralreadyconnected.Terminatenewsocket.
- try{
- socket.close();
- }catch(IOExceptione){
- Log.e(TAG,"Couldnotcloseunwantedsocket",e);
- }
- break;
- }
- }
- }
- }
- if(D)Log.i(TAG,"ENDmAcceptThread");
- }
- publicvoidcancel(){
- if(D)Log.d(TAG,"cancel"+this);
- try{
- mmServerSocket.close();
- }catch(IOExceptione){
- Log.e(TAG,"close()ofserverfailed",e);
- }
- }
- }
- /**
- *Thisthreadrunswhileattemptingtomakeanoutgoingconnection
- *withadevice.Itrunsstraightthrough;theconnectioneither
- *succeedsorfails.
- */
- privateclassConnectThreadextendsThread{
- privatefinalBluetoothSocketmmSocket;
- privatefinalBluetoothDevicemmDevice;
- publicConnectThread(BluetoothDevicedevice){
- mmDevice=device;
- BluetoothSockettmp=null;
- //GetaBluetoothSocketforaconnectionwiththe
- //givenBluetoothDevice
- try{
- tmp=device.createRfcommSocketToServiceRecord(MY_UUID);
- }catch(IOExceptione){
- Log.e(TAG,"create()failed",e);
- }
- mmSocket=tmp;
- }
- publicvoidrun(){
- Log.i(TAG,"BEGINmConnectThread");
- setName("ConnectThread");
- //Alwayscanceldiscoverybecauseitwillslowdownaconnection
- mAdapter.cancelDiscovery();
- //MakeaconnectiontotheBluetoothSocket
- try{
- //Thisisablockingcallandwillonlyreturnona
- //successfulconnectionoranexception
- mmSocket.connect();
- }catch(IOExceptione){
- connectionFailed();
- //Closethesocket
- try{
- mmSocket.close();
- }catch(IOExceptione2){
- Log.e(TAG,"unabletoclose()socketduringconnectionfailure",e2);
- }
- //Starttheserviceovertorestartlisteningmode
- BluetoothChatService.this.start();
- return;
- }
- //ResettheConnectThreadbecausewe'redone
- synchronized(BluetoothChatService.this){
- mConnectThread=null;
- }
- //Starttheconnectedthread
- connected(mmSocket,mmDevice);
- }
- publicvoidcancel(){
- try{
- mmSocket.close();
- }catch(IOExceptione){
- Log.e(TAG,"close()ofconnectsocketfailed",e);
- }
- }
- }
- /**
- *Thisthreadrunsduringaconnectionwitharemotedevice.
- *Ithandlesallincomingandoutgoingtransmissions.
- */
- privateclassConnectedThreadextendsThread{
- privatefinalBluetoothSocketmmSocket;
- privatefinalInputStreammmInStream;
- privatefinalOutputStreammmOutStream;
- publicConnectedThread(BluetoothSocketsocket){
- Log.d(TAG,"createConnectedThread");
- mmSocket=socket;
- InputStreamtmpIn=null;
- OutputStreamtmpOut=null;
- //GettheBluetoothSocketinputandoutputstreams
- try{
- tmpIn=socket.getInputStream();
- tmpOut=socket.getOutputStream();
- }catch(IOExceptione){
- Log.e(TAG,"tempsocketsnotcreated",e);
- }
- mmInStream=tmpIn;
- mmOutStream=tmpOut;
- }
- publicvoidrun(){
- Log.i(TAG,"BEGINmConnectedThread");
- byte[]buffer=newbyte[1024];
- intbytes;
- //KeeplisteningtotheInputStreamwhileconnected
- while(true){
- try{
- //ReadfromtheInputStream
- bytes=mmInStream.read(buffer);
- //SendtheobtainedbytestotheUIActivity
- mHandler.obtainMessage(BluetoothChat.MESSAGE_READ,bytes,-1,buffer)
- .sendToTarget();
- }catch(IOExceptione){
- Log.e(TAG,"disconnected",e);
- connectionLost();
- break;
- }
- }
- }
- /**
- *WritetotheconnectedOutStream.
- *@parambufferThebytestowrite
- */
- publicvoidwrite(byte[]buffer){
- try{
- mmOutStream.write(buffer);
- //SharethesentmessagebacktotheUIActivity
- mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE,-1,-1,buffer)
- .sendToTarget();
- }catch(IOExceptione){
- Log.e(TAG,"Exceptionduringwrite",e);
- }
- }
- publicvoidcancel(){
- try{
- mmSocket.close();
- }catch(IOExceptione){
- Log.e(TAG,"close()ofconnectsocketfailed",e);
- }
- }
- }
- }
DeviceListActivity.java
该类包含UI和操作的Activity类,作用是得到系统默认蓝牙设备的已配对设备列表,以及搜索出的未配对的新设备的列表。然后提供点击后发出连接设备请求的功能。
- importjava.util.Set;
- importandroid.annotation.SuppressLint;
- importandroid.app.Activity;
- importandroid.bluetooth.BluetoothAdapter;
- importandroid.bluetooth.BluetoothDevice;
- importandroid.content.BroadcastReceiver;
- importandroid.content.Context;
- importandroid.content.Intent;
- importandroid.content.IntentFilter;
- importandroid.os.Bundle;
- importandroid.util.Log;
- importandroid.view.View;
- importandroid.view.Window;
- importandroid.view.View.OnClickListener;
- importandroid.widget.AdapterView;
- importandroid.widget.ArrayAdapter;
- importandroid.widget.Button;
- importandroid.widget.ListView;
- importandroid.widget.TextView;
- importandroid.widget.AdapterView.OnItemClickListener;
- /**
- *ThisActivityappearsasadialog.Itlistsanypaireddevicesand
- *devicesdetectedintheareaafterdiscovery.Whenadeviceischosen
- *bytheuser,theMACaddressofthedeviceissentbacktotheparent
- *ActivityintheresultIntent.
- */
- @SuppressLint("NewApi")
- publicclassDeviceListActivityextendsActivity{
- //Debugging
- privatestaticfinalStringTAG="DeviceListActivity";
- privatestaticfinalbooleanD=true;
- //ReturnIntentextra
- publicstaticStringEXTRA_DEVICE_ADDRESS="device_address";
- //Memberfields
- privateBluetoothAdaptermBtAdapter;
- privateArrayAdapter<String>mPairedDevicesArrayAdapter;
- privateArrayAdapter<String>mNewDevicesArrayAdapter;
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- //Setupthewindow
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
- setContentView(R.layout.device_list);
- //SetresultCANCELEDincasetheuserbacksout
- setResult(Activity.RESULT_CANCELED);
- //Initializethebuttontoperformdevicediscovery
- ButtonscanButton=(Button)findViewById(R.id.button_scan);
- scanButton.setOnClickListener(newOnClickListener(){
- publicvoidonClick(Viewv){
- doDiscovery();
- v.setVisibility(View.GONE);
- }
- });
- //Initializearrayadapters.Oneforalreadypaireddevicesand
- //onefornewlydiscovereddevices
- mPairedDevicesArrayAdapter=newArrayAdapter<String>(this,R.layout.device_name);
- mNewDevicesArrayAdapter=newArrayAdapter<String>(this,R.layout.device_name);
- //FindandsetuptheListViewforpaireddevices
- ListViewpairedListView=(ListView)findViewById(R.id.paired_devices);
- pairedListView.setAdapter(mPairedDevicesArrayAdapter);
- pairedListView.setOnItemClickListener(mDeviceClickListener);
- //FindandsetuptheListViewfornewlydiscovereddevices
- ListViewnewDevicesListView=(ListView)findViewById(R.id.new_devices);
- newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
- newDevicesListView.setOnItemClickListener(mDeviceClickListener);
- //Registerforbroadcastswhenadeviceisdiscovered
- IntentFilterfilter=newIntentFilter(BluetoothDevice.ACTION_FOUND);
- this.registerReceiver(mReceiver,filter);
- //Registerforbroadcastswhendiscoveryhasfinished
- filter=newIntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
- this.registerReceiver(mReceiver,filter);
- //GetthelocalBluetoothadapter
- mBtAdapter=BluetoothAdapter.getDefaultAdapter();
- //Getasetofcurrentlypaireddevices
- Set<BluetoothDevice>pairedDevices=mBtAdapter.getBondedDevices();
- //Iftherearepaireddevices,addeachonetotheArrayAdapter
- if(pairedDevices.size()>0){
- findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
- for(BluetoothDevicedevice:pairedDevices){
- mPairedDevicesArrayAdapter.add(device.getName()+"\n"+device.getAddress());
- }
- }else{
- StringnoDevices=getResources().getText(R.string.none_paired).toString();
- mPairedDevicesArrayAdapter.add(noDevices);
- }
- }
- @Override
- protectedvoidonDestroy(){
- super.onDestroy();
- //Makesurewe'renotdoingdiscoveryanymore
- if(mBtAdapter!=null){
- mBtAdapter.cancelDiscovery();
- }
- //Unregisterbroadcastlisteners
- this.unregisterReceiver(mReceiver);
- }
- /**
- *StartdevicediscoverwiththeBluetoothAdapter
- */
- privatevoiddoDiscovery(){
- if(D)Log.d(TAG,"doDiscovery()");
- //Indicatescanninginthetitle
- setProgressBarIndeterminateVisibility(true);
- setTitle(R.string.scanning);
- //Turnonsub-titlefornewdevices
- findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
- //Ifwe'realreadydiscovering,stopit
- if(mBtAdapter.isDiscovering()){
- mBtAdapter.cancelDiscovery();
- }
- //RequestdiscoverfromBluetoothAdapter
- mBtAdapter.startDiscovery();
- }
- //Theon-clicklistenerforalldevicesintheListViews
- privateOnItemClickListenermDeviceClickListener=newOnItemClickListener(){
- publicvoidonItemClick(AdapterView<?>av,Viewv,intarg2,longarg3){
- //Canceldiscoverybecauseit'scostlyandwe'reabouttoconnect
- mBtAdapter.cancelDiscovery();
- //GetthedeviceMACaddress,whichisthelast17charsintheView
- Stringinfo=((TextView)v).getText().toString();
- Stringaddress=info.substring(info.length()-17);
- //CreatetheresultIntentandincludetheMACaddress
- Intentintent=newIntent();
- intent.putExtra(EXTRA_DEVICE_ADDRESS,address);
- //SetresultandfinishthisActivity
- setResult(Activity.RESULT_OK,intent);
- finish();
- }
- };
- //TheBroadcastReceiverthatlistensfordiscovereddevicesand
- //changesthetitlewhendiscoveryisfinished
- privatefinalBroadcastReceivermReceiver=newBroadcastReceiver(){
- @Override
- publicvoidonReceive(Contextcontext,Intentintent){
- Stringaction=intent.getAction();
- //Whendiscoveryfindsadevice
- if(BluetoothDevice.ACTION_FOUND.equals(action)){
- //GettheBluetoothDeviceobjectfromtheIntent
- BluetoothDevicedevice=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- //Ifit'salreadypaired,skipit,becauseit'sbeenlistedalready
- if(device.getBondState()!=BluetoothDevice.BOND_BONDED){
- mNewDevicesArrayAdapter.add(device.getName()+"\n"+device.getAddress());
- }
- //Whendiscoveryisfinished,changetheActivitytitle
- }elseif(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
- setProgressBarIndeterminateVisibility(false);
- setTitle(R.string.select_device);
- if(mNewDevicesArrayAdapter.getCount()==0){
- StringnoDevices=getResources().getText(R.string.none_found).toString();
- mNewDevicesArrayAdapter.add(noDevices);
- }
- }
- }
- };
- }
相关推荐
Android蓝牙程序实例,是你学习android蓝牙程序比较好的参考实例. 采用的是andorid studio开发工具开发的。
Android 蓝牙BLE全面解析以及智能车锁开发实例一、蓝牙BLE产生背景——蓝牙的发展历程 二、蓝牙BLE的基本概念 三、蓝牙BLE的架构介绍 1. 蓝牙BLE架构概览 2. 简述BLE如何发送数据包 2.1 广播方式 2.2 连接方式 四、...
Android_Lightblue.apk是Android版的lightblue,在进行ble开发的时候用该app作为辅助工具还是非常不错的,功能较Bluetooth4_3 BLEDemo 这两个demo都强大。不过Android_Lightblue.apk在android5.0以上的版本手机上...
这是一个Android蓝牙开发的小程序,代码简单,实现了蓝牙打开、搜索、配对、连接、通信等功能。两个Android项目,一个服务器一个客户端
是一个单片机蓝牙开发案例,android系统4.3以上,手机支持蓝牙4.0,搜索,配对,连接,发现服务及特征值,断开连接等功能。
Android BLE蓝牙例子(包括android版Lightblue)实例源码: 源码里面有Bluetooth4_3/BLEDemo/Android_Lightblue.apk三个.前两个是BLE的demo。BLEDemo这个功能较Bluetooth4_3多一些,有兴趣的可以都看下。Android_...
这是android的蓝牙聊天通信程序,可以进行蓝牙设备的搜索、连接,含注释
android开发蓝牙的一个简单例子,服务端和客户端的收发文字信息,用于安卓蓝牙开发入门再好不过了
Android蓝牙通信实例,有客户端和服务端两个程序,以便理解起来更加简单明了。
本文以实例的方式讲解Android蓝牙开发的知识。 1、使用蓝牙的响应权限 XML/HTML代码 <uses android:name=android.permission.BLUETOOTH/> <uses android:name=android.permission.BLUETOOTH_ADMIN/> 2、配置本...
基于android的蓝牙功能实现的源码,改源码能实现在android平台上的蓝牙功能。
本书以Android应用程序的开发为主题,并结合真实的案例向读者详细介绍了Android的基本组件的使用及应用程序开发的整个流程。本书的讲述由浅入深,实例全面并典型,几乎囊括了所有和Android应用相关的项目。全书分为...
2.保证无毒 3.简单,方便,实用 4.实例可以自行改用 5.如有非法,本人无法律责任,由改动代码人负责! 6.需要更多本人作品,查找标签“朱建强” 7.请下载,杀毒后再使用!
Android应用源码开发Demo,主要用于毕业设计学习。
由于现有的手机应用程序的开发是构建在各手机厂家的私有操作系统之上的,所以它限制了第三方应用程序的开发,而Android为我们提供了一个开放和通用的选择。因为没有了人为制造的障碍,所以Android开发人员可以自由地...
的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 • 应用程序框架 支持组件的重用与替换 • Dalvik Dalvik Dalvik Dalvik 虚拟机 专为移动设备优化 • ...
本文实例为大家分享了android实现蓝牙app的具体代码,供大家参考,具体内容如下 private BluetoothGatt bluetoothGatt; private BluetoothGattService gattService; private BluetoothGattCharacteristic ...
用户进行蓝牙开发时,首先将这两个工具类放到你的工程中,其次调用BlueToothUtils中的getSearchedDevices方法(需要实现这个类中的两个接口作为这个方法的参数)来获取搜索到的设备,设备将在接口中返回给你。...
android自带的示例程序 BluetoothChat 变蓝牙串口助手(内含DIY蓝牙遥控车附源码实例教程) Android高手过招 FAQ 网友收集的android开发书籍(可下载哦) 东软集团内部文件《android编程指南》 从零开始Android...