新建一个工程“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窗体的时候系统自动侦测是否有蓝牙模块可以使用,当存在的时候,调出已经配对过的设备列表。然后点击菜单里面的扫描。如果扫描到新设备,则加入。
点击设备的时候,如果没有配对的,重新配对,配对过了就跳转到连接界面去。