手机蓝牙通信开发

在手机通信中,用手机作为服务器控制其他设备,通常手机的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 List mBlueList = 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();
            }
        }
    }
}

 

你可能感兴趣的:(android)