在手机通信中,用手机作为服务器控制其他设备,通常手机的IP时动态的,因此选择运用蓝牙进行通信。
使用手机蓝牙进行通信其原理和socket通信基本一样,都是通过建立服务器端和客户端进行通信
serversocket Bluetoothserversocket
socket Bluetoothsocket
可以通过建立一个新的线程,开启通信服务。
其主要代码如下:
后台代码:
public class lanya extends AppCompatActivity { private InputStream is; private InputStream in2; private OutputStream os; private OutputStream os2; private MyAdapter adapter; private final UUID MY_UUID = UUID .fromString("abcd1234-ab12-ab12-ab12-abcdef123456");//随便定义一个 private BluetoothSocket clientSocket; private BluetoothServerSocket serverSocket; private final static int SEARCH_CODE = 0x123; //建立并获取本地蓝牙适配器 private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); private static final String TAG = "lanya"; private ListmBlueList = new ArrayList<>(); private ListView lisetView; private TextView textView1; private TextView textView2; private ExecutorService myExecutorService = null; private List mList = new ArrayList (); private Button start; private Button send; private Button send2; //蓝牙串口通信的UUID private static final UUID MY_UUID2 = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); private static String address = "20:16:07:26:18:46"; // <==要连接的目标蓝牙设备MAC地址 private EditText sendtext; private BluetoothDevice device; private boolean connect = true; private Thread acceptThread; public static final int REQUEST_CALL_PERMISSION = 10111; //拨号请求码 public boolean checkReadPermission(String string_permission, int request_code) { boolean flag = false; if (ContextCompat.checkSelfPermission(this, string_permission) == PackageManager.PERMISSION_GRANTED) {//已有权限 flag = true; } else {//申请权限 ActivityCompat.requestPermissions(this, new String[]{string_permission}, request_code); } return flag; } private Handler handler = new Handler() { public void handleMessage(Message msg) { Toast.makeText(getApplicationContext(), String.valueOf(msg.obj), Toast.LENGTH_LONG).show(); super.handleMessage(msg); if (String.valueOf(msg.obj).equals("有设备连接")) { textView2.setText("设备连接成功"); } else if (String.valueOf(msg.obj).equals("服务器开启")) { textView2.setText("服务器开启"); } else if (String.valueOf(msg.obj).equals("客户端连接成功")) { textView2.setText("客户端连接成功"); } if (String.valueOf(msg.obj).equals("a")) { //获取输入的电话号码 if (checkReadPermission(Manifest.permission.CALL_PHONE, REQUEST_CALL_PERMISSION)) { String phone = "13309197191"; //创建打电话的意图 Intent intent = new Intent(); //设置拨打电话的动作 intent.setAction(Intent.ACTION_CALL); //设置拨打电话的号码 intent.setData(Uri.parse("tel:" + phone)); startActivity(intent); } } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lanya); lisetView = (ListView) findViewById(R.id.list_view); textView1 = (TextView) findViewById(R.id.textView1); textView2 = (TextView) findViewById(R.id.tishi); start = (Button) findViewById(R.id.start); sendtext = (EditText) findViewById(R.id.sendtext); send = (Button) findViewById(R.id.send); send2 = (Button) findViewById(R.id.send2); send2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { final String mess = sendtext.getText().toString(); new Thread(new Runnable() { @Override //给以链接的服务器发送消息 public void run() { try { if (serverSocket != null) { os2.write(mess.getBytes("utf-8")); } else { return; } } catch (Exception e) { e.printStackTrace(); } } }).start(); } }); send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { final String mess = sendtext.getText().toString(); new Thread(new Runnable() { @Override //给以链接的服务器发送消息 public void run() { try { if (clientSocket != null) { os.write(mess.getBytes("utf-8")); } else { return; } } catch (Exception e) { e.printStackTrace(); } } }).start(); } }); start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { acceptThread = new AcceptThread(); acceptThread.start(); } }); init(); lisetView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView> adapterView, View view, int i, long l) { textView2.setText("启动客户端连接"); BluetoothDevice dev = mBlueList.get(i); String address = dev.getAddress().toString().trim(); Thread cc = new conn(address); cc.start(); } }); } //gps是否可用(有些设备可能需要定位) public static final boolean isGpsEnable(final Context context) { LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (gps || network) { return true; } return false; } /** * 判断蓝牙是否开启,打开蓝牙 */ private void init() { // 判断手机是否支持蓝牙 if (mBluetoothAdapter == null) { Toast.makeText(this, "设备不支持蓝牙", Toast.LENGTH_SHORT).show(); finish(); } // 判断是否打开蓝牙 if (!mBluetoothAdapter.isEnabled()) { //弹出对话框提示用户是后打开 Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent, SEARCH_CODE); } else { // 不做提示,强行打开 mBluetoothAdapter.enable(); } startDiscovery(); } /** * 注册异步搜索蓝牙设备的广播 */ private void startDiscovery() { // 找到设备的广播 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); // 注册广播 registerReceiver(receiver, filter); // 搜索完成的广播 IntentFilter filter1 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); // 注册广播 registerReceiver(receiver, filter1); startScanBluth(); } /** * 广播接收器,搜索为配对的设备 */ private final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // 收到的广播类型 String action = intent.getAction(); // 发现设备的广播 if (BluetoothDevice.ACTION_FOUND.equals(action)) { // 从intent中获取设备 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // 没否配对 if (device.getBondState() != BluetoothDevice.BOND_BONDED || device.getBondState() == BluetoothDevice.BOND_BONDED) { if (!mBlueList.contains(device)) { mBlueList.add(device); } textView1.setText("附近设备:" + mBlueList.size() + "个\u3000\u3000本机蓝牙地址:" + getBluetoothAddress()); adapter = new MyAdapter(lanya.this, mBlueList); lisetView.setAdapter(adapter); } // 搜索完成 } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { // 关闭进度条 progressDialog.dismiss(); } } }; private ProgressDialog progressDialog; // 搜索蓝牙的方法 private void startScanBluth() { // 判断是否在搜索,如果在搜索,就取消搜索 if (mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); } // 开始搜索 mBluetoothAdapter.startDiscovery(); if (progressDialog == null) { progressDialog = new ProgressDialog(this); } progressDialog.setMessage("正在搜索,请稍后!"); progressDialog.show(); } @Override protected void onDestroy() { super.onDestroy(); new Thread(new Runnable() { @Override //给以链接的服务器发送消息 public void run() { try { connect = false; serverSocket.close(); clientSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }).start(); if (receiver != null) { //取消注册,防止内存泄露(onDestroy被回调代不代表Activity被回收?:具体回收看系统,由GC回收,同时广播会注册到系统 //管理的ams中,即使activity被回收,reciver也不会被回收,所以一定要取消注册), unregisterReceiver(receiver); } } // 获取本机蓝牙地址 private String getBluetoothAddress() { try { BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); Field field = bluetoothAdapter.getClass().getDeclaredField("mService"); // 参数值为true,禁用访问控制检查 field.setAccessible(true); Object bluetoothManagerService = field.get(bluetoothAdapter); if (bluetoothManagerService == null) { return null; } Method method = bluetoothManagerService.getClass().getMethod("getAddress"); Object address = method.invoke(bluetoothManagerService); if (address != null && address instanceof String) { return (String) address; } else { return null; } //抛一个总异常省的一堆代码... } catch (Exception e) { e.printStackTrace(); } return null; } //服务端监听客户端的线程类 private class AcceptThread extends Thread { public AcceptThread() { try { serverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID); Message msg1 = new Message(); msg1.obj = "服务器开启"; handler.sendMessage(msg1); } catch (Exception e) { } } public void run() { try { BluetoothSocket socket = serverSocket.accept(); is = socket.getInputStream(); os2 = socket.getOutputStream(); Message msg1 = new Message(); msg1.obj = "有设备连接"; handler.sendMessage(msg1); while (connect) { byte[] buffer = new byte[1024]; int count = is.read(buffer); Message msg = new Message(); msg.obj = new String(buffer, 0, count, "utf-8"); handler.sendMessage(msg); } } catch (Exception e) { } } } //客户端连接进程 private class conn extends Thread { public conn(String address) { //主动连接蓝牙服务端 try { //判断当前是否正在搜索 if (mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); } try { if (device == null) { //获得远程设备 device = mBluetoothAdapter.getRemoteDevice(address); } if (clientSocket == null) { //创建客户端蓝牙Socket clientSocket = device.createRfcommSocketToServiceRecord(MY_UUID); //开始连接蓝牙,如果没有配对则弹出对话框提示我们进行配对 clientSocket.connect(); Message msg1 = new Message(); msg1.obj = "客户端连接成功"; handler.sendMessage(msg1); } } catch (Exception e) { } } catch (Exception e) { } } public void run() { //获得输出流(客户端指向服务端输出文本) try { os = clientSocket.getOutputStream(); in2 = clientSocket.getInputStream(); while (connect) { byte[] buffer = new byte[1024]; int count = in2.read(buffer); Message msg = new Message(); msg.obj = new String(buffer, 0, count, "utf-8"); handler.sendMessage(msg); } } catch (Exception e) { } } } //多线程服务器,一个服务器可以开启多个线程 public class conn2 extends Thread { private String name; public conn2(String name) { this.name = name; } public void run() { try { serverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID); Message msg1 = new Message(); msg1.obj = "服务器开启"; handler.sendMessage(msg1); //创建线程池 myExecutorService = Executors.newCachedThreadPool(); System.out.println("服务端运行中...\n"); Socket client = null; while (true) { BluetoothSocket socket = serverSocket.accept(); mList.add(socket); myExecutorService.execute(new Service(socket)); } } catch (Exception e) { e.printStackTrace(); } } } class Service implements Runnable { private BluetoothSocket socket; private DataInputStream in = null; private String msg = ""; private String a; public Service(BluetoothSocket socket) { this.socket = socket; try { is = socket.getInputStream(); os2 = socket.getOutputStream(); } catch (Exception e) { e.printStackTrace(); } } public void run() { try { while (true) { if (is != null) { byte[] buffer = new byte[1024]; int count = is.read(buffer); Message msg = new Message(); msg.obj = new String(buffer, 0, count, "utf-8"); handler.sendMessage(msg); } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } }