原本晚上回到家是没抱那么大希望的,只是想在研究周末的那段蓝牙程序之前把手机与PC的蓝牙程序项目导入一下。导入过程很顺利,PC上的程序是周日就导入好了的,手机程序今天下班才刚刚导入。手机的项目导入之后Eclipse居然一个错误都没有,心想要不试试吧,没想一试就成了。
哈!
这事儿
一定要嘚
瑟一下 ^_^
原本晚上回到家是没抱那么大希望的,只是想在研究周末的那段蓝牙程序之前把手机与PC的蓝牙程序项目导入一下。导入过程很顺利,PC上的程序是周日就导入好了的,手机程序今天下班才刚刚导入。手机的项目导入之后Eclipse居然一个错误都没有,心想要不试试吧,没想一试就成了。
哈!
这事儿
一定要嘚
瑟一下 ^_^
前阵子调通了google的蓝牙聊天例程,最近要研究源代码,于是在网上找了一篇文章,一段一段对着代码浏览下来
——尼玛, 这个安卓的范例不简单啊,光把文章看下来就不容易了,代码还是自己琢磨。
这是文章链接: http://www.aichengxu.com/view/28484
以下是全文引用,做了一些修改:
安卓自带示例BluetoothChat详解,有需要的朋友可以参考下。
安装好安卓SDK后,新建安卓项目会有一个Android Sample Project的选项,里面都是安卓自带的示例项目,其中BluetoothChat是利用蓝牙进行通信的实例。
BluetoothChat项目src下共有三个类,分别为:
BluetoothChat是主窗体,通俗来讲就是程序刚刚运行时用户所见到的窗体。具体调用过程如下:
1: public void onCreate(Bundle savedInstanceState)
2: {
3: super.onCreate(savedInstanceState);
4: if (D)
5: Log.e(TAG, "+++ ON CREATE +++");
6:
7: // 设置窗体
8: setContentView(R.layout.main);
9: // 初始化蓝牙适配器
10: mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
11: // 如果蓝牙适配器不存在,则退出程序
12: if (mBluetoothAdapter == null)
13: {
14: Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
15: finish();
16: return;
17: }
18: }
1: public void onStart()
2: {
3: super.onStart();
4: if (D)
5: {
6: Log.e(TAG, "++ ON START ++");
7: }
8:
9: // If Bluetooth is not on, request that it be enabled.
10: // setupChat() will then be called during onActivityResult
11: // 判断蓝牙适配器是否打开
12: if (!mBluetoothAdapter.isEnabled())
13: {
14: // 如果蓝牙适配器没有打开,则创建一个Intent,将REQUEST_ENABLE_BT消息发送给
15: // onActiveResult函数
16: Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
17: startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
18:
19: }
20: else
21: // Otherwise, setup the chat session
22: {
23: // 如果蓝牙适配器未打开,则执行setupChat
24: if (mChatService == null)
25: {
26: setupChat();
27: }
28: }
29: }
当用户选择搜索设备时进入scan分支,通过Intent发送 REQUEST_CONNECT_DEVICE消息给onActivityResult()函数,并且初始化DeviceListActivity类的对象,DeviceListActivity类即是src下的一个类,主要用于实现设备搜索窗体,显示已配对设备和搜索到的设备。
onActivityResult()函数接下来会获得到已搜索到设备的MAC地址等信息,并且通过初始化BluetoothChatService类的对象mChatService来建立连接。
1: public boolean onOptionsItemSelected(MenuItem item)
2: {
3: Intent serverIntent = null;
4: switch (item.getItemId())
5: {
6: case R.id.secure_connect_scan:
7: // Launch the DeviceListActivity to see devices and do scan
8: serverIntent = new Intent(this, DeviceListActivity.class);
9: startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
10: return true;
11: case R.id.insecure_connect_scan:
12: // Launch the DeviceListActivity to see devices and do scan
13: serverIntent = new Intent(this, DeviceListActivity.class);
14: startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE);
15: return true;
16: case R.id.discoverable:
17: // Ensure this device is discoverable by others
18: ensureDiscoverable();
19: return true;
20: }
21: return false;
22: }
1: public void onActivityResult(int requestCode, int resultCode, Intent data)
2: {
3: if (D)
4: Log.d(TAG, "onActivityResult " + resultCode);
5: switch (requestCode)
6: {
7: case REQUEST_CONNECT_DEVICE_SECURE:
8: // When DeviceListActivity returns with a device to connect
9: // 当用户点击设备列表上的按钮时,触发下面的代码
10: if (resultCode == Activity.RESULT_OK)
11: {
12: connectDevice(data, true);
13: }
14: break;
15: /** Other codes*/
16: }
17: }
18:
19: private void connectDevice(Intent data, boolean secure)
20: {
21: // Get the device MAC address
22: String address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
23: // Get the BluetoothDevice object
24: BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
25: // Attempt to connect to the device
26: mChatService.connect(device, secure);
27: }
28:
29: // BluetoothChatService类成员函数
30: public synchronized void connect(BluetoothDevice device, boolean secure)
31: {
32: if (D){Log.d(TAG, "connect to: " + device);}
33:
34: // Cancel any thread attempting to make a connection
35: if (mState == STATE_CONNECTING)
36: {
37: if (mConnectThread != null)
38: {
39: mConnectThread.cancel();
40: mConnectThread = null;
41: }
42: }
43:
44: // Cancel any thread currently running a connection
45: if (mConnectedThread != null)
46: {
47: mConnectedThread.cancel();
48: mConnectedThread = null;
49: }
50:
51: // Start the thread to connect with the given device
52: mConnectThread = new ConnectThread(device, secure);
53: mConnectThread.start();
54: setState(STATE_CONNECTING);
55: }
1: /** ConnectThread 构造函数*/
2: public ConnectThread(BluetoothDevice device, boolean secure)
3: {
4: mmDevice = device;
5: /** 蓝牙客户端socket*/
6: BluetoothSocket tmp = null;
7: mSocketType = secure ? "Secure" : "Insecure";
8:
9: // Get a BluetoothSocket for a connection with the given BluetoothDevice
10: try
11: {
12: // 创建蓝牙客户端socket
13: if (secure) {tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);}
14: else {tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE);}
15: }
16: catch (IOException e)
17: {
18: Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
19: }
20: mmSocket = tmp;
21: } // end ConnectThread
1: // ConnectThread类run()函数
2: public void run()
3: {
4: Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
5: setName("ConnectThread" + mSocketType);
6:
7: // Always cancel discovery because it will slow down a connection
8: mAdapter.cancelDiscovery();
9:
10: // Make a connection to the BluetoothSocket
11: try
12: {
13: // This is a blocking call and will only return on a
14: // successful connection or an exception
15: // 连接目标手机,此函数将会阻塞,直至连接成功或异常抛出
16: mmSocket.connect();
17: }
18: catch (IOException e)
19: {
20: // Close the socket
21: try
22: {
23: mmSocket.close();
24: }
25: catch (IOException e2)
26: {
27: Log.e(TAG, "unable to close() " + mSocketType +
28: " socket during connection failure", e2);
29: }
30: connectionFailed();
31: return;
32: } // end Run
1: // BluetoothChatService类start()函数
2: public synchronized void start()
3: {
4: if (D)
5: Log.d(TAG, "start");
6:
7: // Cancel any thread attempting to make a connection
8: if (mConnectThread != null)
9: {
10: mConnectThread.cancel();
11: mConnectThread = null;
12: }
13:
14: // Cancel any thread currently running a connection
15: if (mConnectedThread != null)
16: {
17: mConnectedThread.cancel();
18: mConnectedThread = null;
19: }
20:
21: setState(STATE_LISTEN);
22:
23: // Start the thread to listen on a BluetoothServerSocket
24: if (mSecureAcceptThread == null)
25: {
26: mSecureAcceptThread = new AcceptThread(true);
27: mSecureAcceptThread.start();
28: }
29: if (mInsecureAcceptThread == null)
30: {
31: mInsecureAcceptThread = new AcceptThread(false);
32: mInsecureAcceptThread.start();
33: }
34: } // end start
1: // AcceptThread构造函数
2: public AcceptThread(boolean secure)
3: {
4: BluetoothServerSocket tmp = null;
5: mSocketType = secure ? "Secure" : "Insecure";
6:
7: // Create a new listening server socket
8: try
9: {
10: // 创建服务器socket
11: if (secure) {tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE);}
12: else {tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE, MY_UUID_INSECURE);}
13: }
14: catch (IOException e)
15: {
16: Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);
17: }
18: mmServerSocket = tmp;
19: } // end AcceptThread
1: // AcceptThread类run()函数
2: public void run()
3: {
4: if (D){ Log.d(TAG, "Socket Type: " + mSocketType + "BEGIN mAcceptThread" + this);}
5:
6: setName("AcceptThread" + mSocketType);
7: BluetoothSocket socket = null;
8:
9: // Listen to the server socket if we're not connected
10: while (mState != STATE_CONNECTED)
11: {
12: try
13: {
14: // This is a blocking call and will only return on a
15: // successful connection or an exception
16: socket = mmServerSocket.accept();
17: }
18: catch (IOException e)
19: {
20: Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e);
21: break;
22: }
23:
24: // If a connection was accepted
25: if (socket != null)
26: {
27: synchronized (BluetoothChatService.this)
28: {
29: switch (mState)
30: {
31: case STATE_LISTEN:
32: case STATE_CONNECTING:
33: // Situation normal. Start the connected thread.
34: connected(socket, socket.getRemoteDevice(), mSocketType);
35: break;
36: case STATE_NONE:
37: case STATE_CONNECTED:
38: // Either not ready or already connected. Terminate new socket.
39: try
40: {
41: socket.close();
42: }
43: catch (IOException e)
44: {
45: Log.e(TAG, "Could not close unwanted socket", e);
46: }
47: break;
48: }
49: }
50: }
51: }
52:
53: if (D){Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);}
54:
55: } // end run
1: public void run()
2: {
3: Log.i(TAG, "BEGIN mConnectedThread");
4: byte[] buffer = new byte[1024];
5: int bytes;
6:
7: // Keep listening to the InputStream while connected
8: while (true)
9: {
10: try
11: {
12: // Read from the InputStream
13: bytes = mmInStream.read(buffer);
14:
15: // Send the obtained bytes to the UI Activity
16: mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
17: .sendToTarget();
18: }
19: catch (IOException e)
20: {
21: Log.e(TAG, "disconnected", e);
22: connectionLost();
23: // Start the service over to restart listening mode
24: BluetoothChatService.this.start();
25: break;
26: }
27: }
28: } // end run
主要的数据通信过程已经分析完,另外还有点击发送按钮发送消息时的具体调用过程。
1: private void sendMessage(String message)
2: {
3: // Check that we're actually connected before trying anything
4: if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED)
5: {
6: Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
7: return;
8: }
9:
10: // Check that there's actually something to send
11: if (message.length() > 0)
12: {
13: // Get the message bytes and tell the BluetoothChatService to write
14: byte[] send = message.getBytes();
15: mChatService.write(send);
16:
17: // Reset out string buffer to zero and clear the edit text field
18: mOutStringBuffer.setLength(0);
19: mOutEditText.setText(mOutStringBuffer);
20: }
21: } // end of sendMessage(String message)
MARK:一边修改这篇文章,一边看代码,搞了一晚上没搞完~~~2015.12.19
MARK:历史的车轮滚滚向前,好不容易看完了文章,已经到了公元2015年12月20日~~
这件事情烦人好久了,大约是从今年7月份的时候,开始要把CAN总线的数据发到手机上,大约就是下面这个图的样子。软件的基本原理是一个Server,一个Client。在原型阶段,Server由一台接入CAN总线的PC充当,Client是安卓手机。基本框架是很容易定下来的,因为没有什么冗余的技术方案可选。原型Server的蓝牙实现依赖于BlueCove,Client中的蓝牙实现使用安卓提供的蓝牙开发包——这只是最终的目标,逐步实现得从手机对手机的蓝牙通讯开始。于是从那时候开始在网上找啊找,找手机蓝牙通讯的例程。
其实安卓自带的BluetoothChat例程不是没试过,而是因为缺少安卓经验,一看导入项目这么多错误,觉得要调试肯定很困难了,干脆找一个新的例程来。于是就陷入了死循环,直到周四看到导入的BluetoothChat项目里引用的是1.5的SDK包,觉得不对劲,想看看换一个高版本的SDK包进来看看,终于调出了一个可以编译版本,但是还是没有运行,原文如下:
http://tripsina.com/%E5%BF%97/bluetoothchat/
项目和源代码导入很简单,新建项目,选择Android Project from Existing Code就可以了。
源代码导入之后项目目录里面一连串的红XX,吓人的很,都不敢打开代码文件。不光错误很多,连gen目录下也没有生成R.java文件。排错的基本次序是这么来的,先把SDK从1.5换到了16,然后到AndroidManifest文件里指定目标Android的版本,基本上就是这段代码:
1: <uses-sdk android:minSdkVersion="16"
2: android:targetSdkVersion="16"
3: android:maxSdkVersion="16"/>
不知道什么原因,我使用的例程代码一开始的代码是这样的,这一行就删除了,因为在Manifest的对应图形编辑窗口中,这一行代码对应着Unknown XML Attribute:
1: <uses-sdk minSdkVersion=”6”>
做完上面几步之后就没有任何红叉叉了,分别下载到2个手机上,运行,结果还算满意,接下来就得研读代码了。
Recent Comments