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);}}



      


0 0
原创粉丝点击