BluetoothChat
来源:互联网 发布:苹果安装不了软件 编辑:程序博客网 时间:2024/06/05 04:05
本来想自己写一个蓝牙聊天的程序的,可是看了好几天官方提供的源码,真的看得想哭,真的太蛋筒了,终于明白,基础差,在做稍微复杂写的程序的时候,就能看出自己的不足,就有瓶颈。从这个蓝牙开发来说,可以说是我做这个Android以来遇到的第一个比较头痛的问题,但是由于项目要用到蓝牙,所以这些天只能硬着皮头看下去,不得不说,越看,学到的东西越多,但是我也不能一一说出来,但是,不得不说,任然还有不懂的地方。尤其是多线程那一块,一定要重新认真看。不得不说,这个程序,给我了很大的刺激,让我明白,我还有太多要学习的。
我这里把我这几天看的,然后今天整理的官方的程序写上了我自己的注释,不是很多,但是最主要的是,我把程序的部分调序了,因为我觉得这是一个理解问题,就是按照什么样的顺序和思路来设计程序的。这样调序,可以很方便理解。但是,我不能保证我的理解思路就是适合别人的,但是至少适合我。还有就是service里面的几个线程的程序,我没有注释,因为真的不知道怎么注释比较好,不想直接翻译他提供的英语。
我依次说下他这三个代码的思路吧,我觉得第一个DeviceListActivity这个是最容易理解的,也是思路最明确的,内容也最少。大的方面就是两点,一个是显示本地已配对设备;二是显示搜索到的设备。先说第一个,显示本地已配对设备就直接通过一个set集合把pairedDevices遍历一遍,然后显示在listview里面。第二个稍微复杂点,因为要先查找,然后再显示出来。查找直接用startDiscovery就可以了。至于显示就比较麻烦,因为查找的过程是查找一个就发送一个广播,然后继续查找,直到查找结束。这就有一个问题,怎么把查找到一个就显示出一个呢?这就要用到BroadcastReceiver,这里要设置两个过滤器,用来处理不同的广播,一个是用来处理查找到新设备的广播,一个是用来处理结束查找的广播。第一个广播是最重要的,就是查到一个,通过这个过滤器,然后如果是这个广播,就执行显示操作。不过这里显示有两部分,一个是显示name,一个是MAC地址。不过这还么有完,因为你只是显示在listview里面了,但是你还要设置listview的选项监听器,因为我们要能选择一个设备,然后就进行和设备的配对,至于怎么配对待会再说,这里要能响应,然后把MAC地址返回到BluetoothChat这个activity里面,然后执行配对。所以这里使用的是setResult,把Intent的内容传回到主activity。这就是这个DeviceListActivity的全部功能。
接下来说BluetoothChat这个activity。总的来说是一下几个步骤,检测蓝牙,蓝牙是否打开,蓝牙的可被检测性,建立连接,开始聊天服务,但是有一个是贯穿整个流程的,就是UI的动态更新。蓝牙的检测和打开,可被检测这都很简单,不多说了。主要是怎么建立连接,这个要在service里面说;这个activity最最主要的有两点,一个是把信息显示在在listview上,就是发送和接收到的信息都要显示出来,这个其实也是在service的connectedThread里面做的,但是显示部分是在这个里面,service里只是通过handler把信息传给这个activity,BluetoothChat这个activity只是负责显示。另外一点就是连接状态的显示,分为四个状态,没有操作,连接中,连接了,和接收监听,我这个翻译也许不准确,但是应该能理解这四个状态,不过你从显示上看,只能看到三个,而监听这个是看不出来的。这四个状态也是通过handler传递信息,然后显示在状态栏的。其实这里面最难的就是这个handler的使用,因为他有两个功能,就是上面两类信息的显示。而第二类的显示就是所谓的UI的更新,也就是界面里能看到的动态listview和textview的显示。不过我也不能一下子说清楚这个handler,(我也还在学习中),所以希望我们都能好好学习,嘻嘻。。。
最后要说的就是这个service,也是最复杂的部分,其实这部分之所以复杂,主要是用到多线程,因为,这里面的很多方法都是阻塞线程的。大体上来说,我也只是说我知道的,这个服务,就是建立连接,那么中间有那些可能性呢?connect,connectionFailed,connected,connectionLost。而这四种可能性我想大家也都可以有自己的理解,我的理解就是,第一个是连接两个设备,第二个是连接失败,第三个是连接成功了,第四个也是连接失败,不过这个和第二个的区别在于,这个的前一状态是第三个,而不是第一个。由这四个引出的是两个线程,也是最重要的线程,ConnectThread和ConnectedThread,第一个是用来建立连接的,第二个是已经连接了,处理的是连接中的事,主要是两点,一个是收发信息,一个是如果发生connectionLost怎么办。而第一个建立连接是通过createRfcommSocketToServiceRecord方法来实现的。但是我们前面说到了这里有三个线程,还有一个是AcceptThread,这是一个监听socket的线程,用来查看有没有连接请求,我对他的理解是,他要监听的是刚才连接时说到的那个方法的UUID,然后进行连接。然后返回的是一个socket。这里还有的就是UI的更新,这里用到的是state的设置,然后通过handler把这个state返回去,然后更新UI。
好吧,这就是我能理解的部分,还有就是把我的注释的给展示出来吧。至于以后用到蓝牙的部分,以后再更新吧。
这是这个月最后一更了,这个月本来这应该是最有价值的一篇文章,结果,水平太菜了,没办法,只能做到这里,五一回家玩玩吧,放松下。。。
DeviceListActivity.java
package com.example.bluetooth;import java.util.Set;import android.app.Activity;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Bundle;import android.view.View;import android.view.Window;import android.view.View.OnClickListener;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.ListView;import android.widget.AdapterView.OnItemClickListener;import android.widget.TextView;public class DeviceListActivity extends Activity {private BluetoothAdapter mBtAdapter; private ArrayAdapter<String> mPairedDevicesArrayAdapter; private ArrayAdapter<String> mNewDevicesArrayAdapter; public static String EXTRA_DEVICE_ADDRESS = "device_address"; @Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);//这里设置窗体为不确定进度,因为有progressbarrequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.device_list); //setResult(Activity.RESULT_CANCELED); Button scanButton = (Button) findViewById(R.id.button_scan); scanButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { doDiscovery(); v.setVisibility(View.GONE); } }); mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); ListView pairedListView = (ListView) findViewById(R.id.paired_devices); pairedListView.setAdapter(mPairedDevicesArrayAdapter); pairedListView.setOnItemClickListener(mDeviceClickListener); ListView newDevicesListView = (ListView) findViewById(R.id.new_devices); newDevicesListView.setAdapter(mNewDevicesArrayAdapter); newDevicesListView.setOnItemClickListener(mDeviceClickListener); //注册两个过滤器,用来接收两个广播,一个是搜索到一个可用设备,一个是结束搜索 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); this.registerReceiver(mReceiver, filter); filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); this.registerReceiver(mReceiver, filter); //获取本地蓝牙适配器,把本地已配对设备显示出来 mBtAdapter = BluetoothAdapter.getDefaultAdapter(); Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices(); if (pairedDevices.size() > 0) { findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE); for (BluetoothDevice device : pairedDevices) { mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } else { String noDevices = getResources().getText(R.string.none_paired).toString(); mPairedDevicesArrayAdapter.add(noDevices); }}//搜索private void doDiscovery(){//设置显示setProgressBarIndeterminateVisibility(true); setTitle(R.string.scanning); findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE); //如果正在搜索,取消正在搜索 if (mBtAdapter.isDiscovering()) { mBtAdapter.cancelDiscovery(); } //开始搜索 mBtAdapter.startDiscovery();}//监听器private OnItemClickListener mDeviceClickListener = new OnItemClickListener(){@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {// TODO Auto-generated method stubmBtAdapter.cancelDiscovery();//获取内容,然后把后面17位的MAC地址取出来,连接只需要MAC地址String info = ((TextView) arg1).getText().toString();String address = info.substring(info.length() - 17);//把MAC地址传回到主activity,调用setResult在finish之前传回值Intent intent = new Intent(); intent.putExtra(EXTRA_DEVICE_ADDRESS, address); setResult(Activity.RESULT_OK, intent); finish();}}; //注册一个广播接收,两个不同的接收给出不同的动作private final BroadcastReceiver mReceiver = new BroadcastReceiver(){@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubString action = intent.getAction();if(BluetoothDevice.ACTION_FOUND.equals(action)){//把新发现的设备显示出来BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);if (device.getBondState() != BluetoothDevice.BOND_BONDED) { mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());}}else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){setProgressBarIndeterminateVisibility(false); setTitle(R.string.select_device); if (mNewDevicesArrayAdapter.getCount() == 0) { String noDevices = getResources().getText(R.string.none_found).toString(); mNewDevicesArrayAdapter.add(noDevices); }}}};@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();if (mBtAdapter != null) { mBtAdapter.cancelDiscovery(); }//广播要取消注册,防止内存泄漏this.unregisterReceiver(mReceiver);}}
BluetoothChat.java
package com.example.bluetooth;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.app.ActionBar;import android.app.Activity;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.content.Intent;import android.view.KeyEvent;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.view.inputmethod.EditorInfo;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.EditText;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;public class BluetoothChat extends Activity {//handler处理public static final int MESSAGE_STATE_CHANGE = 1;public static final int MESSAGE_READ = 2;public static final int MESSAGE_WRITE = 3;public static final int MESSAGE_DEVICE_NAME = 4;public static final int MESSAGE_TOAST = 5;public static final String DEVICE_NAME = "device_name"; public static final String TOAST = "toast"; private static final int REQUEST_CONNECT_DEVICE_SECURE = 1; private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2; private static final int REQUEST_ENABLE_BT = 3; private BluetoothAdapter mBluetoothAdapter = null;private BluetoothChatService mChatService = null;private ArrayAdapter<String> mConversationArrayAdapter;private ListView mConversationView; private EditText mOutEditText; private Button mSendButton; private StringBuffer mOutStringBuffer;private String mConnectedDeviceName = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);//本地如果没有蓝牙,提示没有蓝牙mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { Toast.makeText(this, "没有发现蓝牙设备", Toast.LENGTH_LONG).show(); finish(); return; } //蓝牙是否打开了,没有的话,让用户选择是否打开 if (!mBluetoothAdapter.isEnabled()) { Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent, RESULT_FIRST_USER); } else { if (mChatService == null) setupChat(); } }//蓝牙是否可以被检测private void ensureDiscoverable() {// TODO Auto-generated method stubif (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent); }}//信息显示private void setupChat() {// TODO Auto-generated method stubmConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message); mConversationView = (ListView) findViewById(R.id.in); mConversationView.setAdapter(mConversationArrayAdapter); mOutEditText = (EditText) findViewById(R.id.edit_text_out); mOutEditText.setOnEditorActionListener(mWriteListener); mSendButton = (Button) findViewById(R.id.button_send); mSendButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { // Send a message using content of the edit text widget TextView view = (TextView) findViewById(R.id.edit_text_out); String message = view.getText().toString(); sendMessage(message); } });}//EditText+Button响应,软键盘设置private TextView.OnEditorActionListener mWriteListener = new TextView.OnEditorActionListener() { public boolean onEditorAction(TextView view, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) { String message = view.getText().toString(); sendMessage(message); } return true; } };//开始聊天服务@Overrideprotected synchronized void onResume() {// TODO Auto-generated method stubsuper.onResume();if (mChatService != null) { if (mChatService.getState() == BluetoothChatService.STATE_NONE) { mChatService.start(); } }} protected void sendMessage(String message) {// TODO Auto-generated method stub//是否已经连接,没有连接是不能发送信息的if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) { Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show(); return; }//发送信息if (message.length() > 0) { byte[] send = message.getBytes(); mChatService.write(send); mOutStringBuffer.setLength(0); mOutEditText.setText(mOutStringBuffer); }}//停止服务@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();if (mChatService != null) mChatService.stop();}//设置当前连接状态的显示private final void setStatus(int resId) { final ActionBar actionBar = getActionBar(); actionBar.setSubtitle(resId); } private final void setStatus(CharSequence subTitle) { final ActionBar actionBar = getActionBar(); actionBar.setSubtitle(subTitle); } //从BluetoothChatService中读取message,更新UI显示 private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_STATE_CHANGE: switch (msg.arg1) { case BluetoothChatService.STATE_CONNECTED: setStatus(getString(R.string.title_connected_to, mConnectedDeviceName)); mConversationArrayAdapter.clear(); break; case BluetoothChatService.STATE_CONNECTING: setStatus(R.string.title_connecting); break; case BluetoothChatService.STATE_LISTEN: case BluetoothChatService.STATE_NONE: setStatus(R.string.title_not_connected); break; } break; case MESSAGE_WRITE: byte[] writeBuf = (byte[]) msg.obj; // 写信息到缓存 String writeMessage = new String(writeBuf); mConversationArrayAdapter.add("Me: " + writeMessage); break; case MESSAGE_READ: byte[] readBuf = (byte[]) msg.obj; // 从缓存中读信息 String readMessage = new String(readBuf, 0, msg.arg1); mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage); break; case MESSAGE_DEVICE_NAME: // 保存设备名称 mConnectedDeviceName = msg.getData().getString(DEVICE_NAME); Toast.makeText(getApplicationContext(), "Connected to " + mConnectedDeviceName, Toast.LENGTH_SHORT).show(); break; case MESSAGE_TOAST: //打印toast Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), Toast.LENGTH_SHORT).show(); break; } } }; //DeviceActivity的结果返回响应 public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_CONNECT_DEVICE_SECURE: // 返回结果是要求一个连接 if (resultCode == Activity.RESULT_OK) { connectDevice(data, true); } break; case REQUEST_CONNECT_DEVICE_INSECURE: // if (resultCode == Activity.RESULT_OK) { connectDevice(data, false); } break; case REQUEST_ENABLE_BT: // 返回结果是要求打开蓝牙 if (resultCode == Activity.RESULT_OK) { setupChat(); } else { Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show(); finish(); } } } //连接设备 private void connectDevice(Intent data, boolean secure) { String address = data.getExtras() .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS); BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); mChatService.connect(device, secure); } @Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// TODO Auto-generated method stubIntent serverIntent = null; switch (item.getItemId()) { case R.id.secure_connect_scan: // Launch the DeviceListActivity to see devices and do scan serverIntent = new Intent(this, DeviceListActivity.class); startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE); return true; case R.id.insecure_connect_scan: // Launch the DeviceListActivity to see devices and do scan serverIntent = new Intent(this, DeviceListActivity.class); startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE); return true; case R.id.discoverable: // Ensure this device is discoverable by others ensureDiscoverable(); return true; } return false;}}
BluetoothChatService.java
package com.example.bluetooth;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.UUID;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothServerSocket;import android.bluetooth.BluetoothSocket;import android.content.Context;import android.os.Bundle;import android.os.Handler;import android.os.Message;public class BluetoothChatService {private final BluetoothAdapter mAdapter; private final Handler mHandler; private AcceptThread mSecureAcceptThread; private AcceptThread mInsecureAcceptThread; private ConnectThread mConnectThread; private ConnectedThread mConnectedThread; private static final String NAME_SECURE = "BluetoothChatSecure"; private static final String NAME_INSECURE = "BluetoothChatInsecure"; private static final UUID MY_UUID_SECURE = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66"); private static final UUID MY_UUID_INSECURE = UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66"); //设置UI的状态private int mState;public static final int STATE_NONE = 0; // we're doing nothing public static final int STATE_LISTEN = 1; // now listening for incoming connections public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection public static final int STATE_CONNECTED = 3; // now connected to a remote device public BluetoothChatService(Context context, Handler handler) { mAdapter = BluetoothAdapter.getDefaultAdapter(); //UI的动态显示,显示的是状态 mState = STATE_NONE; //信息的处理线程 mHandler = handler; } public int getState() {// TODO Auto-generated method stubreturn mState;}//改变UI的状态显示private void setState(int stateListen) {// TODO Auto-generated method stubmState = stateListen; mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE, stateListen, -1).sendToTarget();}//建立设备之间的连接public void connect(BluetoothDevice device, boolean secure) {// TODO Auto-generated method stubif (mState == STATE_CONNECTING) { if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} } if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} mConnectThread = new ConnectThread(device, secure); mConnectThread.start(); setState(STATE_CONNECTING);}//连接失败的提示private void connectionFailed() { // 把连接失败显示在UI上 Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(BluetoothChat.TOAST, "Unable to connect device"); msg.setData(bundle); mHandler.sendMessage(msg); // 重新开始服务 BluetoothChatService.this.start(); }//连接已建立,保持连接public synchronized void connected(BluetoothSocket socket, BluetoothDevice device, final String socketType) { if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} if (mSecureAcceptThread != null) { mSecureAcceptThread.cancel(); mSecureAcceptThread = null; } if (mInsecureAcceptThread != null) { mInsecureAcceptThread.cancel(); mInsecureAcceptThread = null; } mConnectedThread = new ConnectedThread(socket, socketType); mConnectedThread.start(); // 在UI上把当前连接的设备名显示出来 Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME); Bundle bundle = new Bundle(); bundle.putString(BluetoothChat.DEVICE_NAME, device.getName()); msg.setData(bundle); mHandler.sendMessage(msg); setState(STATE_CONNECTED); }//连接中断private void connectionLost() { // 连接如果中断了,就在UI上提示 Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(BluetoothChat.TOAST, "Device connection was lost"); msg.setData(bundle); mHandler.sendMessage(msg); // 重新开始服务 BluetoothChatService.this.start(); }//开始聊天服务public void start() {// TODO Auto-generated method stubif (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} setState(STATE_LISTEN); // 开始监听socket if (mSecureAcceptThread == null) { mSecureAcceptThread = new AcceptThread(true); mSecureAcceptThread.start(); }}//停止服务public void stop() {// TODO Auto-generated method stubif (mConnectThread != null) { mConnectThread.cancel(); mConnectThread = null; } if (mConnectedThread != null) { mConnectedThread.cancel(); mConnectedThread = null; } if (mSecureAcceptThread != null) { mSecureAcceptThread.cancel(); mSecureAcceptThread = null; } if (mInsecureAcceptThread != null) { mInsecureAcceptThread.cancel(); mInsecureAcceptThread = null; } setState(STATE_NONE);}//监听连接请求线程private class AcceptThread extends Thread{//本地socket private final BluetoothServerSocket mmServerSocket; private String mSocketType; public AcceptThread(boolean secure){ BluetoothServerSocket tmp = null; mSocketType = secure ? "Secure":"Insecure"; // 创建一个新的服务socket try { if (secure) { tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE); } else { tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord( NAME_INSECURE, MY_UUID_INSECURE); } } catch (IOException e) { } mmServerSocket = tmp; } public void run() { setName("AcceptThread" + mSocketType); BluetoothSocket socket = null; //没有建立连接 while (mState != STATE_CONNECTED) { try { socket = mmServerSocket.accept(); } catch (IOException e) { break; } // 建立了连接 if (socket != null) { synchronized (BluetoothChatService.this) { switch (mState) { case STATE_LISTEN: case STATE_CONNECTING: connected(socket, socket.getRemoteDevice(), mSocketType); break; case STATE_NONE: case STATE_CONNECTED: try { socket.close(); } catch (IOException e) { } break; } } } } } public void cancel() { try { mmServerSocket.close(); } catch (IOException e) { } } }//连接线程private class ConnectThread extends Thread { private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; private String mSocketType; public ConnectThread(BluetoothDevice device, boolean secure) { mmDevice = device; BluetoothSocket tmp = null; mSocketType = secure ? "Secure" : "Insecure"; //连接 try { if (secure) { tmp = device.createRfcommSocketToServiceRecord( MY_UUID_SECURE); } else { tmp = device.createInsecureRfcommSocketToServiceRecord( MY_UUID_INSECURE); } } catch (IOException e) { } mmSocket = tmp; } public void run() { setName("ConnectThread" + mSocketType); mAdapter.cancelDiscovery(); //连接到BluetoothSocket try { mmSocket.connect(); } catch (IOException e) { try { mmSocket.close(); } catch (IOException e2) { } connectionFailed(); return; } // 取消连接线程 synchronized (BluetoothChatService.this) { mConnectThread = null; } // 开始连接线程 connected(mmSocket, mmDevice, mSocketType); } public void cancel() { try { mmSocket.close(); } catch (IOException e) { } } } //已连接线程,通过这个线程发送和接收数据private class ConnectedThread extends Thread {private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; //初始化 public ConnectedThread(BluetoothSocket socket, String socketType){ mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; try { //得到输入输出数据流tmpIn = socket.getInputStream();tmpOut = socket.getOutputStream();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} mmInStream = tmpIn; mmOutStream = tmpOut; } //读 public void run(){ byte[] buffer = new byte[1024]; int bytes; //长连接 while (true) { try { bytes = mmInStream.read(buffer); // 把信息反馈给UI界面显示出来 mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer) .sendToTarget(); } catch (IOException e) { connectionLost(); // 重新开始服务 BluetoothChatService.this.start(); break; } } } //写 public void write(byte[] buffer) { try { mmOutStream.write(buffer); mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer) .sendToTarget(); } catch (IOException e) { } } public void cancel() { try { mmSocket.close(); } catch (IOException e) { } } }//写接口public void write(byte[] send) {// TODO Auto-generated method stubConnectedThread r; synchronized (this) { if (mState != STATE_CONNECTED) return; r = mConnectedThread; } r.write(send);}}
- BluetoothChat
- bluetoothChat
- BluetoothChat 基本
- 十三、BluetoothChat之BluetoothChat.java
- BluetoothChat 例程分析
- bluetoothchat的学习
- 蓝牙之-----------BluetoothChat
- ANDROID蓝牙实例---BluetoothChat学习
- Android Mutithreading | BluetoothChat (标题党)
- 十一、BluetoothChat 的运行演示
- 十五、BluetoothChat之BluetoothChatService.java
- 十二、bluetoothChat之AndroidManifest.xml
- 关于BluetoothChat的例子修改!
- BluetoothChat之BluetoothChatService.java解析
- 通过BluetoothChat学习蓝牙操作
- Android SDK自带教程之BluetoothChat
- 四、Bluetoothchat 整体调用关系序列图
- 十四、bluetoothChat之扫描设备DeviceListActivity.java
- (要正式学Linux,发现大一学的c底子太薄,看专业书籍重学。)重写简单的整数中取某一位的算法。
- 内存泄露之Cursor篇
- 如何判断是手机或电脑访问web
- for循环时候可以+2循环
- 如何做到每天写代码?
- BluetoothChat
- 《算法导论》学习笔记(4)——红黑树
- jQuery操作CheckBox的方法(选中,取消,取值)
- fzu - Problem 1759 Super A^B mod C
- 关于servlet配置和struts2配置
- Flex和Servlet结合上传文件
- Linux文件类型和文件扩展名
- java字符串常量池
- JS正则表达式大全