Android蓝牙开发经验总结(三)
2015-12-22 19:22
459 查看
前两篇已经写了主要的东西了,已经可以实现请求连接和接受连接的操作了,但是主控制界面的代码还没有贴上,其实Android官方自带的那个界面还是挺不错的,就是一个聊天的界面,但是我们项目需求的话用不到那样的,只是需要用到一个数据传输,而不是那种聊天式的界面。所以我改了一下。
由于我们的项目需要用到到的是Unity3D,所以有调用U3D的接口,但是这需求是很特别的,一般来说是用不到这些的,所以我把它注释掉了,但是也算是为了防止以后有可能再次用到,就先把它放这上面了。
这个类里面定义了一个Handler对象,用来进行进程之间数据的传递,上一篇里用到的handler就是从这里面传递过去的,定义AcceptThread和ConnectThread线程的时候都将Handler对象作为构造函数的参数传递了过去,这样在子线程中发生了什么就可以通过Handler向主线程发送提示,比如连接突然断开,就可以通过Handler发送消息告知主线程,主线程这时可以弹出一个Toast来告知用户连接已经断开。
另外需要注意的是
这个方法是官方demo里的,我对这类主题窗口类的方法还不是很了解,所以我就在网上查了一下,这个类是用来显示自定义的Title的,我们Android系统的主题里面给我们定义了一些Title,但这些Title的功能往往不适合我们的项目,所以我们需要自定义一个Title,这个方法就是用来告知系统我要用自己定义的一个Title了,就直接取代了系统的Title了。至于Title的样式则需要在XML文件中自己来定义啦。
最后再讲一下蓝牙的断开,蓝牙连接是可以了,但是要是想在程序里断开,官方demo里是没有这个功能的,于是我就想着怎么能给用户提供一个断开的方法呢,总不能总是让用户一直连着,或者需要用户关闭程序或者关闭蓝牙才能实现这样的需求吧。
后来还真是找到了办法,思路就是断开Socket,在ConnectedThread里面,我们可以看到连接之后传过来的Socket对象,就是它,蓝牙之间通信就是像网络通信一样用的是Socket。所以,我们只要断开了Socket,两个蓝牙设备之间的通信就会断开,于是,就可以用以下代码了。
因为前面的线程里,我已经把ConnectedThread的对象存入到了Constant中,现在只需要通过getConnectedThread()这个方法就能获得,获得之后判断是否为空,如果不为空的话,就调用mConnectedThread对象里的cancle方法,在这个方法里会执行关闭Socket的操作,这样就算是断开了,断开之后将mConnceted设为空即可。
蓝牙的部分基本上就是这些了!有什么问题可以找我共同探讨沟通^_^。
[code]public class BluetoothControl extends Activity { private String address; private String Devicename; private String TAG = "BluetoothControl"; private boolean D = true; private BluetoothAdapter mBluetoothAdapter; private Button scan, discoverable; private TextView mTitle; private AcceptThread mAcceptThread; private ConnectThread mConnectThread; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.activity_bluetoothcontrol); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title); init(); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); } // 对需要使用到的资源进行初始化 private void init() { mTitle = (TextView) this.findViewById(R.id.title_left_text); mTitle.setText("未连接"); // 获得系统默认蓝牙适配器 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { Toast.makeText(getApplicationContext(), getResources().getString(R.string.none_bluetooth), Toast.LENGTH_LONG).show(); finish(); } else { openBluetooth(); } scan = (Button) this.findViewById(R.id.scan); discoverable = (Button) this.findViewById(R.id.discoverable); scan.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub // 跳转到DeviceList类 Intent intent = new Intent(BluetoothControl.this, DeviceList.class); startActivityForResult(intent, Constant.REQUEST_CONNECT_DEVICE); scan.setEnabled(false); discoverable.setEnabled(false); } }); discoverable.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub Intent discoverableIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra( BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120); startActivity(discoverableIntent); mTitle.setText("正在等待连接"); mAcceptThread = Constant.getAcceptThread(); if (mAcceptThread == null) { mAcceptThread = new AcceptThread(mHandler); mAcceptThread.start(); Constant.setAcceptThread(mAcceptThread); } else if (mAcceptThread != null) { mAcceptThread = null; mAcceptThread = new AcceptThread(mHandler); mAcceptThread.start(); Constant.setAcceptThread(mAcceptThread); } } }); } private void openBluetooth() {// 打开蓝牙的方法 if (!mBluetoothAdapter.isEnabled()) { Intent enableIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent, 2); } } public void onActivityResult(int requestCode, int resultCode, Intent data) { if (D) Log.d(TAG, "onActivityResult " + resultCode); switch (requestCode) { case Constant.REQUEST_CONNECT_DEVICE: if (resultCode == Activity.RESULT_OK) { address = data.getExtras().getString( DeviceList.EXTRA_DEVICE_ADDRESS); Log.i(TAG, address); BluetoothDevice device = mBluetoothAdapter .getRemoteDevice(address); mConnectThread = Constant.getConnectThread(); mConnectThread = new ConnectThread(mHandler, device); mConnectThread.start(); Constant.setConnectThread(mConnectThread); mTitle.setText("正在连接" + device.getName()); } break; case Constant.REQUEST_ENABLE_BT: if (resultCode == Activity.RESULT_OK) { openBluetooth(); } else { Log.d(TAG, "BT not enabled"); Toast.makeText(this, "蓝牙不可用", Toast.LENGTH_SHORT).show(); finish(); } } } private final Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case Constant.MESSAGE_STATE_CHANGE: if (D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1); // 显示现在处在的状态 // switch (msg.arg1) { // case BluetoothControlService.STATE_CONNECTED: // mTitle.setText(R.string.title_connected_to); // mTitle.append(Devicename); // break; // case BluetoothControlService.STATE_CONNECTING: // mTitle.setText(R.string.title_connecting); // break; // case BluetoothControlService.STATE_LISTEN: // mTitle.setText(R.string.title_not_connected); // break; // case BluetoothControlService.STATE_NONE: // mTitle.setText(R.string.title_not_connected); // break; // } // break; case Constant.MESSAGE_READ: // 读取获得的信息 byte[] readBuf = (byte[]) msg.obj; String readMessage = new String(readBuf, 0, msg.arg1); System.out.println("readMessage" + readMessage); // UnityPlayer.UnitySendMessage(readMessage.substring(0, // readMessage.indexOf(",")), readMessage.substring( // readMessage.indexOf(",") + 1, // readMessage.lastIndexOf(",")), readMessage // .substring(readMessage.lastIndexOf(",") + 1)); break; case Constant.MESSAGE_DEVICE_NAME: // 获得连接到的设备名字,显示 Devicename = msg.getData().getString(Constant.DEVICE_NAME); Toast.makeText(getApplicationContext(), "连接到:" + Devicename, Toast.LENGTH_SHORT).show(); mTitle.setText("已连接到:" + Devicename); // UnityPlayer.UnitySendMessage("BluetoothObjects", // "BluetoothConnected", ""); finish(); break; case Constant.MESSAGE_TOAST: Toast.makeText(getApplicationContext(), msg.getData().getString(Constant.TOAST), Toast.LENGTH_SHORT).show(); mTitle.setText("未连接"); scan.setEnabled(true); discoverable.setEnabled(true); // UnityPlayer.UnitySendMessage("BluetoothObjects", // "BluetoothDisconnected", ""); break; } } }; }
由于我们的项目需要用到到的是Unity3D,所以有调用U3D的接口,但是这需求是很特别的,一般来说是用不到这些的,所以我把它注释掉了,但是也算是为了防止以后有可能再次用到,就先把它放这上面了。
这个类里面定义了一个Handler对象,用来进行进程之间数据的传递,上一篇里用到的handler就是从这里面传递过去的,定义AcceptThread和ConnectThread线程的时候都将Handler对象作为构造函数的参数传递了过去,这样在子线程中发生了什么就可以通过Handler向主线程发送提示,比如连接突然断开,就可以通过Handler发送消息告知主线程,主线程这时可以弹出一个Toast来告知用户连接已经断开。
另外需要注意的是
[code] requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
这个方法是官方demo里的,我对这类主题窗口类的方法还不是很了解,所以我就在网上查了一下,这个类是用来显示自定义的Title的,我们Android系统的主题里面给我们定义了一些Title,但这些Title的功能往往不适合我们的项目,所以我们需要自定义一个Title,这个方法就是用来告知系统我要用自己定义的一个Title了,就直接取代了系统的Title了。至于Title的样式则需要在XML文件中自己来定义啦。
最后再讲一下蓝牙的断开,蓝牙连接是可以了,但是要是想在程序里断开,官方demo里是没有这个功能的,于是我就想着怎么能给用户提供一个断开的方法呢,总不能总是让用户一直连着,或者需要用户关闭程序或者关闭蓝牙才能实现这样的需求吧。
后来还真是找到了办法,思路就是断开Socket,在ConnectedThread里面,我们可以看到连接之后传过来的Socket对象,就是它,蓝牙之间通信就是像网络通信一样用的是Socket。所以,我们只要断开了Socket,两个蓝牙设备之间的通信就会断开,于是,就可以用以下代码了。
[code] Button off = (Button) findViewById(R.id.off); off.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub mConnectedThread = Constant.getConnectedThread(); if (mConnectedThread != null) { mConnectedThread.cancel(); mConnectedThread = null; Constant.setConnectedThread(mConnectedThread); } finish(); } });
因为前面的线程里,我已经把ConnectedThread的对象存入到了Constant中,现在只需要通过getConnectedThread()这个方法就能获得,获得之后判断是否为空,如果不为空的话,就调用mConnectedThread对象里的cancle方法,在这个方法里会执行关闭Socket的操作,这样就算是断开了,断开之后将mConnceted设为空即可。
蓝牙的部分基本上就是这些了!有什么问题可以找我共同探讨沟通^_^。
相关文章推荐
- 「译」Android最佳实践指南——GitHub Star 7000+
- Android的Uri与Path的区别
- Android开发之第一个小项目--我的MP3播放器之后台服务Service的实现(四)
- android中常见声音操作方式(Ringtone,SoundPool,MediaPlayer)小结
- Android之动画Animation的使用
- 【Android】Facebook获取 user location
- Android ORMLite数据库简介
- Android5.0 Battery开发(一)
- (转)Android如何编程设置APP安装位置(外部存储或内部存储)?
- android-----WeakReference 在android中的应用
- 最新AndroidStudio使用教程
- 怎样使android的view动画循环弹动
- MPAndroidChart 教程:动画 Animations(十)
- Android中的RecyclerView的使用(一)
- Android实时视频采集方案
- Face Detection using OpenCV Haarcascades in Android
- Android关闭键盘时的一个小问题
- Android5.0如何监听USB插拔
- Android自定义view控件
- 读Android学Java基础之动机