码迷,mamicode.com
首页 > 移动开发 > 详细

android蓝牙模块

时间:2015-11-17 19:21:20      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:android   蓝牙模块   

新建一个工程“blt”。

-----------------------MainActivity.java

package com.example.blt;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {

	static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
	// 适配器
	private BluetoothAdapter blueadapter = null;
	// 设备地址列表
	private List<String> deviceList = new ArrayList<String>();
	private ArrayAdapter<String> adapter;
	private ListView deviceListview;
	private boolean isFind = false;

	// 存储设备信息
	private List<UserDriver> userDrivers = new ArrayList<UserDriver>();

	// 连接设备
	public static BluetoothSocket btSocket;
	int useIndex;

	ProgressDialog pDialog;
	private long exitTime = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		pDialog = new ProgressDialog(MainActivity.this);
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		setView();
		setBluetooth();

	}

	// 设置列表信息
	private void setView() {

		adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1, deviceList);
		deviceListview = (ListView) findViewById(R.id.listView1);
		deviceListview.setAdapter(adapter);
		deviceListview.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				useIndex = position;
				// TODO Auto-generated method stub
				new AlertDialog.Builder(MainActivity.this)
						.setTitle("提示框")
						.setMessage(
								"确认连接?"
										+ userDrivers.get(useIndex).DeviceAdapter
												.getName())
						.setPositiveButton("确定",
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int which) {
										// 判断是否需要配对
										switch (userDrivers.get(useIndex).DeviceAdapter
												.getBondState()) {
										case BluetoothDevice.BOND_BONDING:
											Log.d("BlueToothTestActivity",
													"正在配对......");
											break;
										case BluetoothDevice.BOND_BONDED:
											Log.d("BlueToothTestActivity",
													"完成配对");
											LinkDevice();
											break;
										case BluetoothDevice.BOND_NONE:
											Log.d("BlueToothTestActivity",
													"未配对");
											ApadeDevice();
										default:
											break;
										}
									}
								})
						.setNegativeButton("取消",
								new DialogInterface.OnClickListener() {

									@Override
									public void onClick(DialogInterface dialog,
											int which) {
										// TODO Auto-generated method stub
										
									}
								}).show();
			}
		});

	}

	/**
	 * 第一步,设置蓝牙开启
	 */
	private void setBluetooth() {
		blueadapter = BluetoothAdapter.getDefaultAdapter();

		if (blueadapter != null) { // Device support Bluetooth
			// 确认开启蓝牙
			if (!blueadapter.isEnabled()) {
				// 请求用户开启
				Intent intent = new Intent(
						BluetoothAdapter.ACTION_REQUEST_ENABLE);
				startActivityForResult(intent, RESULT_FIRST_USER);
				// 使蓝牙设备可见,方便配对
				// Intent in = new Intent(
				// BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
				// in.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,
				// 200);
				// startActivity(in);
				// 直接开启,不经过提示
				blueadapter.enable();
			}
			findAvalibleDevice();
		} else { // Device does not support Bluetooth

			AlertDialog.Builder dialog = new AlertDialog.Builder(this);
			dialog.setTitle("硬件错误");
			dialog.setMessage("未找到蓝牙设备");

			dialog.setNegativeButton("取消",
					new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							
						}
					});
			dialog.show();
		}
	}

	/**
	 * 第二步,搜索设备
	 */
	private void findAvalibleDevice() {
		// 获取可配对蓝牙设备
		Set<BluetoothDevice> device = blueadapter.getBondedDevices();

		userDrivers.clear();
		deviceList.clear();
		adapter.notifyDataSetChanged();
		if (device.size() > 0) { // 存在已经配对过的蓝牙设备
			for (Iterator<BluetoothDevice> it = device.iterator(); it.hasNext();) {
				BluetoothDevice btd = it.next();
				userDrivers.add(new UserDriver(btd, true));
				deviceList.add(btd.getName() + "(已配对)\n" + btd.getAddress());
				adapter.notifyDataSetChanged();
			}
			// 搜索没有配对的设备。

		}
		// else { // 不存在已经配对过的蓝牙设备
		// deviceList.add("No can be matched to use bluetooth");
		// adapter.notifyDataSetChanged();
		// }
	}

	/**
	 * 第三步。查找其他
	 */
	public void FindOthers() {
		// 如果正在搜索,就先取消搜索
		if (blueadapter.isDiscovering()) {
			blueadapter.cancelDiscovery();
		}
		if (isFind)
			return;
		isFind = true;
		findAvalibleDevice();
		// 注册用以接收到已搜索到的蓝牙设备的receiver
		IntentFilter mFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
		registerReceiver(mReceiver, mFilter);
		// 注册搜索完时的receiver
		mFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
		registerReceiver(mReceiver, mFilter);

		setProgressBarIndeterminateVisibility(true);
		setTitle("正在扫描....");
		// 开始搜索蓝牙设备,搜索到的蓝牙设备通过广播返回
		blueadapter.startDiscovery();
	}

	/**
	 * 广播处理
	 **/
	private BroadcastReceiver mReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			// TODO Auto-generated method stub

			String action = intent.getAction();
			// 获得已经搜索到的蓝牙设备
			if (action.equals(BluetoothDevice.ACTION_FOUND)) {
				BluetoothDevice device = intent
						.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				// 搜索到的不是已经绑定的蓝牙设备
				if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
					// 显示在TextView上
					userDrivers.add(new UserDriver(device, false));
					deviceList.add(device.getName() + "(未配对)\n"
							+ device.getAddress());
					adapter.notifyDataSetChanged();
				}
				// 搜索完成
			} else if (action
					.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
				setProgressBarIndeterminateVisibility(false);
				setTitle("扫描结束");
				unReceive();
				isFind = false;
			}
		}

	};

	/**
	 * 关闭注册事件
	 */
	private void unReceive() {
		try {
			// 解除注册
			unregisterReceiver(mReceiver);
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	/**
	 * 配对并且连接设备
	 */
	private void ApadeDevice() {
		try {
			Method createBondMethod = BluetoothDevice.class
					.getMethod("createBond");
			Log.d("BlueToothTestActivity", "开始配对1");
			try {
				createBondMethod
						.invoke(userDrivers.get(useIndex).DeviceAdapter);
				Log.d("BlueToothTestActivity", "开始配对2");
				new Thread(new Runnable() {

					@Override
					public void run() {
						// TODO Auto-generated method stub
						BluetoothDevice bDevice = userDrivers.get(useIndex).DeviceAdapter;
						while (true) {
							try {
								Thread.sleep(1000);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							// 判断配对状态,更新列表信息。
							if (bDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
								Log.d("BlueToothTestActivity", "成功配对");
								userDrivers.get(useIndex).IsConnected = true;
								deviceList.set(useIndex, bDevice.getName()
										+ "(已配对)\n" + bDevice.getAddress());
								Log.d("BlueToothTestActivity", "成功配对2");
								handler2.sendMessage(new Message());
								break;
							}
						}
					}
				}).start();

			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch
				// block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch
				// block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch
				// block
				e.printStackTrace();
			}
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch
			// block
			e.printStackTrace();
		}
	}

	@SuppressLint("HandlerLeak")
	Handler handler2 = new Handler() {
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			adapter.notifyDataSetChanged();
			LinkDevice();
		}
	};

	private void LinkDevice() {
		pDialog.setMessage("连接中....");
		pDialog.show();
		new Thread(new Runnable() {

			@Override
			public void run() { //
				// TODO Auto-generated //
				// connect(userDrivers.get(useIndex).DeviceAdapter);
				Message msg = new Message();
				Bundle data = new Bundle();

				UUID uuid = UUID.fromString(SPP_UUID);
				try {
					if (btSocket != null && btSocket.isConnected())
						btSocket.close();
					btSocket = userDrivers.get(useIndex).DeviceAdapter
							.createRfcommSocketToServiceRecord(uuid);
					Log.d("BlueToothTestActivity", "开始连接...");
					btSocket.connect();
					if (btSocket.isConnected()) {
						data.putString("Request", "连接成功");
					} else {
						data.putString("Request", "连接失败");
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					data.putString("Request", "发生错误");
				}
				msg.setData(data);
				handler.sendMessage(msg);
			}
		}).start();
	}

	@SuppressLint("HandlerLeak")
	Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			Bundle data = msg.getData();
			String valString = data.getString("Request");
			if (valString.equals("连接成功")) {
				Intent intent = new Intent(MainActivity.this, Connected.class);
				startActivity(intent);
			} else {
				Toast.makeText(getApplicationContext(), valString,
						Toast.LENGTH_SHORT).show(); //
			}
			if (pDialog.isShowing())
				pDialog.cancel();
		}
	};

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK
				&& event.getAction() == KeyEvent.ACTION_DOWN) {
			if ((System.currentTimeMillis() - exitTime) > 2000) {
				Toast.makeText(getApplicationContext(), "再按一次退出程序",
						Toast.LENGTH_SHORT).show();
				exitTime = System.currentTimeMillis();
			} else {
				if (btSocket != null && btSocket.isConnected())
					try {
						btSocket.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				finish();
				System.exit(0);
			}
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		unReceive();
		super.onDestroy();
	}

	@Override
	public 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;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.item1) {
			// 搜索设备
			FindOthers();
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}

界面XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.blt.MainActivity" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >

    </ListView>

</RelativeLayout>

-------------------------------------------蓝牙的发送和接收!Connected窗体

package com.example.blt;

import java.io.InputStream;
import java.io.OutputStream;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

public class Connected extends Activity {

	String sendData = "";
	boolean _runThread = true;
	private TextView mResults;

	Thread thread = new Thread(new Runnable() {

		@Override
		public void run() {
			Log.d("BlueToothTestActivity", "启动线程");
			String bufferString = "";
			// TODO Auto-generated method stub
			while (_runThread) {
				if (sendData != "") {
					Log.d("BlueToothTestActivity", "准备数据" + sendData);
					try {
						OutputStream outputStream = MainActivity.btSocket
								.getOutputStream();
						Log.d("BlueToothTestActivity", "获得输出流");
						outputStream.write(sendData.getBytes());
						Log.d("BlueToothTestActivity", "写入输出流");
						bufferString = "send:" + sendData;
						Log.d("BlueToothTestActivity", "已经发送");
					} catch (Exception e) {
						// TODO: handle exception
						Log.d("BlueToothTestActivity", "发送错误");
					}
					sendData = "";
				}
				try {
					InputStream inputStream = MainActivity.btSocket
							.getInputStream();
					int count = inputStream.available();
					if (count > 0) {
						byte[] b = new byte[count];
						inputStream.read(b);

						bufferString = "rece:" + new String(b);
					}
				} catch (Exception e) {
					// TODO: handle exception
				}

				if (bufferString == null || bufferString == "")
					continue;
				Message msg = new Message();
				Bundle data = new Bundle();
				data.putString("Request", bufferString);
				msg.setData(data);
				handler.sendMessage(msg);
				bufferString = "";
			}
		}
	});

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_connected);
		mResults = (TextView) findViewById(R.id.axis_x);
		mResults.setMovementMethod(ScrollingMovementMethod.getInstance());
		mResults.setText("日志信息");
		thread.start();
		((Button) findViewById(R.id.BtnSend))
				.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						// TODO Auto-generated method stub
						Log.d("BlueToothTestActivity", "点击按钮");
						sendData = ((EditText) findViewById(R.id.editText1))
								.getText().toString();
					}
				});
		((EditText) findViewById(R.id.editText1))
				.setOnEditorActionListener(new OnEditorActionListener() {

					@Override
					public boolean onEditorAction(TextView v, int actionId,
							KeyEvent event) {
						// TODO Auto-generated method stub
						Log.d("BlueToothTestActivity", "键盘发送");
						sendData = ((EditText) findViewById(R.id.editText1))
								.getText().toString();
						return false;
					}
				});
	}

	// 通信模块

	@SuppressLint("HandlerLeak")
	Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			Bundle data = msg.getData();
			String valString = data.getString("Request");
			mResults.setText(mResults.getText().toString() + "\r\n" + valString);
			/*
			 * Log.d("BlueToothTestActivity", mResults.getScrollX() + "," +
			 * mResults.getScrollY());
			 */
		}
	};

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {

		if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
			// do something...
			_runThread = false;
			Log.d("BlueToothTestActivity", "返回了");
		}
		return super.onKeyDown(keyCode, event);
	}

	/*
	 * private byte[] getHexBytes(String message) { int len = message.length() /
	 * 2; char[] chars = message.toCharArray(); String[] hexStr = new
	 * String[len]; byte[] bytes = new byte[len]; for (int i = 0, j = 0; j <
	 * len; i += 2, j++) { hexStr[j] = "" + chars[i] + chars[i + 1]; bytes[j] =
	 * (byte) Integer.parseInt(hexStr[j], 16); } return bytes; }
	 */

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.connected, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}

--------------------------窗体部分

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.blt.Connected" >

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/BtnSend"
        android:digits="0123456789.abcdefghigklmnopqrstuvwxyz"
        android:ems="10"
        android:imeOptions="actionSend"
        android:inputType="textPersonName" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/BtnSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/editText1"
        android:layout_alignBottom="@+id/editText1"
        android:layout_alignParentRight="true"
        android:text="Send" />

    <TextView
        android:id="@+id/axis_x"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/BtnSend"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_alignRight="@+id/BtnSend"
        android:scrollbars="vertical"
        android:text="TextView" />

</RelativeLayout>


UserDriver类******************

package com.example.blt;

import android.bluetooth.BluetoothDevice;

public class UserDriver {
	
	//设备信息
	public BluetoothDevice DeviceAdapter = null;
	
	//是否已经配对了
	public boolean IsConnected = false;
	
	public UserDriver(BluetoothDevice valueDevice, boolean isConnected) {
		this.DeviceAdapter=valueDevice;
		this.IsConnected=isConnected;
	}
	
}


*************************************************

载入main窗体的时候系统自动侦测是否有蓝牙模块可以使用,当存在的时候,调出已经配对过的设备列表。然后点击菜单里面的扫描。如果扫描到新设备,则加入。

点击设备的时候,如果没有配对的,重新配对,配对过了就跳转到连接界面去。

本文出自 “石头记里看石头” 博客,转载请与作者联系!

android蓝牙模块

标签:android   蓝牙模块   

原文地址:http://nutter.blog.51cto.com/7390238/1713471

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!