新建一个工程“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窗体的时候系统自动侦测是否有蓝牙模块可以使用,当存在的时候,调出已经配对过的设备列表。然后点击菜单里面的扫描。如果扫描到新设备,则加入。
点击设备的时候,如果没有配对的,重新配对,配对过了就跳转到连接界面去。
本文出自 “石头记里看石头” 博客,转载请与作者联系!
原文地址:http://nutter.blog.51cto.com/7390238/1713471