经典蓝牙的基本操作

来源:互联网 发布:专业检测手机信号软件 编辑:程序博客网 时间:2024/05/18 18:45

需要3个权限:

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><uses-permission android:name="android.permission.BLUETOOTH"/><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

<?xml version="1.0" encoding="utf-8"?><LinearLayout 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:orientation="vertical"    tools:context="com.example.bluetooth.MainActivity">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="open"            android:text="直接打开蓝牙" />        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="request"            android:text="请求用户打开蓝牙" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="close"            android:text="关闭蓝牙" />        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="setName"            android:text="设置蓝牙名称" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="discover"            android:text="打开可被发现" />        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="getBound"            android:text="获取已配对的设备" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="scan"            android:text="开始扫描" />        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="startServer"            android:text="建立连接" />    </LinearLayout>    <ListView        android:id="@+id/lv"        android:layout_width="match_parent"        android:layout_height="match_parent">    </ListView></LinearLayout>

package com.example.bluetooth;import android.Manifest;import android.app.AlertDialog;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothServerSocket;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.content.pm.PackageManager;import android.os.Build;import android.os.Bundle;import android.support.annotation.NonNull;import android.support.v7.app.AppCompatActivity;import android.text.TextUtils;import android.util.Log;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.EditText;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 AppCompatActivity implements AdapterView.OnItemClickListener {    BluetoothAdapter bluetoothAdapter;    ListView lv;    // 所有扫描的蓝牙名称的集合    List<String> deviceNames = new ArrayList<>();    // 所有扫描的蓝牙设备的集合    List<BluetoothDevice> devices = new ArrayList<>();    ArrayAdapter<String> adapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 获取蓝牙适配器        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();        // 找到ListView控件        lv = (ListView) findViewById(R.id.lv);        // 创建一个适配器        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, deviceNames);        lv.setAdapter(adapter);        // 设置ListView的点击事件去请求服务端        lv.setOnItemClickListener(this);    }    // 点击按钮直接打开蓝牙    public void open(View view) {        // 直接打开蓝牙(不推荐使用的)第一次打开需要获取权限 要添加权限 BLUETOOTH_ADMIN 和 BLUETOOTH        bluetoothAdapter.enable();    }    // 点击按钮请求用户打开蓝牙    public void request(View view) {        // 请求用户打开蓝牙(推荐使用的方法)每次打开都需要获取权限        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);        startActivity(intent);    }    // 点击按钮关闭蓝牙    public void close(View view) {        // 关闭直接调用disable方法        bluetoothAdapter.disable();    }    // 点击按钮设置蓝牙名称    public void setName(View view) {        // 创建一个对话框        AlertDialog.Builder builder = new AlertDialog.Builder(this);        // 创建一个输入控件        final EditText et = new EditText(this);        // 显示蓝牙名称        et.setText(bluetoothAdapter.getName());        // 把输入控件设置到对话框内        builder.setView(et);        // 设置对话框标题        builder.setTitle("设置蓝牙名称");        // 设置取消确定按钮        builder.setNegativeButton("取消", null);        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {                String name = et.getText().toString();                if (TextUtils.isEmpty(name)) {                    Toast.makeText(MainActivity.this, "蓝牙名称不能为空", Toast.LENGTH_SHORT).show();                } else {                    bluetoothAdapter.setName(name);                }            }        }).create().show();    }    // 点击按钮可被发现或扫描    public void discover(View view) {        // 使用意图来操作 可被发现        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);        // 可被发现的默认时间是120秒(可以被改,这里改成600秒)        intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 600);        startActivity(intent);    }    // 点击按钮获取已配对过的设备    public void getBound(View view) {        // 获取已配对的蓝牙设备        Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();        // set集合里面去数据用迭代器或者foreach,不能使用for循环,因为没有索引号        for (BluetoothDevice bondedDevice : bondedDevices) {            // 这里就打印下            Log.e("TAG", "-----------" + bondedDevice.getName());        }    }    // 点击按钮开始扫描附近蓝牙设备    public void scan(View view) {        // 扫描蓝牙必须是打开状态,先判断蓝牙的状态        if (bluetoothAdapter.isEnabled()) {            // 打开状态 (6.0以上,扫描必须动态获取地理位置权限)            if (Build.VERSION.SDK_INT >= 23) {                int check = checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION);                if (check == PackageManager.PERMISSION_GRANTED) {                    startScan();                } else {                    // 请求权限(执行完就会执行权限请求结果的方法onRequestPermissionsResult())                    requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);                }            } else {                // 开始扫描                startScan();            }        } else {            // 关闭状态            request(view);        }    }    private void startScan() {        // 以广播的方式来发送蓝牙设备        // 判断蓝牙是否正在扫描中        if (!bluetoothAdapter.isDiscovering()) {            // 开始扫描            bluetoothAdapter.startDiscovery();        }        // 停止扫描        //bluetoothAdapter.cancelDiscovery();    }    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        // 判断结果(requestCode要与上面的相同,grantResults[0]是数组0坐标位置的权限)        if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {            // 开始扫描            startScan();        } else {            Toast.makeText(this, "由于android版本高于6.0必须获取地理位置才能扫描蓝牙", Toast.LENGTH_SHORT).show();        }    }    // 通过广播接收者来接收蓝牙设备    private BroadcastReceiver receiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            // 蓝牙设备被发现的监听            if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {                // 获取到其它的蓝牙设备                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);                // 从蓝牙设备中获取具体的数据,获取蓝牙的名称(如果没有名称就显示匿名)                String name = device.getName() == null ? "匿名" : device.getName();                // 把蓝牙名称添加到集合                deviceNames.add(name);                adapter.notifyDataSetChanged();                // 把蓝牙设备添加到集合                devices.add(device);            }        }    };    @Override    protected void onResume() {        super.onResume();        // 注册广播接受者        registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));    }    @Override    protected void onPause() {        super.onPause();        // 注销广播接收者        unregisterReceiver(receiver);    }    // 点击按钮建立连接    public void startServer(View view) {        if (server == null) {            server = new MyServer();            // 开启线程            server.start();        }    }    MyServer server;    // 手机连接的UUID(可以随机获取),设备连接非UUID由厂商决定    UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");    @Override    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {        // 点击列表请求服务器   从蓝牙设备集合中获取蓝牙设备        final BluetoothDevice device = devices.get(position);        // 需要耗时创建一个子线程        new Thread(){            @Override            public void run() {                super.run();                // 创建一个安全的连接                try {                    BluetoothSocket socket = device.createRfcommSocketToServiceRecord(uuid);                    // 必须要调socket.connect()才能打开流                    socket.connect();                    // 获取输出流                    OutputStream outputStream = socket.getOutputStream();                    outputStream.write("你好!蓝牙服务器".getBytes());                    outputStream.flush();                    outputStream.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }.start();    }    class MyServer extends Thread {        @Override        public void run() {            super.run();            BluetoothServerSocket bluetoothServerSocket;            try {                // 使用网络了所以要创建子线程                bluetoothServerSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(bluetoothAdapter.getName(), uuid);                // 等待客户的连接                BluetoothSocket socket = bluetoothServerSocket.accept();                // 如果是连接状态就一直创建流读取数据(客户端在ListView上显示,点击就请求服务器,接下来设置它的点击事件)                while (socket.isConnected()) {                    // 从socket里面获取输入流读取数据                    InputStream inputStream = socket.getInputStream();                    int len = 0;                    byte[] buf = new byte[1024];                    while ((len = inputStream.read(buf)) != -1) {                        Log.e("TAG", "----------------" + new String(buf, 0, len, "utf-8"));                    }                }                // 执行run方法后返回一个客户端,服务端就可以关闭了(蓝牙设备里面必须1对1所以可以关闭服务端,而TCP是1对多的所要服务器不能关闭)                bluetoothServerSocket.close();            } catch (IOException e) {                e.printStackTrace();            }            // 这里等于null是为了下次还可以再建立服务端            bluetoothServerSocket = null;        }    }}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 去韩国留学护照怎么办 去韩国签证怎么办d4 出国留学拒签怎么办 高中毕业考不上大学怎么办 深圳怎么办客运营运证 深圳龙岗怎么办居住证 想去日本怎么办签证 孩子没有出生证怎么办通行证 去日本旅游怎么办签证 去美国旅游签证怎么办 我想去泰国怎么办签证 怎么办去泰国的签证 去韩国工作怎么办签证 去越南打工怎么办签证 越南到中国签证怎么办 去越南工作签证怎么办 马来西亚留学签证过期后怎么办 日本留学存款不够怎么办 没有工作单位怎么办签证 深户日本签证怎么办 土耳其跟团签证怎么办 公司取消交通车职工怎么办 出国健康证丢失怎么办 大三阳怎么办健康证 办不了健康证怎么办 办健康证不合格怎么办 美团健康证怎么办 便检取样很多怎么办 拉不出大便怎么办马上解决方法 无业人员怎么办健康证 健康证没身份证怎么办 身份证过期了怎么办护照 驾照体检表丢了怎么办 驾照体检表掉了怎么办 驾校体检表掉了怎么办 身份证掉了怎么办护照 驾照体检表过期了怎么办 助力车行驶证过期怎么办 c1证骑摩托车怎么办 别人知道驾驶证号码怎么办 摩托车卖了车牌怎么办