毕业设计--基于安卓的智能小车(二)

界面设计完了,下面开始着重于蓝牙搜索与连接功能。

本文主要参考了SDK中的sample。源码可在oschina.net查看,附上链接:http://www.oschina.net/code/explore/android-2.2-froyo/com/example/android/BluetoothChat

下面介绍一下有关蓝牙的使用。

1. 获取蓝牙权限

     要使用蓝牙先得获取蓝牙权限,在AndroidManifest.xml中添加BLUETOOTH和BLUETOOTH_ADMIN

    
    
2. 获取 BluetoothAdapter类

    可以通过getBluetoothAdapter() 的方法来获取BluetoothAdapter

private BluetoothAdapter mBluetoothAdapter = null;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		if (mBluetoothAdapter == null) {
			Toast.makeText(this, "蓝牙不可用", Toast.LENGTH_LONG).show();
			finish();
			return;
		}
3. 打开蓝牙

    使用 isEnabled() 来检测蓝牙是否打开。调用startActivtyForResult() Intent来打开蓝牙,其中REQUEST_ENABLE_BT定义为一个大于0 的整数。执行该语句会弹出一个对话框,点击允许会返回RESULT_OK ,即打开蓝牙;而点击拒绝则会返回RESULT_CANCLE,也就是不同意打开蓝牙。

private static final int REQUEST_ENABLE_BT = 1;

	if (!mBluetoothAdapter.isEnabled()) {
			Intent OpenBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
			startActivityForResult(OpenBTIntent, REQUEST_ENABLE_BT);
		} 

4. 查找已配对设备

private BluetoothAdapter mBtAdapter;
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
		Set 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());
			}
5. 查询蓝牙设备

    然后通过startDiscovery()方法启动蓝牙设备的搜寻。这是个异步方法,调用的时候立刻就会返回,大约会持续12秒。为了获得搜寻的结果,必须在用户自己的Activity中注册一个BroadcastReceiver

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			String 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);
				}
			}
		}
	};
}
    为ACTION_FOUND设置监听过滤,注册BroadcastReciver

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
		this.registerReceiver(mReceiver, filter);

Activity结束后调用cancelDiscovery()可停止搜索,并注销广播。

protected void onDestroy() {
		super.onDestroy();
		if (mBtAdapter != null) {
			mBtAdapter.cancelDiscovery();
		}
		this.unregisterReceiver(mReceiver);
	}
6. 建立连接

    客户端(Client)作为发起连接的一方,我们可以调用createRfcommSocketToServiceRecord(UUID)来获得蓝牙套接字。蓝牙串口通信,有一个固定的UUID,为00001101-0000-1000-8000-00805F9B34FB。

    通过调用connect()来发起一个连接,这是一个阻塞调用,所以必须新建一个线程。

private static final UUID MY_UUID = UUID
			.fromString("00001101-0000-1000-8000-00805F9B34FB");
private class ConnectThread extends Thread {
		private final BluetoothSocket mmSocket;
		private final BluetoothDevice mmDevice;

		public ConnectThread(BluetoothDevice device) {
			mmDevice = device;
			BluetoothSocket tmp = null;
			try {
				tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
			} catch (IOException e) {
			}
			mmSocket = tmp;
		}

		public void run() {
			setName("ConnectThread");
			mAdapter.cancelDiscovery();
			try {
				mmSocket.connect();
			} catch (IOException e) {
				connectionFailed();
				try {
					mmSocket.close();
				} catch (IOException e2) {
				}
				BluetoothCarService.this.start();
				return;
			}
			synchronized (BluetoothCarService.this) {
				mConnectThread = null;
			}
			connected(mmSocket, mmDevice);
		}

		public void cancel() {
			try {
				mmSocket.close();
			} catch (IOException e) {
			}
		}
	}
建立点击蓝牙列表的监听。搜索蓝牙会消耗大量的资源,所以在准备建立连接之前需要取消搜索。

private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
		public void onItemClick(AdapterView av, View v, int arg2, long arg3) {
			mBtAdapter.cancelDiscovery();
			String info = ((TextView) v).getText().toString();
			String address = info.substring(info.length() - 17);
			Intent intent = new Intent();
			intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
			setResult(Activity.RESULT_OK, intent);
			finish();
		}
	};

7. 管理连接

    连接建立之后,就可以在客户端和蓝牙模块之间进行通讯。通过调用getOutPutStream()来获取OutputStream,通过write(byte[])写入数据。

    因为write(byte[])也为阻塞调用,所以也必须建立一个新的线程。

private class ConnectedThread extends Thread {
		private final BluetoothSocket mmSocket;
		private final OutputStream mmOutStream;

		public ConnectedThread(BluetoothSocket socket) {
			mmSocket = socket;
			OutputStream tmpOut = null;
			try {
				tmpOut = socket.getOutputStream();
			} catch (IOException e) {
			}
			mmOutStream = tmpOut;
		}
		
		public void write(byte[] buffer) {
			try {
				mmOutStream.write(buffer); 
				mHandler.obtainMessage(MainActivity.MESSAGE_WRITE, -1, -1,
						buffer).sendToTarget();
			} catch (IOException e) {
			}
		}

		public void cancel() {
			try {
				mmSocket.close();
			} catch (IOException e) {
			}
		}
	}
}









你可能感兴趣的:(Java,毕业设计,安卓,小车,源码)