【Android探索】基于Android Studio平台的蓝牙遥控APP

本文详细介绍了使用Android Studio和Java开发蓝牙遥控APP的过程,包括工程概念逻辑、控件布局、蓝牙配置、数据交互及实现效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:好久没更新这博客了,接下来有时间记录下前阵子做的东西,当作是复习之余的回顾往事和时间消遣,哈哈。首先是这个蓝牙遥控APP,这个APP是之前做一个小比赛的时候尝试做来玩玩的,主要内容是使用这个APP来与HC05设备进行数据交互然后控制一个灯光云台,虽然最后拿了个小奖,但是毕竟术业有专攻,做的不是很好,也过去一段时间了,下面记录一下主要的实现过程。先有一个整个工程的概念逻辑,逐步完善即是perfect。

 GitHub仓库地址:https://github.com/linzs-online/Bluetooth_App.git 

环境:Android Studio,Android系统

语言:Android、Java

主要实现功能:启动手机蓝牙、搜索蓝牙、蓝牙数据传输

主要技术指标:局限布局、列表、弹出窗口、启动蓝牙……

正文:

这里把整个工程分成两个部分:APP控件布局+主函数code

一、APP控件布局

因为这里使用的是Android Studio,它有一种比较合适小白新手入门的布局方式constraintlayout,这种方式可以直接拖拽空间进入布局界面然后设置限位即可完成布局非常方便,当然有时候它表现得也不是很好(可能是我不会使用),在多控件的时候这个布局会出现一些错位,需要手动调整合适的限位才能正确显示控件位置。

主要的控件有:SeekBar、TextView、Button、Switch

这个布局比较入门没啥好记录的,注意的就是在控件多起来的时候需要通过code来调整位置。还有就是那个SeekBar控件要设置一些初值,如果想要改变颜色的话也可以在交互界面调整,这个AndroidStudio个人感觉做得真的非常好,很人性化小白入门也很快。下面给出布局的code

<?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"
    tools:layout_editor_absoluteY="81dp">

    <SeekBar
        android:id="@+id/Yaw"
        android:layout_width="202dp"
        android:layout_height="21dp"


        android:background="#EFF1F3"
        android:max="355"
        android:progress="0"
        android:secondaryProgress="15"
        app:layout_constraintBottom_toBottomOf="@+id/Yaw_view"
        app:layout_constraintStart_toEndOf="@+id/Yaw_view" />

    <TextView
        android:id="@+id/Yaw_view"
        android:layout_width="129dp"
        android:layout_height="21dp"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginBottom="28dp"
        android:background="#FFFFFF"
        android:text="@string/yaw"
        app:layout_constraintBottom_toTopOf="@+id/light_view"
        app:layout_constraintStart_toStartOf="@+id/light_view" />

    <Button
        android:id="@+id/ADD_BLUETOOTH"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="60dp"
        android:layout_marginRight="60dp"
        android:layout_marginBottom="60dp"
        android:text="@string/Add_bluetooth"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <Button
        android:id="@+id/Scene_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/Sence1"
        app:layout_constraintBottom_toBottomOf="@+id/Scene_2"
        app:layout_constraintEnd_toStartOf="@+id/WorkView"
        app:layout_constraintTop_toTopOf="@+id/Scene_2" />

    <Button
        android:id="@+id/Scene_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="28dp"
        android:text="@string/Sence4"
        app:layout_constraintEnd_toEndOf="@+id/Scene_2"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="@+id/Scene_2"
        app:layout_constraintTop_toBottomOf="@+id/Scene_2" />

    <Button
        android:id="@+id/Scene_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="@string/Scene2"
        app:layout_constraintStart_toEndOf="@+id/WorkView"
        app:layout_constraintTop_toBottomOf="@+id/WorkView" />

    <Button
        android:id="@+id/Scene_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/Sence3"
        app:layout_constraintBottom_toBottomOf="@+id/Scene_4"
        app:layout_constraintEnd_toEndOf="@+id/Scene_1"
        app:layout_constraintStart_toStartOf="@+id/Scene_1"
        app:layout_constraintTop_toTopOf="@+id/Scene_4" />

    <TextView
        android:id="@+id/Pitch_view"
        android:layout_width="129dp"
        android:layout_height="21dp"
        android:background="#FFFFFF"
        android:text="@string/BrightneesResult"
        app:layout_constraintBottom_toBottomOf="@+id/Pitch"
        app:layout_constraintEnd_toEndOf="@+id/Yaw_view"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="@+id/Yaw_view"
        app:layout_constraintTop_toTopOf="@+id/Pitch"
        app:layout_constraintVertical_bias="0.0" />

    <SeekBar
        android:id="@+id/Pitch"
        android:layout_width="204dp"
        android:layout_height="19dp"
        android:layout_marginBottom="24dp"
        android:background="#EFF1F3"
        android:max="60"
        android:progress="0"
        android:secondaryProgress="30"
        app:layout_constraintBottom_toTopOf="@+id/Yaw"
        app:layout_constraintEnd_toEndOf="@+id/Yaw" />

    <Switch
        android:id="@+id/LED_Switch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="76dp"
        android:layout_marginLeft="76dp"
        android:layout_marginBottom="60dp"
        android:text="@string/Switch"
        app:layout_constraintBottom_toBottomOf="@+id/ADD_BLUETOOTH"
        app:layout_constraintEnd_toStartOf="@+id/ADD_BLUETOOTH"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/ADD_BLUETOOTH"
        app:layout_constraintVertical_bias="0.0" />

    <TextView
        android:id="@+id/WorkView"
        android:layout_width="155dp"
        android:layout_height="105dp"
        android:text="@string/workview"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.512"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.002" />

    <SeekBar
        android:id="@+id/light"
        android:layout_width="287dp"
        android:layout_height="17dp"
        android:layout_marginEnd="24dp"
        android:layout_marginRight="24dp"
        android:layout_marginBottom="32dp"
        android:max="100"
        android:progress="0"
        app:layout_constraintBottom_toTopOf="@+id/ADD_BLUETOOTH"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/LED_Switch" />

    <TextView
        android:id="@+id/light_view"
        android:layout_width="69dp"
        android:layout_height="19dp"
        android:text="@string/light_view"
        app:layout_constraintBottom_toBottomOf="@+id/light"
        app:layout_constraintEnd_toStartOf="@+id/light"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/light" />

</androidx.constraintlayout.widget.ConstraintLayout>

二、主函数code

主要有两个Activity、一个是主界面的另一个是连接蓝牙弹窗的listview使用的

1、主界面code

这里主要是对一些控件的初始化,然后申请调用系统的蓝牙,对蓝牙进行一些配置

1)Button等基本控件这里简单一带而过

主要是先定义这个控件

    private Button ADD_BLUETOOTH;
    private Button Scene_1;
    private Button Scene_2;
    private Button Scene_3;
    private Button Scene_4;
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothManager mBluetoothManager;
    private SeekBar Yaw;
    private TextView Yaw_view;
    private TextView Pitch_view;
    private SeekBar Pitch;
    private SeekBar light;
    private TextView light_view;

    private View bluetooth_view;
    private AlertDialog mAlertDialog;
    private ListView listView;
    private Switch LED_Switch;
    private TextView WorkView;

然后找到版面的对应控件,对控件进行初始化配置

private void initView() {
        ADD_BLUETOOTH = (Button) findViewById(R.id.ADD_BLUETOOTH);
        ADD_BLUETOOTH.setOnClickListener(this);
        Scene_1 = (Button) findViewById(R.id.Scene_1);
        Scene_1.setOnClickListener(this);
        Scene_2 = (Button) findViewById(R.id.Scene_2);
        Scene_2.setOnClickListener(this);
        Scene_3 = (Button) findViewById(R.id.Scene_3);
        Scene_3.setOnClickListener(this);
        Scene_4 = (Button) findViewById(R.id.Scene_4);
        Scene_4.setOnClickListener(this);
        LED_Switch = (Switch) findViewById(R.id.LED_Switch);
        LED_Switch.setOnClickListener(this);
        LED_Switch.setOnCheckedChangeListener(this);
        WorkView = (TextView) findViewById(R.id.WorkView);
        WorkView.setOnClickListener(this);
}

然后设置一些点击事件执行函数

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.ADD_BLUETOOTH:
                Add_bluetooth();
                break;
            case R.id.Scene_1:
                Work_Scene_1();
                break;
            case R.id.Scene_2:
                Work_Scene_2();
                break;
            case R.id.Scene_3:
                Work_Scene_3();
                break;
            case R.id.Scene_4:
                Work_Scene_4();
                break;
        }
    }

在系统初始化控件之后就会进入这个点击事件检测,如果触发点击事件就执行相应的Scene函数,触发事件可以直接写入到初始化那个函数里面,这里是使用这种switch case的方式,个人感觉这种结构清晰明了。

除了Bottom控件之外SeekBar控件也要设置相应的触发事件,因为我这里功能定义是要无级调光和调整云台角度,所以我这里的触发事件是拖动条进度改变时调用的,如下:

        light = (SeekBar) findViewById(R.id.light);
        light.setOnClickListener(this);
        light.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            /*拖动条停止拖动时调用 */
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }

            /*拖动条开始拖动时调用*/
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            /* 拖动条进度改变时调用*/
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                light_view.setText("亮度:" + progress );
                msg_buffer[3]=(byte)((progress)>>0*8);
                msg_buffer[4]=(byte)((progress)>>1*8);
                msg_buffer[5]=(byte)((progress)>>2*8);
                msg_buffer[6]=(byte)((progress)>>3*8);
                Write(msg_buffer);
            }
        });
        light_view = (TextView) findViewById(R.id.light_view);
        light_view.setOnClickListener(this);
        light_view.setText("亮度:"+light.getProgress());
除此之外,还可以给控件设定一些初始值,在控件初始化之后调用一次即可
        light.setProgress(50);
        Yaw.setProgress(180);
        Pitch.setProgress(30);

还要初始化弹窗控件AlertDialog,弹窗用于点击添加设备之后弹窗设备搜寻列表展示搜寻设备结果提供联机对象列表

        bluetooth_view = getLayoutInflater().inflate(R.layout.activity_bluetooth_link, null);
        listView = bluetooth_view.findViewById(R.id.blue_list);
        mAlertDialog = new AlertDialog.Builder(this).setTitle("蓝牙设备列表\n")
                .setIcon(R.mipmap.ic_launcher)
                .setView(bluetooth_view)
                .setPositiveButton("取消", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface paramAnonymousDialogInterface,
                                        int paramAnonymousInt) {
                        mBluetoothAdapter.cancelDiscovery();//取消蓝牙扫描
                    }
                }).create();

另外一个Activity和简单,它的作用就是当进入搜索设备准备联机模式时候开启的,主要是一个ListView控件

package com.example.bluetoothsdkapp;

import android.os.Bundle;
import android.widget.ListView;

import androidx.appcompat.app.AppCompatActivity;

public class bluetooth_link extends AppCompatActivity {

    private ListView blue_list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth_link);
        initView();
    }

    private void initView() {
        blue_list = (ListView) findViewById(R.id.blue_list);
    }
}

2)蓝牙配置

首先要定义两个列表,分别用来存蓝牙名称和设备的地址。

    //定义一个列表,存蓝牙名称的地址。
    public ArrayList<String> deviceName = new ArrayList<>();
    //定义一个列表,存蓝牙设备的地址。
    private List<BluetoothDevice> arrayList = new ArrayList<>();

还有配置一些协议和定义客户端模式

//服务和特征值
    private UUID write_UUID_service;
    private UUID write_UUID_chara;
    private UUID read_UUID_service;
    private UUID read_UUID_chara;
    private UUID notify_UUID_service;
    private UUID notify_UUID_chara;
    private UUID indicate_UUID_service;
    private UUID indicate_UUID_chara;
    private final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    private BluetoothDevice selectDevice;
    // 获取到选中设备的客户端串口,全局变量,否则连接在方法执行完就结束了
    private BluetoothSocket clientSocket;
    // 获取到向设备写的输出流,全局变量,否则连接在方法执行完就结束了
    private OutputStream os;
    // 连接对象的名称
    private final String Name = "HC05";
    // 服务端利用线程不断接受客户端信息
    private AcceptThread thread;

然后是蓝牙的初始化函数,申请调用系统蓝牙,然后配置蓝牙相关参数

    public void init_bluetooth() {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();//获取蓝牙适配器
        if (mBluetoothAdapter == null) {//表示手机不支持蓝牙
            finish();
            return;
        }
        if (mBluetoothAdapter.getState() == mBluetoothAdapter.STATE_OFF) {  //打开蓝牙
            mBluetoothAdapter.enable();
        }
        IntentFilter intentFilter = new IntentFilter();//注册广播接收信号
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        intentFilter.addAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        registerReceiver(bluetoothReceiver, intentFilter);//注册,当一个设备被发现时调用bluetoothReceiver
        Toast.makeText(getApplicationContext(), "蓝牙配置初始化成功!", Toast.LENGTH_SHORT).show();
    }

接下来是广播机制接收信号的code

    private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case BluetoothDevice.ACTION_FOUND:  //找到一个设备之后响应
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    //添加名字和地址到list中
                    if (device.getName() != null && arrayList.indexOf(device) == -1) {//防止重复添加
                        deviceName.add("\n" + "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n");
                        arrayList.add(device);//将搜索到的蓝牙地址添加到列表
                        adapter.notifyDataSetChanged();//更新
                    }
                    break;

                case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
                    BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    int state = bluetoothDevice.getBondState();
                    if (state == BluetoothDevice.BOND_BONDED) {
                        Log.e("###", "连接成功");
                    }
                    break;
            }
        }
    };

然后是配置list以及扫描蓝牙设备,添加蓝牙设备到列表中,

  public void Add_bluetooth() {
        mAlertDialog.show();//以弹窗的形式显示蓝牙列表
        if (mBluetoothAdapter.isDiscovering()) {
            //判断蓝牙是否正在扫描,如果是调用取消扫描方法;如果不是,则开始扫描
            mBluetoothAdapter.cancelDiscovery();
        } else {
            mBluetoothAdapter.startDiscovery();
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    mBluetoothAdapter.cancelDiscovery();
                }
            }, 8000);
        }
        adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, deviceName);
        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // 判断当前是否还是正在搜索周边设备,如果是则暂停搜索
                if (mBluetoothAdapter.isDiscovering()) {
                    mBluetoothAdapter.cancelDiscovery();
                }
                // 如果选择设备为空则代表还没有选择设备
                if (selectDevice == null) {
                    selectDevice = arrayList.get(position);
                }
                if (selectDevice.getBondState() == BluetoothDevice.BOND_NONE) {
                    try {
                        Method method = BluetoothDevice.class.getMethod("createBond");//配对
                        Log.d("TAG", "开始配对");
                        method.invoke(selectDevice);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }//配对完成
                }
                // 实例接收客户端传过来的数据线程
                thread = new AcceptThread();
                // 接收线程开始
                thread.start();
                try {
                    // 判断客户端接口是否为空
                    if (clientSocket == null) {
                        // 获取到客户端接口
                        clientSocket = selectDevice.createRfcommSocketToServiceRecord(MY_UUID);
                        // 向服务端发送连接
                        clientSocket.connect();
                        Toast.makeText(getApplicationContext(), "蓝牙连接成功!", Toast.LENGTH_SHORT).show();
                        // 获取到输出流,向外写数据
                        os = clientSocket.getOutputStream();
                        //关闭弹窗
                        mAlertDialog.dismiss();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "蓝牙连接失败!", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

之后就是配置一下数据流模式,以及做一套自定义的数据传送协议即可,我这里是用帧头校验的方式来实现数据交流

    /**
     * 传输数据
     *
     * @param message
     */
    public void Write(byte[] message) {
        try {
            if (os != null) {
                msg_buffer[0]=0x30;
                //String msgString = new String(msgArray);//把Char型转成String发送
                //os.write(msgString.getBytes("utf-8"));
                os.write(message);
            }
            Log.e("OS", "write:" + message);
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(), "写数据失败!", Toast.LENGTH_SHORT).show();
        }
//        //关闭流
//        try {
//            os.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }

之后另开一个线程做数据传送的

    // 服务端,需要监听客户端的线程类
    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };

    // 线程服务类
    public class AcceptThread extends Thread {
        private BluetoothServerSocket serverSocket;
        private BluetoothSocket socket;
        // 输入 输出流
        private OutputStream os;
        private InputStream is;

        public AcceptThread() {
            try {
                serverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(Name, MY_UUID);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            // 截获客户端的蓝牙消息
            try {
                // 接收其客户端的接口
                socket = serverSocket.accept();
                // 获取到输入流
                is = socket.getInputStream();
                // 获取到输出流
                os = socket.getOutputStream();
                // 循环来接收数据
                while (true) {
                    // 创建一个128字节的缓冲
                    byte[] buffer = new byte[128];
                    // 每次读取128字节,并保存其读取的角标
                    int count = is.read(buffer);
                    // 创建Message类,向handler发送数据
                    Message msg = new Message();
                    // 发送一个String的数据,让他向上转型为obj类型
                    msg.obj = new String(buffer, 0, count, "utf-8");
                    // 发送数据
                    handler.sendMessage(msg);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

然后不要忘记了注销Activity的时候关闭蓝牙

    @Override
    protected void onDestroy() {
        super.onDestroy();//解除注册
        unregisterReceiver(bluetoothReceiver);
        mBluetoothAdapter.cancelDiscovery();
        mBluetoothAdapter.disable();
    }

三、效果

第一次接触Android也没认真学习过Java这门语言,做得不是很好,参考了很多前辈的经验,踩了很多坑,算是能够实现自定义蓝牙数据交互APP吧。因为云台拆卸了,没法展示遥控部分,下面是这个APP的一些截图。

### 回答1: Android Studio蓝牙遥控app是一种使用Android Studio开发的应用程序,用于通过蓝牙技术控制其他蓝牙设备。 这个应用程序可以连接到支持蓝牙的设备,如智能手机或电脑。通过蓝牙连接,用户可以发送指令来控制其他蓝牙设备,如机器人、小车或无人机等。 开发这种应用程序的关键是使用Android Studio中的蓝牙API来实现蓝牙连接和数据传输。首先,应用程序需要搜索和发现附近的蓝牙设备,选择要连接的设备,并与其建立蓝牙连接。然后,通过发送和接收数据包,应用程序可以向设备发送控制指令,并获取设备的反馈信息。 在开发过程中,我们可以利用Android Studio提供的工具和库,如蓝牙管理器、蓝牙适配器和蓝牙套接字来实现蓝牙连接和数据传输。同时,我们还可以为用户提供友好的用户界面,如按钮和滑块,用于发送各种控制指令。 在编写代码时,我们需要处理一些键盘或触摸事件来响应用户的操作,并将指令转换为特定的蓝牙数据格式发送给蓝牙设备。同时,我们还需要处理从设备接收到的数据并解析它们以获取有用的信息。 总而言之,Android Studio蓝牙遥控app是一种基于Android Studio开发的应用程序,可通过蓝牙技术连接到其他蓝牙设备,并通过发送和接收数据包来控制这些设备。它提供了一个友好的用户界面和一些关键的API和库来实现蓝牙连接和数据传输。 ### 回答2: Android Studio是一款专门用于开发Android应用程序的集成开发环境。通过Android Studio,可以方便地开发各种功能强大的Android应用,包括蓝牙遥控应用。 蓝牙遥控app是一种可以通过蓝牙技术来控制其他设备的应用程序。通过该应用,用户可以使用自己的Android设备来控制其他设备的功能,例如控制电视、音响、灯光等。 在Android Studio中开发蓝牙遥控app,首先需要进行蓝牙模块的相关设置和初始化。通过使用Android提供的蓝牙API,可以实现蓝牙设备的扫描、连接和数据传输等功能。 在app界面中,可以设计一个简洁直观的用户界面,包括蓝牙设备列表、连接按钮和控制按钮等元素。用户可以通过点击连接按钮来扫描附近的蓝牙设备,并选择要连接的设备。一旦连接成功,用户可以通过点击控制按钮来发送相应的指令给设备,实现对设备功能的控制。 同时,为了增加用户体验,还可以在app中添加一些额外的功能,例如设备状态显示、指令发送记录等。这些功能能够帮助用户更方便地使用蓝牙遥控app,并提供反馈和记录等功能。 总之,通过使用Android Studio,我们可以开发出功能强大且易于使用的蓝牙遥控app。这种应用可以使我们的Android设备成为一个方便实用的蓝牙遥控器,为我们的生活带来更多的便利性和娱乐体验。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值