1.布局
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/button_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开启蓝牙" /> <Button android:id="@+id/button_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="搜索设备"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <ListView android:id="@+id/list_item" android:layout_width="match_parent" android:layout_height="wrap_content"> </ListView> </LinearLayout> </LinearLayout> </android.support.constraint.ConstraintLayout>
2.权限
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
3.MainActivity
package com.example.administrator.myapplication62; import android.Manifest; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothSocket; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.Build; import android.os.Handler; import android.os.Message; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.Toast; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.UUID; public class MainActivity extends Activity implements AdapterView.OnItemClickListener { private BluetoothAdapter bluetoothAdapter; //本地蓝牙适配器 private BluetoothDevice bluetoothDevice; private BlueReceiver blueReceiver; private List <String> list =new ArrayList<>(); private ListView listView; private ArrayAdapter<String> adapter; private ArrayAdapter<BluetoothDevice> bluetoothDeviceArrayAdapter; private IntentFilter filter; private OutputStream os; private final UUID MY_UUID = UUID .fromString("00001101-0000-1000-8000-00805F9B34FB"); private final String NAME = "Bluetooth_Socket"; private BluetoothSocket bluetoothSocket; private AcceptThread thread; @Override //注册蓝牙广播接收器 protected void onStart() { super.onStart(); blueReceiver = new BlueReceiver(); filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_FOUND);//发现蓝牙动作 filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束动作 filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//搜素开始动作 registerReceiver(blueReceiver, filter);//注册 Log.d("CZK", "蓝牙广播接受器注册完毕"); } @Override protected void onStop() { super.onStop(); unregisterReceiver(blueReceiver); Log.d("CZK", "取消注册"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button1 =findViewById(R.id.button_1); Button button2 =findViewById(R.id.button_2); listView = findViewById(R.id.list_item); listView.setOnItemClickListener(this); bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); bluetoothPermissions(); // 用Set集合保持已绑定的设备 Set<BluetoothDevice> devices = bluetoothAdapter.getBondedDevices(); if (devices.size() > 0) { for (BluetoothDevice bluetoothDevice : devices) { // 保存到arrayList集合中 list.add(bluetoothDevice.getName() + ":" + bluetoothDevice.getAddress() + "\n"); } } button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (!bluetoothAdapter.isEnabled()) { Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent, 200); Log.d("CZK", "1");//刷新 }else{ Toast.makeText(MainActivity.this,"蓝牙已开启",Toast.LENGTH_SHORT).show(); } } }); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { setTitle("正在扫描..."); if(bluetoothAdapter.isDiscovering()){//如果还在搜索,则停止搜索 bluetoothAdapter.cancelDiscovery(); } list.clear(); //清除列表内容 listView.setAdapter(null); bluetoothAdapter.startDiscovery(); } }); //启动线程 // 实例接收客户端传过来的数据线程 thread = new AcceptThread(); // 线程开始 thread.start(); } private void bluetoothPermissions() { if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{ android.Manifest.permission.ACCESS_COARSE_LOCATION}, 1); Log.d("CZK", "地理位置授权成功 "); } } //蓝牙接收器 public class BlueReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if(device.getBondState()!=BluetoothDevice.BOND_BONDED){ list.add(device.getName()+":"+device.getAddress()+"\n"); adapter = new ArrayAdapter<>(MainActivity.this,android.R.layout.simple_list_item_1,android.R.id.text1,list); listView.setAdapter(adapter); adapter.notifyDataSetChanged(); Log.d("CZK", "蓝牙发现目标"); } }else if (intent.getAction() .equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) { setTitle("搜索完成"); } if (intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) { Log.d("CZK","蓝牙搜索结束"); Toast.makeText(MainActivity.this,"搜素结束",Toast.LENGTH_SHORT).show(); } if (intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) { Log.d("CZK","蓝牙搜索开始"); Toast.makeText(MainActivity.this,"开始搜素",Toast.LENGTH_SHORT).show(); } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode==200){ Intent dis=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); dis.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(dis); Log.d("CZK", "discoverable");//刷新 } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode){ case 1: if(grantResults.length > 0&& grantResults[0]==PackageManager.PERMISSION_GRANTED){ Toast.makeText(MainActivity.this,"地理授权成功",Toast.LENGTH_SHORT); } else { Toast.makeText(MainActivity.this,"地理授权失败",Toast.LENGTH_SHORT); } } } Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); // 通过msg传递过来的信息,吐司一下收到的信息 Toast.makeText(MainActivity.this, (String) msg.obj, Toast.LENGTH_LONG).show(); } }; private class AcceptThread extends Thread{ private BluetoothServerSocket serverSocket;// 服务端接口 private BluetoothSocket socket;// 获取到客户端的接口 private InputStream is;// 获取到输入流 private OutputStream os;// 获取到输出流 public AcceptThread(){ try { // 通过UUID监听请求,然后获取到对应的服务端接口 serverSocket = bluetoothAdapter .listenUsingRfcommWithServiceRecord(NAME, MY_UUID); } catch (Exception e) { // TODO: handle exception } } public void run(){ try { // 接收其客户端的接口 socket = serverSocket.accept(); // 获取到输入流 is = socket.getInputStream(); // 获取到输出流 os = socket.getOutputStream(); // 无线循环来接收数据 while (true) { // 创建一个128字节的缓冲 byte[] buffer = new byte[128]; // 每次读取128字节,并保存其读取的角标 int count = is.read(buffer); // 创建Message类,向handler发送数据 Message msg = new Message(); // 发送一个String的数据,让他向上转型为obj类型 msg.obj = new String(buffer, 0, count, "utf-8"); // 发送数据 handler.sendMessage(msg); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { String s = adapter.getItem(i); String address = s.substring(s.indexOf(":")+1).trim(); if(bluetoothAdapter.isDiscovering()){//如果还在搜索,则停止搜索 bluetoothAdapter.cancelDiscovery(); } if (bluetoothDevice == null){ bluetoothDevice = bluetoothAdapter.getRemoteDevice(address);//getRemoteDevice()得到指定蓝牙的BluetoothDevice Log.d("CZK", "getRemoteDevice()得到指定蓝牙的BluetoothDevice"); } try { if (bluetoothSocket == null){ // 获取到客户端接口(获得对象) bluetoothSocket = bluetoothDevice .createRfcommSocketToServiceRecord(MY_UUID); // 向服务端发送连接 bluetoothSocket.connect(); Log.d("CZK", "连接成功"); // 获取到输出流,向外写数据 os = bluetoothSocket.getOutputStream(); }else { Log.d("CZK","bluetoothSocket != null"); } // 判断是否拿到输出流 if (os != null) { // 需要发送的信息 String text = "你个菜鸡"; // 以utf-8的格式发送出去 os.write(text.getBytes("UTF-8")); Log.d("CZK", "发送成功"); } } catch (IOException e) { Log.d("CZK",e.toString()); e.printStackTrace(); // 如果发生异常则告诉用户发送失败 Toast.makeText(this, "发送信息失败", Toast.LENGTH_SHORT).show(); } } }