精华内容
下载资源
问答
  • Android Studio 蓝牙开发流程 万次阅读 多人点赞
    2018-07-13 22:45:17

    1. 权限

    关于蓝牙的权限主要涉及到下面三个:

    BLUETOOTH:允许配对的设备进行连接

    BLUETOOTH_ADMIN:允许搜索和配对设备

    ACCESS_COARSE_LOCATION:广播接收器接收BluetoothDevice.ACTION_FOUND广播需要改权限

     

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

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

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

    在后面还会提到在Android6.0及以上的版本中关于ACCESS_COARSE_LOCATION权限的申请。

     

    2. 开启蓝牙

    建立蓝牙通信之前需要验证是否有蓝牙设备,以及蓝牙设备是否已经开启。对于一个Android系统而言只有一个蓝牙适配器,通过getDefaultAdapter()方法可以返回其一个实例,如果返回为null,则说明该设备不支持蓝牙。

     

    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    if (mBluetoothAdapter == null) {

            // device doesn't support Bluetooth

    }

    接下来是检查蓝牙设备是否已经开启,如果没有开启,可以调用startActivityForResult()方法来弹出对话框让用户选择开启,这种方式不会停止当前的应用。

     

    if (!mBluetoothAdapter.isEnabled()) {

            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

    }

     

    3. 搜索设备

    搜索设备可以分成两部分,一是查找已经与本机配对的设备,通过getBondedDevices()方法返回已经配对的设备信息:

     

    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();

    if (pariedDevices.size > 0) {

            for (BluetoothDevice device: pairedDevices) {

                    String deviceName = device.getName();

                    String deviceMACAddress = device.getAddress();

            }

    }

    二是搜索周围可用的但是还未配对的设备。

    系统在发现蓝牙设备会通过广播的形式通知app,所以在搜索设备之前需要注册广播接收器来接收发现蓝牙设备的消息,在销毁Activity时注销广播接收器。

     

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {

            public void onReceiver(Context context, Intent intent) {

                    String action = intent.getAction();

                    if (BluetoothDevice.ACTION_FOUND.equals(action)) {

                            BluetoothDevie device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                    }

            }

    }

     

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        // Register for broadcasts when a device is discovered.

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

        registerReceiver(mReceiver, filter);

    }

     

    @Override

    protected void onDestroy() {

        super.onDestroy();

        // Don't forget to unregister the ACTION_FOUND receiver.

        unregisterReceiver(mReceiver);

    }

    BluetoothDevice.ACTION_FOUND广播需要ACCESS_COARSE_LOCATION权限,该权限是个危险权限,在Android 6.0及以上,除了在manifest中声明还需要在java代码中申请。获取了该权限之后,在搜索蓝牙设备时才能收到系统发出的蓝牙设备发现的广播。搜索设备调用startDiscovery()方法,当周围有可用设备时,系统会通过广播的形式通知应用。

     

    //检查ACCESS_COARSE_LOCATION权限

                    if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)

                            == PackageManager.PERMISSION_GRANTED){

                        Toast.makeText(MainActivity.this,"搜索回调权限已开启",Toast.LENGTH_SHORT).show();

                        if(mBluetoothAdapter.isDiscovering()){

                            mBluetoothAdapter.cancelDiscovery();

                        }

                        mBluetoothAdapter.startDiscovery();

                    }else{

                        Toast.makeText(MainActivity.this,"搜索回调权限未开启",Toast.LENGTH_SHORT).show();

                        ActivityCompat.requestPermissions(MainActivity.this,

                                new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},REQUEST_ACCESS_COARSE_LOCATION);

                    }

     

    @Override

        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

            super.onRequestPermissionsResult(requestCode, permissions, grantResults);

            if(requestCode==REQUEST_ACCESS_COARSE_LOCATION){

                if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){

                    mBluetoothAdapter.startDiscovery();

                    if(mBluetoothAdapter.isDiscovering()){

                        mBluetoothAdapter.cancelDiscovery();

                    }

                    mBluetoothAdapter.startDiscovery();

     

                } else {

                    Toast.makeText(MainActivity.this,"action found is not granted.",Toast.LENGTH_LONG).show();

                }

     

            }

        }

    4.6.3 建立连接发送数据

    做的这个应用主要是与HC-06模块进行蓝牙通信,HC-06是一个串口透传模块,其对应的UUID是“00001101-0000-1000-8000-00805F9B34FB”。手机端是作为客户端与HC-06蓝牙模块进行连接的。在蓝牙socket进行connect之前,一定要调用BluetoothAdaptercancelDiscovery()方法。连接的第一步是通过调用BluetoothDevicecreateRfcommSocketToServiceRecord(UUID)获取BluetoothSocket.第二步是调用BluetoothSocketconnect()方法发起连接。由于connect()为阻塞调用,因此该连接过程应该在主线程之外的线程中执行。

    在调用connect()时,应始终确保设备未在执行设备发现。如果正在进行发现操作,则会大幅降低连接尝试的速度,并增加连接失败的可能性。

    示例:

     

    String macAddr = "20:15:05:25:02:43";

    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddr);

    UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");

    try {

        mSocket = device.createRfcommSocketToServiceRecord(uuid);

    } catch (IOException e) {

        e.printStackTrace();

    }

    new Thread(){

        @Override

        public void run() {

            mBluetoothAdapter.cancelDiscovery();

            try {

                mSocket.connect();

            } catch (IOException e) {

                try {

                    mSocket.close();

                } catch (IOException e1) {

                    e1.printStackTrace();

                }

                e.printStackTrace();

            }

            super.run();

        }

    }.start();

    确保在建立连接之前始终调用cancelDiscovery(),而且调用时无需实际检查其是否正在运行,如果确实想要执行检查,请调用isDiscovering()

    更多相关内容
  • 基于Android studio蓝牙开发代码,正在进行android程序开发的小伙伴可以看一下,可用于手环二次开发的蓝牙模块的书写。
  • Android Studio开发蓝牙应用(一)

    千次阅读 热门讨论 2022-01-26 11:17:25
    Android Studio开发蓝牙应用(一) 环境 window 11 安卓12 HC-06蓝牙模块 创建空project 选择Empty Activity,后点击Next 可修改项目名,自定义,后点击Finish即可。 首先设计布局,布局文件位于app/src/...

    Android Studio开发蓝牙应用(一)

    环境

    • window 11
    • 安卓12
    • HC-06蓝牙模块

    创建空project

    • 选择Empty Activity,后点击Next
      在这里插入图片描述

    • 可修改项目名,自定义,后点击Finish即可。
      在这里插入图片描述

    • 首先设计布局,布局文件位于app/src/main/res/layout
      在这里插入图片描述

    • 直接使用约束布局方式,这种方式布局代码大部分可自动生成,方便
      在这里插入图片描述

      • 项目实现的功能
        • 查看手机是否支持蓝牙
        • 查看当前蓝牙状态
        • 蓝牙开关
        • 使蓝牙可见
        • 搜索可见蓝牙
        • 查看已绑定的设备
    • Acitivity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.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">
    
        <Button
            android:id="@+id/button3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="是否支持蓝牙"
            app:layout_constraintEnd_toStartOf="@+id/guideline2"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/button4"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="当前蓝牙状态"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline2"
            app:layout_constraintTop_toTopOf="parent" />
    
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_begin="205dp" />
    
        <Button
            android:id="@+id/button7"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="打开蓝牙"
            app:layout_constraintEnd_toStartOf="@+id/guideline2"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/button3" />
    
        <Button
            android:id="@+id/button8"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="关闭蓝牙"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline2"
            app:layout_constraintTop_toBottomOf="@+id/button4" />
    
        <Button
            android:id="@+id/button9"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="使蓝牙可见"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/button7" />
    
        <Button
            android:id="@+id/button10"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="搜索可见蓝牙"
            app:layout_constraintEnd_toStartOf="@+id/guideline2"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/button9" />
    
        <Button
            android:id="@+id/button11"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="查看已绑定蓝牙"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline2"
            app:layout_constraintTop_toBottomOf="@+id/button9" />
    
        <ListView
            android:id="@+id/listview1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView" />
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="#00BCD4"
            android:gravity="center"
            android:text="蓝牙列表"
            android:textSize="24sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/button10" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    蓝牙权限问题

    安卓12对蓝牙权限做了改动,且需要动态获取权限

    • 首先在app/src/main/AndroidManifest.xml中添加权限
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.btapp">
    
        <!-- 先前的蓝牙权限需求-->
        <uses-permission android:name="android.permission.BLUETOOTH" />
        <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
        <!-- 安卓12新增的蓝牙权限-->
        <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
        <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
        <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />    
        <!-- 定位权限, 蓝牙搜索需要-->
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.BTapp">
            <activity
                android:name=".MainActivity"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>
    
    • MainActivity.java中实现动态申请权限,在执行蓝牙相关函数时执行getPermission函数
    public class MainActivity extends AppCompatActivity {
    	private static final int REQ_PERMISSION_CODE = 1;
        // 蓝牙权限列表
        public ArrayList<String> requestList = new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        /**
         * 动态申请权限
         */
        public void getPermision(){
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
                requestList.add(Manifest.permission.BLUETOOTH_SCAN);
                requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);
                requestList.add(Manifest.permission.BLUETOOTH_CONNECT);
                requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);
                requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
                requestList.add(Manifest.permission.BLUETOOTH);
            }
            if(requestList.size() != 0){
                ActivityCompat.requestPermissions(this, requestList.toArray(new String[0]), REQ_PERMISSION_CODE);
            }
        }
    }
    

    实机测试

    实机测试时若提示安装包异常,则在项目的gradle.properties后添加

    android.injected.testOnly=false
    

    功能实现

    • app/src/main/java/com.example.btapp内新建蓝牙控制器类BlueToothController.java
    • 获取蓝牙适配器类BlueToothAdpter
    public class BlueToothController {
    	// 成员变量
    	private BluetoothAdapter mAdapter;
    	/**
    	 * 构造函数
    	 */
    	public BlueToothController(){
    	    // 获取本地的蓝牙适配器
    	    mAdapter = BluetoothAdapter.getDefaultAdapter();
    	}
    
    • 查看是否支持蓝牙
    public boolean isSupportBlueTooth(){
       // 若支持蓝牙,则本地适配器不为null
       if(mAdapter != null){
           return true;
       }
       // 否则不支持
       else{
           return false;
       }
    }
    

    MainActivity.java中绑定对应功能

    package com.example.btapp;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
    	private static final int REQ_PERMISSION_CODE = 1;
        // 实例化蓝牙控制器
        public BlueToothController btController = new BlueToothController();
        // 实例化蓝牙控制器
        public BlueToothController btController = new BlueToothController();
        // 弹窗
        private Toast mToast;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 通过id获取“是否支持蓝牙”按钮
            Button button_1 = (Button) findViewById(R.id.button3);
            // 绑定按钮点击事件处理函数
            button_1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                	// 获取蓝牙权限
                    getPermision();
                    // 判断是否支持蓝牙
                    boolean ret = btController.isSupportBlueTooth();
                    // 弹窗显示结果
                    showToast("是否支持蓝牙" + ret);
                }
            });
        }
    
    	   /**
         * 动态申请权限
         */
        public void getPermision(){
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
                requestList.add(Manifest.permission.BLUETOOTH_SCAN);
                requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);
                requestList.add(Manifest.permission.BLUETOOTH_CONNECT);
                requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);
                requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
                requestList.add(Manifest.permission.BLUETOOTH);
            }
            if(requestList.size() != 0){
                ActivityCompat.requestPermissions(this, requestList.toArray(new String[0]), REQ_PERMISSION_CODE);
            }
        }
    	
        /**
         * Toast弹窗显示
         * @param text  显示文本
         */
        public void showToast(String text){
            // 若Toast控件未初始化
            if( mToast == null){
                // 则初始化
                mToast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
            }
            // 否则
            else{
                // 修改显示文本
                mToast.setText(text);
            }
            // 显示
            mToast.show();
        }
    }
    
    • 判断当前蓝牙状态
    /**
    * 判断当前蓝牙状态
     * @return true为打开,false为关闭
     */
    public boolean getBlueToothStatus(){
        // 断言,为了避免mAdapter为null导致return出错
        assert (mAdapter != null);
        // 蓝牙状态
        return mAdapter.isEnabled();
    }
    

    绑定功能

    // 通过id获取“当前蓝牙状态”按钮
    Button button_2 = (Button) findViewById(R.id.button4);
    // 绑定按钮点击事件处理函数
    button_2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
    		// 获取蓝牙权限
    		getPermision();
            // 判断当前蓝牙状态
            boolean ret = btController.getBlueToothStatus();
            // 弹窗显示结果
            showToast("当前蓝牙状态:" + ret);
        }
    });
    
    • 打开蓝牙
    /**
    * 打开蓝牙
    */
    public boolean turnOnBlueTooth(Activity activity, int requestCode){
        if(!mAdapter.isEnabled()) {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            activity.startActivityForResult(intent, requestCode);
       }
    }
    

    MainActivity.java中绑定函数

    
    // 蓝牙状态改变广播
    private BroadcastReceiver receiver = new BroadcastReceiver(){
    	@Override
    	public void onReceive(Context context, Intent intent) {
    		int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
    		switch (state){
    		    case BluetoothAdapter.STATE_OFF:
    		        showToast("STATE_OFF");
    		        break;
    		    case BluetoothAdapter.STATE_ON:
    		        showToast("STATE_ON");
    		        break;
    		    case BluetoothAdapter.STATE_TURNING_OFF:
    		        showToast("STATE_TURNING_OFF");
    		        break;
    		    case BluetoothAdapter.STATE_TURNING_ON:
    		        showToast("STATE_TURNING_ON");
    		        break;
    		    default:
    		        showToast("UnKnow STATE");
    		        unregisterReceiver(this);
    		        break;
    		}
    	}
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    	IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
    	// 注册广播
    	registerReceiver(receiver, filter);
    	// 通过id获取"打开蓝牙"按钮
    	Button button_3 = (Button) findViewById(R.id.button7);
    	// 绑定按钮点击事件处理函数
    	button_3.setOnClickListener(new View.OnClickListener() {
    	    @Override
    	    public void onClick(View view) {
    	        turnOnbt();
    	    }
    	});
    }
    
    /**
    * 打开蓝牙
    */
    public void turnONbt(){
        // 获取蓝牙权限
        getPermision();
        // 打开蓝牙
        btController.turnOnBlueTooth(this, 1);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == RESULT_OK){
            showToast("open successfully");
        }
        else{
            showToast("open unsuccessfully");
        }
    }
    
    • 关闭蓝牙
    /**
    * 关闭蓝牙
    * @return
    */
    public void turnOffBlueTooth() {
       if(mAdapter.isEnabled()) {
           mAdapter.disable();
       }
    }
    

    MainActivity,java绑定功能

    // 通过id获取”关闭蓝牙“按钮
    Button button_4 = (Button) findViewById(R.id.button8);
     // 绑定按钮点击事件处理函数
     button_4.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View view) {
             // 获取蓝牙权限
             getPermision();
             // 关闭蓝牙
             btController.turnOffBlueTooth();
         }
     });
    
    • 使蓝牙可见
    /**
    * 打开蓝牙可见性
    * @param context
    */
    public void enableVisibly(Context context){
    	Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    	discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
    	context.startActivity(discoverableIntent);
    }
    

    MainActivity.java中绑定函数

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	// 通过id获取”使蓝牙可见“按钮
    	Button button_5 = (Button) findViewById(R.id.button9);
    	 // 绑定按钮点击事件处理函数
    	 button_5.setOnClickListener(new View.OnClickListener() {
    	     @Override
    	     public void onClick(View view) {
    	         // 蓝牙可见
    	         BTVisible();
    	     }
    	 });
    }
    
    /**
    * 设置蓝牙可见
    */
    public void BTVisible(){
    	// 获取蓝牙权限
    	getPermision();
    	// 打开蓝牙可见
    	btController.enableVisibly(this);
    }
    
    • 搜索可见蓝牙
    /**
    * 查找设备
    */
    public boolean findDevice(){
    	assert(mAdapter!=null);
    	if(mAdapter.isDiscovering()){
    	    mAdapter.cancelDiscovery();
    	    return false;
    	}else {
    	    return mAdapter.startDiscovery();
    	}
    }
    

    MainActivity.java绑定函数

     // 搜索蓝牙广播
    private IntentFilter foundFilter;
    //
    public ArrayAdapter adapter1;
    //定义一个列表,存蓝牙设备的地址。
    public ArrayList<String> arrayList=new ArrayList<>();
    //定义一个列表,存蓝牙设备地址,用于显示。
    public ArrayList<String> deviceName=new ArrayList<>();
    // 搜索蓝牙广播
    private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            String s;
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            if (device.getBondState() == 12) {
                s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
            }
            else if (device.getBondState() == 10){
                s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n";
            }else{
                s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n";
            }
            if (!deviceName.contains(s)) {
                deviceName.add(s);//将搜索到的蓝牙名称和地址添加到列表。
                arrayList.add(device.getAddress());//将搜索到的蓝牙地址添加到列表。
                adapter1.notifyDataSetChanged();//更新
            }
        }else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
            showToast("搜索结束");
            unregisterReceiver(this);
        }else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
            showToast("开始搜索");
        }
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	// 通过id获取”搜索可见蓝牙“按钮
    	Button button_6 = (Button) findViewById(R.id.button10);
    	// 绑定按钮点击事件处理函数
    	button_6.setOnClickListener(new View.OnClickListener() {
    	    @Override
    	    public void onClick(View view) {
    	        // 获取蓝牙权限
                getPermision();
                // 注册广播
                registerReceiver(bluetoothReceiver, foundFilter);
                // 初始化各列表
                arrayList.clear();
                deviceName.clear();
                adapter1.notifyDataSetChanged();
                // 开始搜索
                btController.findDevice();
    	    }
    	});
    	//搜索蓝牙的广播
    	foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    	foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
    	foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    	// 获取ListView组件
    	ListView listView = (ListView) findViewById(R.id.listview1);
    	// 实例化ArrayAdapter对象
    	adapter1 = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, deviceName);
    	// 添加到ListView组件中
    	listView.setAdapter(adapter1);
    }
    
    • 查看已绑定的设备
    /**
    * 获取绑定设备
    * @return
    */
    public ArrayList<BluetoothDevice> getBondedDeviceList(){
    	return new ArrayList<BluetoothDevice>(mAdapter.getBondedDevices());
    }
    

    绑定功能

    // 通过id获取”查看已绑定蓝牙“按钮
    Button button_7 = (Button) findViewById(R.id.button11);
    // 绑定按钮点击事件处理函数
    button_7.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // 获取蓝牙权限
            getPermision();
            // 初始化各列表
            deviceName.clear();
            arrayList.clear();
            adapter1.notifyDataSetChanged();
            // 获取已绑定蓝牙
            ArrayList<BluetoothDevice> bluetoothDevices = btController.getBondedDeviceList();
            // 更新列表
            for (int i = 0; i < bluetoothDevices.size(); i++){
                BluetoothDevice device = bluetoothDevices.get(i);
                arrayList.add(device.getAddress());
                if (device.getBondState() == 12) {
                    deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n");
                }
                else if (device.getBondState() == 10){
                    deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n");
                }else{
                    deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n");
                }
                adapter1.notifyDataSetChanged();
            }
        }
    });
    

    ListView的列表点击事件

    • 添加点击监听
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    		@Override
    		public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
    		    CharSequence content = ((TextView) view).getText();
    		    String con = content.toString();
    		    String[] conArray = con.split("\n");
    		    String rightStr = conArray[1].substring(5, conArray[1].length());
    		    BluetoothDevice device = btController.find_device(rightStr);
    		    if (device.getBondState() == 10) {
    		        btController.cancelSearch();
    		        String s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对"  + "\n";
    		        deviceName.remove(s);
    		        device.createBond();
    		        s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对"  + "\n";
    		        deviceName.add(s);
    		        adapter1.notifyDataSetChanged();
    		        showToast("配对:" + device.getName());
    		    }
    		    else{
    		        btController.cancelSearch();
    		        String s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
    		        if(deviceName.contains(s2)) {
    		            unpairDevice(device);
    		            deviceName.remove(s2);
    		            s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对"  +"\n";
    		            deviceName.add(s2);
    		            adapter1.notifyDataSetChanged();
    		            showToast("取消配对:" + device.getName());
    		        }
    		    }
    		}
    	});
    }
    
    /**
    * 尝试取消配对
    * @param device
    */
    private void unpairDevice(BluetoothDevice device) {
       try {
           Method m = device.getClass()
                   .getMethod("removeBond", (Class[]) null);
           m.invoke(device, (Object[]) null);
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
    

    MainActivity.java

    package com.example.btapp;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.app.ActivityCompat;
    
    import android.Manifest;
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.os.Build;
    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.ListView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity {
        // 常量
        private static final int REQ_PERMISSION_CODE = 1;
        // 实例化蓝牙控制器
        public BlueToothController btController = new BlueToothController();
        // 弹窗
        private Toast mToast;
        // 蓝牙权限列表
        public ArrayList<String> requestList = new ArrayList<>();
        // 搜索蓝牙广播
        private IntentFilter foundFilter;
        //
        public ArrayAdapter adapter1;
        //定义一个列表,存蓝牙设备的地址。
        public ArrayList<String> arrayList=new ArrayList<>();
        //定义一个列表,存蓝牙设备地址,用于显示。
        public ArrayList<String> deviceName=new ArrayList<>();
        // 蓝牙状态改变广播
        private BroadcastReceiver receiver = new BroadcastReceiver(){
    
            @Override
            public void onReceive(Context context, Intent intent) {
            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            switch (state){
                case BluetoothAdapter.STATE_OFF:
                    showToast("STATE_OFF");
                    break;
                case BluetoothAdapter.STATE_ON:
                    showToast("STATE_ON");
                    break;
                case BluetoothAdapter.STATE_TURNING_OFF:
                    showToast("STATE_TURNING_OFF");
                    break;
                case BluetoothAdapter.STATE_TURNING_ON:
                    showToast("STATE_TURNING_ON");
                    break;
                default:
                    showToast("UnKnow STATE");
                    unregisterReceiver(this);
                    break;
            }
            }
        };
    
        // 搜索蓝牙广播
        private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                String s;
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device.getBondState() == 12) {
                    s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
                }
                else if (device.getBondState() == 10){
                    s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n";
                }else{
                    s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n";
                }
                if (!deviceName.contains(s)) {
                    deviceName.add(s);//将搜索到的蓝牙名称和地址添加到列表。
                    arrayList.add(device.getAddress());//将搜索到的蓝牙地址添加到列表。
                    adapter1.notifyDataSetChanged();//更新
                }
            }else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                showToast("搜索结束");
                unregisterReceiver(this);
            }else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
                showToast("开始搜索");
            }
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 蓝牙状态改变信息
            IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
            // 注册广播
            registerReceiver(receiver, filter);
            //搜索蓝牙的广播
            foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
            foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            // 获取ListView组件
            ListView listView = (ListView) findViewById(R.id.listview1);
            // 实例化ArrayAdapter对象
            adapter1 = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, deviceName);
            // 添加到ListView组件中
            listView.setAdapter(adapter1);
    
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    CharSequence content = ((TextView) view).getText();
                    String con = content.toString();
                    String[] conArray = con.split("\n");
                    String rightStr = conArray[1].substring(5, conArray[1].length());
                    BluetoothDevice device = btController.find_device(rightStr);
                    if (device.getBondState() == 10) {
                        btController.cancelSearch();
                        String s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对"  + "\n";
                        deviceName.remove(s);
                        device.createBond();
                        s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对"  + "\n";
                        deviceName.add(s);
                        adapter1.notifyDataSetChanged();
                        showToast("配对:" + device.getName());
                    }
                    else{
                        btController.cancelSearch();
                        String s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
                        if(deviceName.contains(s2)) {
                            unpairDevice(device);
                            deviceName.remove(s2);
                            s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对"  +"\n";
                            deviceName.add(s2);
                            adapter1.notifyDataSetChanged();
                            showToast("取消配对:" + device.getName());
                        }
                    }
                }
            });
    
            // 通过id获取“是否支持蓝牙”按钮
            Button button_1 = (Button) findViewById(R.id.button3);
            // 绑定按钮点击事件处理函数
            button_1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // 获取蓝牙权限
                    getPermision();
                    // 判断是否支持蓝牙
                    boolean ret = btController.isSupportBlueTooth();
                    // 弹窗显示结果
                    showToast("是否支持蓝牙" + ret);
                }
            });
    
            // 通过id获取“当前蓝牙状态”按钮
            Button button_2 = (Button) findViewById(R.id.button4);
            // 绑定按钮点击事件处理函数
            button_2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // 获取蓝牙权限
                    getPermision();
                    // 判断当前蓝牙状态
                    boolean ret = btController.getBlueToothStatus();
                    // 弹窗显示结果
                    showToast("当前蓝牙状态:" + ret);
                }
            });
    
            // 通过id获取"打开蓝牙"按钮
            Button button_3 = (Button) findViewById(R.id.button7);
            // 绑定按钮点击事件处理函数
            button_3.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    turnONbt();
                }
            });
    
            // 通过id获取”关闭蓝牙“按钮
            Button button_4 = (Button) findViewById(R.id.button8);
            // 绑定按钮点击事件处理函数
            button_4.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // 获取蓝牙权限
                    getPermision();
                    // 关闭蓝牙
                    btController.turnOffBlueTooth();
                }
            });
    
            // 通过id获取”使蓝牙可见“按钮
            Button button_5 = (Button) findViewById(R.id.button9);
            // 绑定按钮点击事件处理函数
            button_5.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // 蓝牙可见
                    BTVisible();
                }
            });
    
            // 通过id获取”搜索可见蓝牙“按钮
            Button button_6 = (Button) findViewById(R.id.button10);
            // 绑定按钮点击事件处理函数
            button_6.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // 获取蓝牙权限
                    getPermision();
                    // 注册广播
                    registerReceiver(bluetoothReceiver, foundFilter);
                    // 初始化各列表
                    arrayList.clear();
                    deviceName.clear();
                    adapter1.notifyDataSetChanged();
                    // 开始搜索
                    btController.findDevice();
                }
            });
    
            // 通过id获取”查看已绑定蓝牙“按钮
            Button button_7 = (Button) findViewById(R.id.button11);
            // 绑定按钮点击事件处理函数
            button_7.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // 获取蓝牙权限
                    getPermision();
                    // 初始化各列表
                    deviceName.clear();
                    arrayList.clear();
                    adapter1.notifyDataSetChanged();
                    // 获取已绑定蓝牙
                    ArrayList<BluetoothDevice> bluetoothDevices = btController.getBondedDeviceList();
                    // 更新列表
                    for (int i = 0; i < bluetoothDevices.size(); i++){
                        BluetoothDevice device = bluetoothDevices.get(i);
                        arrayList.add(device.getAddress());
                        if (device.getBondState() == 12) {
                            deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n");
                        }
                        else if (device.getBondState() == 10){
                            deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n");
                        }else{
                            deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n");
                        }
                        adapter1.notifyDataSetChanged();
                    }
                }
            });
        }
    
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data){
            super.onActivityResult(requestCode, resultCode, data);
            if(resultCode == RESULT_OK){
                showToast("open successfully");
            }
            else{
                showToast("open unsuccessfully");
            }
        }
    
        /**
         * 尝试取消配对
         * @param device
         */
        private void unpairDevice(BluetoothDevice device) {
            try {
                Method m = device.getClass()
                        .getMethod("removeBond", (Class[]) null);
                m.invoke(device, (Object[]) null);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 打开蓝牙
         */
        public void turnONbt(){
            // 获取蓝牙权限
            getPermision();
            // 打开蓝牙
            btController.turnOnBlueTooth(this,1);
        }
    
        /**
         * 设置蓝牙可见
         */
        public void BTVisible(){
            // 获取蓝牙权限
            getPermision();
            // 打开蓝牙可见
            btController.enableVisibly(this);
        }
    
        /**
         * 动态申请权限
         */
        public void getPermision(){
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
                requestList.add(Manifest.permission.BLUETOOTH_SCAN);
                requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);
                requestList.add(Manifest.permission.BLUETOOTH_CONNECT);
                requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);
                requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
                requestList.add(Manifest.permission.BLUETOOTH);
            }
            if(requestList.size() != 0){
                ActivityCompat.requestPermissions(this, requestList.toArray(new String[0]), REQ_PERMISSION_CODE);
            }
        }
    
        /**
         * Toast弹窗显示
         * @param text  显示文本
         */
        public void showToast(String text){
            // 若Toast控件未初始化
            if( mToast == null){
                // 则初始化
                mToast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
            }
            // 否则
            else{
                // 修改显示文本
                mToast.setText(text);
            }
            // 显示
            mToast.show();
        }
    }
    

    list_item.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="18sp"
        >
    
    </TextView>
    

    BlueToothController.java

    package com.example.btapp;
    
    import android.app.Activity;
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothSocket;
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
    import android.widget.Toast;
    
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    
    /**
     * 蓝牙适配器
     */
    public class BlueToothController {
        // 成员变量
        private BluetoothSocket btSocket;
        private BluetoothAdapter mAdapter;
        private String TAG = "";
        public static final int RECV_VIEW = 0;
        public static final int NOTICE_VIEW = 1;
    
        /**
         * 构造函数
         */
        public BlueToothController(){
            // 获取本地的蓝牙适配器
            mAdapter = BluetoothAdapter.getDefaultAdapter();
        }
    
        /**
         * 是否支持蓝牙
         * @return true支持,false不支持
         */
        public boolean isSupportBlueTooth(){
            // 若支持蓝牙,则本地适配器不为null
            if(mAdapter != null){
                return true;
            }
            // 否则不支持
            else{
                return false;
            }
        }
    
        /**
         * 判断当前蓝牙状态
         * @return true为打开,false为关闭
         */
        public boolean getBlueToothStatus(){
            // 断言?为了避免mAdapter为null导致return出错
            assert (mAdapter != null);
            // 蓝牙状态
            return mAdapter.isEnabled();
        }
    
        /**
         * 打开蓝牙
         */
        public void turnOnBlueTooth(Activity activity, int requestCode){
            if(!mAdapter.isEnabled()) {
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                activity.startActivityForResult(intent, requestCode);
            }
        }
    
        /**
         * 关闭蓝牙
         * @return
         */
        public void turnOffBlueTooth() {
            if(mAdapter.isEnabled()) {
                mAdapter.disable();
            }
        }
    
        /**
         * 打开蓝牙可见性
         * @param context
         */
        public void enableVisibly(Context context){
            Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
            context.startActivity(discoverableIntent);
        }
    
        /**
         * 查找设备
         */
        public boolean findDevice(){
            assert(mAdapter!=null);
            if(mAdapter.isDiscovering()){
                mAdapter.cancelDiscovery();
                return false;
            }else {
                return mAdapter.startDiscovery();
            }
        }
    
        /**
         * 获取绑定设备
         * @return
         */
        public ArrayList<BluetoothDevice> getBondedDeviceList(){
            return new ArrayList<BluetoothDevice>(mAdapter.getBondedDevices());
        }
    
        /**
         * 根据蓝牙地址找到相应的设备
         * @param addr
         * @return
         */
        public BluetoothDevice find_device(String addr){
            return mAdapter.getRemoteDevice(addr);
        }
    
        /**
         * 连接设备
         */
        public void connect_init(BluetoothDevice device){
            mAdapter.cancelDiscovery();
            try{
                Method clientMethod = device.getClass().getMethod("createRfcommSocketToServiceRecord", new Class[]{int.class});
                btSocket = (BluetoothSocket)clientMethod.invoke(device, 1);
                connect(btSocket);
    
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        public void connect(final BluetoothSocket btSocket){
            try {
                if (btSocket.isConnected()){
                    Log.e(TAG, "connect: 已经连接");
                    return;
                }
                btSocket.connect();
                if (btSocket.isConnected()){
                    Log.e(TAG, "connect: 连接成功");
                }else{
                    Log.e(TAG, "connect: 连接失败");
                    btSocket.close();
    
                }
            }catch (Exception e){e.printStackTrace();}
        }
    
        public void cancelSearch() {
            mAdapter.cancelDiscovery();
        }
    }
    
    展开全文
  • 这个代码在AndroidStudio上运行之后可以实现扫描wifi和蓝牙的功能,并将结果显示在一个列表中,点击列表可以连接wifi,没密码会直接连接,有密码的话,输入密码就可以连接
  • Android Studio开发蓝牙应用(二)

    千次阅读 热门讨论 2022-01-26 15:11:19
    Android Studio开发蓝牙应用(二) 实现的功能 与蓝牙模块HC-06交换信息 过程 新建Empty Activity 创建布局 activity_btread_and_write.xml <?xml version="1.0" encoding="utf-8"?> <androidx....

    Android Studio开发蓝牙应用(二)

    实现的功能

    • 与蓝牙模块HC-06交换信息

    过程

    • 新建Empty Activity
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
    • 创建布局
      在这里插入图片描述

    activity_btread_and_write.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.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">
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:gravity="fill_vertical"
            android:text="蓝牙状态:"
            android:textSize="24sp"
            app:layout_constraintBottom_toBottomOf="@+id/button6"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <TextView
            android:id="@+id/textView2"
            android:layout_width="152dp"
            android:layout_height="46dp"
            android:gravity="fill_vertical"
            android:text="连接中"
            android:textColor="#00BCD4"
            android:textSize="24sp"
            app:layout_constraintBottom_toBottomOf="@+id/button6"
            app:layout_constraintStart_toEndOf="@+id/textView"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/button6"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="断开/连接"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/textView2"
            app:layout_constraintTop_toTopOf="parent" />
    
        <ListView
            android:id="@+id/listView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@+id/textView4"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.538"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView3" />
    
        <TextView
            android:id="@+id/textView3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="#03A9F4"
            android:gravity="center"
            android:text="接收信息"
            android:textSize="24sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/button6" />
    
        <TextView
            android:id="@+id/textView4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#00BCD4"
            android:gravity="center"
            android:text="发送数据"
            android:textSize="24sp"
            app:layout_constraintBottom_toTopOf="@+id/editTextTextPersonName"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent" />
    
        <EditText
            android:id="@+id/editTextTextPersonName"
            android:layout_width="0dp"
            android:layout_height="49dp"
            android:ems="10"
            android:inputType="textPersonName"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/button7"
            app:layout_constraintStart_toStartOf="parent" />
    
        <Button
            android:id="@+id/button7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="@+id/editTextTextPersonName"
            app:layout_constraintVertical_bias="1.0"
            android:onClick="sead_msg"/>
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    修改之前的listview点击监听事件

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            CharSequence content = ((TextView) view).getText();
            String con = content.toString();
            String[] conArray = con.split("\n");
            String rightStr = conArray[1].substring(5, conArray[1].length());
            BluetoothDevice device = mController.find_device(rightStr);
            if (device.getBondState() == 10) {
                mController.cancelSearch();
                String s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对"  + "\n";
                deviceName.remove(s);
                device.createBond();
                s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对"  + "\n";
                deviceName.add(s);
                adapter1.notifyDataSetChanged();
                showToast("配对:" + device.getName());
            }
            else{
                mController.cancelSearch();
                String s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
                if(deviceName.contains(s2)) {
                    Intent intent = new Intent(MainActivity.this, BTReadAndWrite.class);
                    Bundle bundle = new Bundle();
                    bundle.putString("deviceAddr", device.getAddress());
                    intent.putExtras(bundle);
                    startActivity(intent);
                    finish();
                }
            }
        }
    });
    

    BTReadAndWrite.java

    package com.example.btapp;
    
    import androidx.annotation.NonNull;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.collection.ArraySet;
    import androidx.core.app.ActivityCompat;
    
    import android.Manifest;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothSocket;
    import android.content.Intent;
    import android.os.Build;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    import android.widget.ArrayAdapter;
    import android.widget.EditText;
    import android.widget.ListView;
    import android.widget.TextView;
    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.UUID;
    
    public class BTReadAndWrite extends AppCompatActivity {
        // 需求列表
        private ArrayList<String> requestList = new ArrayList<>();
        // 常量
        private int REQ_PERMISSION_CODE = 1;
        // 蓝牙服务
        private BluetoothSocket bluetoothSocket;
        // 延时创建Toast类,
        private Toast mToast;
        // 实例化BTclient
        private BTclient bTclient = new BTclient();
        // 实例化蓝牙适配器类
        public BlueToothController mController = new BlueToothController();
        // 存放接收数据
        public Byte[] mmbuffer;
        // 消息列表
        public ArrayList<String> msglist = new ArrayList<>();
        // listview控件
        public ListView listView;
        // ArrayAdapter
        public ArrayAdapter adapter1;
        // 读取数据线程
        public readThread readthread = new readThread();
        // 文字输入框
        public EditText editText;
        // 活动间消息传递
        public Handler mHandler;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_btread_and_write);
            // 根据ID获取listview和editText
            listView = (ListView) findViewById(R.id.listView);
            editText = (EditText) findViewById(R.id.editTextTextPersonName);
            // 实例化ArrayAdapter
            adapter1 = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, msglist);
            // 设置listview
            listView.setAdapter(adapter1);
            // 获取intent
            Intent intent = getIntent();
            // 获取intent传来的数据
            Bundle bundle = intent.getExtras();
            // 连接服务
            bTclient.connectDevice(mController.find_device(bundle.getString("deviceAddr")));
            // 服务线程开始
            bTclient.start();
            // 实例化Handler
            mHandler = new Handler(){
                @Override
                public void handleMessage(@NonNull Message msg) {
                    super.handleMessage(msg);
                    switch (msg.what){
                        case 1:
                            String s = msg.obj.toString();
                            msglist.add("接收数据:" + s);
                            adapter1.notifyDataSetChanged();
                    }
                }
            };
        }
    
        public void sead_msg(View view) {
            String s = editText.getText().toString();
            if (s.length() != 0){
                sendMessageHandle(s);
                msglist.add("发送数据:" + s + "\n");
                adapter1.notifyDataSetChanged();
            }
        }
    
        private class BTclient extends Thread{
            private void connectDevice(BluetoothDevice device){
                try {
                    getPermision();
                    bluetoothSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                    bluetoothSocket.connect();
                    readthread.start();
                    showToast("蓝牙连接成功");
                } catch (IOException e) {
                    e.printStackTrace();
                    showToast("蓝牙连接失败");
                }
            }
        }
    
        public void getPermision(){
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
                requestList.add(Manifest.permission.BLUETOOTH_SCAN);
                requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);
                requestList.add(Manifest.permission.BLUETOOTH_CONNECT);
                requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);
                requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
                requestList.add(Manifest.permission.BLUETOOTH);
            }
            if(requestList.size() != 0){
                ActivityCompat.requestPermissions(this, requestList.toArray(new String[0]), REQ_PERMISSION_CODE);
            }
        }
    
        public void showToast(String text){
            if( mToast == null){
                mToast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
            }
            else{
                mToast.setText(text);
            }
            mToast.show();
        }
    
        //发送数据
        public void sendMessageHandle(String msg)
        {
            getPermision();
            if (bluetoothSocket == null)
            {
                showToast("没有连接");
                return;
            }
            try {
                OutputStream os = bluetoothSocket.getOutputStream();
                os.write(msg.getBytes()); //发送出去的值为:msg
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        //读取数据
        private class readThread extends Thread {
            private static final String TAG = "";
    
            public void run() {
                super.run();
                byte[] buffer = new byte[1024];
                int bytes;
                InputStream mmInStream = null;
    
                try {
                    mmInStream = bluetoothSocket.getInputStream();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                while (true) {
                    try {
                        // Read from the InputStream
                        if( (bytes = mmInStream.read(buffer)) > 0 )
                        {
                            byte[] buf_data = new byte[bytes];
                            for(int i=0; i<bytes; i++)
                            {
                                buf_data[i] = buffer[i];
                            }
                            String s = new String(buf_data);//接收的值inputstream 为 s
                            Log.e(TAG, "run: " + s);
                            Message message = Message.obtain();
                            message.what = 1;
                            message.obj = s;
                            mHandler.sendMessage(message);
    
                            if(s.equalsIgnoreCase("o")){ //o表示opend!
                                showToast("open");
                            }
                            else if(s.equalsIgnoreCase("c")){  //c表示closed!
                                showToast("closed");
                            }
                        }
                    } catch (IOException e) {
                        try {
                            mmInStream.close();
                        } catch (IOException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }
                        break;
                    }
                }
            }
        }
    }
    

    蓝牙模块的使用

    • 使用arduino连接HC-06

    HC-06与arduino连接的方式

    • VCC -> 5V
    • GND -> GND
    • TX -> 8
    • RX -> 9
    • arduino程序
    #include <SoftwareSerial.h>
    
    int i = 0;
    SoftwareSerial BT(8, 9);  //新建对象,接收脚为8,发送脚为9
    char val;  //存储接收的变量
    
    void setup() {
      Serial.begin(9600);   //与电脑的串口连接
      Serial.println("BT is ready!");
      BT.begin(9600);  //设置波特率
    }
    
    void loop() {
      //如果串口接收到数据,就输出到蓝牙串口
      if (Serial.available()) {
        val = Serial.read();
        BT.print(val);
      }
    
      //如果接收到蓝牙模块的数据,输出到屏幕
      if (BT.available()) {
        val = BT.read();
        Serial.print(val);
      }
    
      delay(300);
    }
    
    展开全文
  • 因项目需要做一个Android蓝牙app来通过手机蓝牙传输数据以及控制飞行器,... 该应用的Compile Sdk Version 和targetSdkVersion均为26,Min Sdk Version为22,基于Android studio平台开发。 一、声明蓝牙权限 ...

     

     

           因项目需要做一个Android 的蓝牙app来通过手机蓝牙传输数据以及控制飞行器,在此,我对这段时间里写的蓝牙app的代码进行知识梳理和出现错误的总结。

           该应用的Compile Sdk Version 和targetSdkVersion均为26,Min Sdk Version为22,基于Android studio平台开发。

     一、声明蓝牙权限

           首先,要在新建项目中的AndroidManifest.xml中声明两个权限:BLUETOOTH权限和BLUETOOTH_ADMIN权限。其中,BLUETOOTH权限用于请求连接和传送数据;BLUETOOTH_ADMIN权限用于启动设备、发现或进行蓝牙设置,如果要拥有该权限,必须现拥有BLUETOOTH权限。

           其次,因为android 6.0之后采用新的权限机制来保护用户的隐私,如果我们设置的targetSdkVersion大于或等于23,则需要另外添加ACCESS_COARSE_LOCATION和ACCESS_FINE_LOCATION权限,否则,可能会出现搜索不到蓝牙设备的问题。

     

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

     


     二、 启动和关闭蓝牙

    1.首先,要获取BluetoothAdapter蓝牙适配器的对象,然后检测设备是否支持蓝牙。

     

    BluetoothAdapter blueadapter = BluetoothAdapter.getDefaultAdapter();
    //获取蓝牙适配器

     

    if(blueadapter==bull)
    //表示手机不支持蓝牙
    return;

     


    2.启动蓝牙功能:isEnable()方法用来检查蓝牙当前状态,如果方法返回false,则蓝牙没启动。enable()方法用来打开本地蓝牙适配器。

     if (!blueadapter.isEnabled())
            //判断本机蓝牙是否打开
            {//如果没打开,则打开蓝牙
            blueadapter.enable();
            }

     

    3.使用disable()可以关闭本地蓝牙适配器。

     

    三、发现蓝牙设备

    1.开启当前蓝牙的可见性
           Android 设备默认是不能被搜索的,如果想要本机设备可被搜索,可以以BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE动作为startActivity()方法的参数,这个方法会提交一个开启蓝牙可见的请求。默认的情况下,设备在120秒内可以被搜索,也可以自定义一个间隔时间,但是规定的最大值为300秒,0秒则表示设备可以一直被搜索,自定义时间通过EXTRA_DISCOVERABLE_DURATION来定义,代码如下。

    if (blueadapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) //不在可被搜索的范围
            {
            Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//设置本机蓝牙在300秒内可见
            startActivity(discoverableIntent);
            }

     


    2.调用startDiscover()搜索蓝牙

           开启蓝牙后,调用startDiscover()方法搜索蓝牙,注意,只有开启了蓝牙可见性的设备才会响应。该搜索过程为异步操作,调用后讲以广播的机制返回搜索到的对象,搜索的过程一般为12秒,搜索过程页面会显示搜索到的设备。

     

    public void doDiscovry() {
        if (blueadapter.isDiscovering()) {
            //判断蓝牙是否正在扫描,如果是调用取消扫描方法;如果不是,则开始扫描
            blueadapter.cancelDiscovery();
        } else
            blueadapter.startDiscovery();
    
    }

     


    3.注册广播
           通过blueadapter.startDiscovery()来搜索蓝牙设备,要获取到搜索的结果需要注册广播。

     

           定义一个列表

    public ArrayAdapter adapter;
    ListView listView = (ListView) findViewById(R.id.list);//控件 列表

     

     

    //定义一个列表,存蓝牙设备的地址。
    public ArrayList<String> arrayList=new ArrayList<>();
    //定义一个列表,存蓝牙设备地址,用于显示。
    public ArrayList<String> deviceName=new ArrayList<>();

     

     

           将搜索到的显示在控件列表上

    adapter = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, deviceName);
    listView.setAdapter(adapter);

     

     

           定义广播和处理广播消息

    IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);//注册广播接收信号
    registerReceiver(bluetoothReceiver, intentFilter);//用BroadcastReceiver 来取得结果
    
    private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                deviceName.add("设备名:"+device.getName()+"\n" +"设备地址:"+device.getAddress() + "\n");//将搜索到的蓝牙名称和地址添加到列表。
                arrayList.add( device.getAddress());//将搜索到的蓝牙地址添加到列表。
                adapter.notifyDataSetChanged();//更新
            }
        }
     };

     


           搜索完设备后,要记得注销广播。注册后的广播对象在其他地方有强引用,如果不取消,activity会释放不了资源 。

    protected void onDestroy(){
        super.onDestroy();//解除注册
        unregisterReceiver(bluetoothReceiver);
    }



    4.了解targetSdkVersion是否大于或等于23

           若是大于或等于23,除了添加了蓝牙权限外,还要动态获取位置权限,才能将搜索到的蓝牙设备显示出来。若是小于,则不需要动态获取权限。
    动态申请权限,网上例子如下。

     

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    
        if (requestCode == REQUEST_ENABLE_BT) {
            if (resultCode == RESULT_OK) {
                textView.setText("打开蓝牙成功");
            }
            if (resultCode == RESULT_CANCELED) {
                textView.setText("放弃打开蓝牙");
            }
        } else {
            textView.setText("蓝牙异常");
        }
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_COARSE_LOCATION:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                }
                break;
        }
    }

     

     

     四、配对蓝牙设备

           蓝牙的配对和连接有两种方式。一种是每个设备作为一个客户端去连接一个服务端,向对方发起连接。另一种则是作为服务端来接收客户端发来连接的消息。蓝牙之间的数据传输采用的是和TCP传输类似的传输机制。

    1.作为客户端连接
           首先要获取一个代表远程设备BluetoothDevice的对象,然后使用该BluetoothDevice的对象来获取一个BluetoothSocket对象。BluetoothSocket对象调用connect()可以建立连接。

           蓝牙连接整个过程需要在子线程中执行的,并且要将 scoket.connect()放在一个新的子线程中,因为如果将这个方法也放在同一个子线程中解决的话,就会永远报错read failed, socket might closed or timeout, read ret: -1;借鉴网上的方法:再开一个子线程专门执行socket.connect()方法,问题可以解决;

           另外,借鉴网上方法和建议,在获得socket的时候 ,尽量不使用uuid方式;因为这样虽然能够获取到socket 但是不能进行自动,所以使用的前提是已经配对了的设备连接;

           使用反射的方式,能够自动提示配对,也适合手机间通信。

     

    final BluetoothSocket socket = (BluetoothSocket) device.getClass().getDeclaredMethod("createRfcommSocket", new Class[]{int.class}).invoke(device, 1);

     


           代码中的device需要把注册广播时的device作为参数传进线程中。注意,传进来的device的值要为远程设备的地址,若不是或有出入,则可能会出现NullPointerException异常,并提示尝试调用一个空的对象。为了解决这个问题,可以把显示获得的device名字、地址和传入线程的device的地址分在不同的集合类。传入线程的device使用只有设备地址的集合类。

           在连接蓝牙之前,还要先取消蓝牙设备的扫描,否则容易连接失败。

     

    adapter.cancelDiscovery();//adapter为获取到的蓝牙适配器
    socket.connect();//连接

     

     

    2.作为服务端连接
           服务端接收连接需要使用BluetoothServerSocket类,它的作用是监听进来的连接,在一个连接被接收之后,会返回一个BluetoothSocket对象,这个对象可以用来和客户端进行通信。

           与客户端一样,服务端也要在子线程中实现。通过调用listenUsingRfcommWithServiceRecord(String,UUID)方法可以得到一个BluetoothServerSocket的对象,然后再用这个对象来调用accept()来返回一个BluetoothSocket对象。由于accept()是个阻塞的方法,它会直到接收到一个连接或异常之后才会返回,所以要放在子线程中。

     
     
    bluetoothServerSocket=bluetoothAdapter.listenUsingRfcommWithServiceRecord(bluetoothAdapter.getDefaultAdapter().getName(), UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
    //bluetoothServerSocket= (BluetoothServerSocket) bluetoothAdapter.getClass().getMethod("listenUsingRfcommOn",new Class[]{int.class}).invoke(bluetoothAdapter,10);
    socket=bluetoothServerSocket.accept();//接收连接

     


           代码中注释掉的内容是通过反射的方式来接收,由于我使用时出现了异常,所以暂时不考虑这个方法。

           还有,与TCP不同的是,这个连接时只允许一个客户端连接,因此在BluetoothServerSocket对象接收到一个连接请求时就要立刻调用close()方法把服务端关闭。


    五、客户端发送数据

           当两个设备成功连接之后,双方都会有一个BluetoothSocket对象,这时,就可以在设备之间传送数据了。

           1.使用getOutputStream()方法来获取输出流来处理传输。

           2.调用write()。

    os = socket.getOutputStream();//获取输出流
    if (os != null) {//判断输出流是否为空
        os.write(message.getBytes("UTF-8"));
    }
    os.flush();//将输出流的数据强制提交
    os.close();//关闭输出流
    }

     

           将输出流中的数据提交后,要记得关闭输出流,否则,可能会造成只能发送一次数据。

     

    六、服务端接收数据

           1.使用getInputStream()方法来获取输入流来处理传输。

           2.调用read()。

     

       

    InputStream im=null;
    im=bluetoothSocket.getInputStream();
    byte buf[] = new byte[1024];
    if (is != null) {
        is.read(buf, 0, buf.length);//读取发来的数据
        String message = new String(buf);//把发来的数据转化为String类型
        BuletoothMainActivity.UpdateRevMsg(message);//更新信息在显示文本框
        is.close();//关闭输入流

     

     

           使用服务端接收数据时,要先从客户端向服务端发起连接,只有接收到连接请求之后,才会返回一个BluetoothSocket对象。有BluetoothSocket对象才能获取到输入流。

     

           下面是将接收到数据显示在界面的方法:

            在Activity中定义Handler类的对象handler。

    public static void UpdateRevMsg(String revMsg) {
        mRevMsg=revMsg;
        handler.post(RefreshTextView);
    }
    
    private static Runnable RefreshTextView=new Runnable() {
        @Override
        public void run() {
            textView2.setText(mRevMsg);
        }
    };

     

    转载于:https://www.cnblogs.com/lwkdbk/p/9939643.html

    展开全文
  • 根据最新的AS整理,下载可直接运行,一些坑已经写好了
  • app连接蓝牙模块2.0进行互相通讯,使用androidstudio编写,页面相对简单,但是功能完善,蓝牙必须先配对再在app中连接
  • Android Studio开发蓝牙通信

    千次阅读 2020-06-01 20:53:55
    安卓开发-蓝牙通信 功能需求:在微信程序的第一子项中完成“蓝牙聊天功能” 开发步骤: 配置文件注册 设计界面布局 编写用于蓝牙会话的服务组件ChatService 分别建立供主Activity使用的菜单文件res/menu/optionmenu...
  • Android Studio 经典蓝牙实现

    千次阅读 2022-02-14 14:23:11
    Android Studio 经典蓝牙实现
  • ## Android Studio 开发(四)--蓝牙通信

    千次阅读 2021-12-11 17:16:51
    Android Studio 开发(三)–百度地图定位APP 本次Github代码仓库 --crcr1013/MyWechat 文章目录Android Studio 开发(三)--百度地图定位APP一、成果要求二、关键步骤1、工程结构2、清单文件注册权限3、准备设计...
  • 基于Android的BlueTooth开发手机蓝牙蓝牙模块通讯,
  • Android蓝牙串口开发指南
  • 这是很简洁的android 蓝牙和socket的范例,开发环境为android studio
  • android_studio手机蓝牙串口通信源代码,我自己已经下载到手机上调试过,可以用。讲解清楚,十分受用!
  • 一、简介  作为一个纯粹的硬件开发人员,迫不得已开发安卓。前面也花了3天的时候,搭建好了环境,也算是明白了安卓开发的流程。写这个文章的目的也算是做一个...因为我本身是做蓝牙芯片程序开发的,所以不可避免需...
  • android实现蓝牙app代码

    2021-01-04 22:13:13
    本文实例为大家分享了android实现蓝牙app的具体代码,供大家参考,具体内容如下 private BluetoothGatt bluetoothGatt; private BluetoothGattService gattService; private BluetoothGattCharacteristic ...
  • Android studio蓝牙

    千次阅读 2019-04-27 18:39:03
    (Android Studio)Android 手机设备与HC05 蓝牙设备的通信(成功案例+源码) - 谈笑风生不动情 - CSDN博客 https://blog.csdn.net/H2677lucy/article/details/79613707 实现蓝牙HC-05、06与单片机的连接及与手机...
  • AndroidStudio蓝牙通信

    千次阅读 2021-12-13 20:53:08
    openBluetooth蓝牙开启函数4. BlueToothAdapter.java适配器四、运行界面展示五、源码 一、三种近场通信技术的特点 近场通信技术是一种短距离无线通信技术,它允许设备之间进行非接触点对点数据传输和数据交换。近场...
  • 无论是WIFI还是4G网络,建立网络连接后都是访问...Android蓝牙技术提供了4个工具类,分别是蓝牙适配器BluetoothAdapter、蓝牙设备BluetoothDevice、蓝牙服务端套接字BluetoothServerSocket和蓝牙客户端套接字Blueto
  • 遇见到坑爹的队友只有接受现实并且解决问题~ 首先介绍一下网上几乎所有的能搜到的方法: 1.首先,要操作蓝牙,先要在AndroidManifest.xml里加入...uses-permissionandroid:name="android.permission.BLUETOOTH_ADMI...
  • 蓝牙ble调试工具 蓝牙 连接 通信 发送命令 显示硬件端数据 (专注于Android iOS 低功耗设备开发
  • 本代码将蓝牙通信封装在一个API里,资源就在里面。代码实现了手机和蓝牙小车之间的通信
  • Bluetooth Android 蓝牙开发 Android 打开、搜索、配对、连接、通信 发送文字、传输默认文件 <----- Android经典蓝牙 -------->
  • 实现基于Android Studio蓝牙通信的简单应用与开发实现蓝牙通信界面展示核心文件部分代码展示总结 实现蓝牙通信 通过权限申请与代码实现,完成蓝牙通信的简单应用与开发。 界面展示 核心文件 三个主要核心java文件...
  • AndroidStudio开发】(三):蓝牙BLE设备搜索 【AndroidStudio开发】(四):蓝牙BLE设备连接 目录 系列文章目录 前言 二、具体实现 1.获取系统权限 (1)AndroidManifest.xml文件 (2)创建一个文本弹出...
  • 最近公司开发需要用到蓝牙,花了大约一天的时间总结整理了一下。主要是为了以后自己方便看。有需要的朋友可以看下。欢迎一起讨论。后面会带上博客。里面是实现了蓝牙搜索,配对,连接,数据互传。
  • 首先,要操作蓝牙,先要在AndroidManifest.xml里加入权限2.在android.bluetooth包下就这些能用的东西:3.我们一般用的是BluetoothAdapter基本就可以实现需求了:cancelDiscovery() :取消发现,也就是说当我们正在...
  • } //连接蓝牙 public void connectBle(String MAC) { bleManager.connect(MAC, new BleGattCallback() { @Override public void onStartConnect() { } @Override public void onConnectFail(BleDevice bleDevice, ...
  • AndroidStudio芯烨蓝牙打印机打印源码 开发IDE:Android Studio

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,878
精华内容 1,551
关键字:

androidstudio蓝牙开发