iT邦幫忙

2022 iThome 鐵人賽

DAY 22
3
Mobile Development

Android Studio 30天學習紀錄系列 第 22

Android Studio 30天學習紀錄-Day22 Bluetooth掃描&配對

  • 分享至 

  • xImage
  •  

藍芽是一種無線通訊,可在不同裝置間進行無線連接,用來進行短距離的傳輸,無論是物聯網、電腦周邊(耳機、滑鼠)或手機等都能見到藍芽的影子,而藍芽又可分為傳統藍芽、低功率藍芽(BLE)、高速藍芽三種,那麼首先先加入藍芽需要的權限至Manifest中:

權限

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

UI

接著附上今日UI:

<?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">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="240dp"
        android:onClick="pairDevice"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent" />

    <EditText
        android:id="@+id/editTextTextPersonName"
        android:layout_width="400dp"
        android:layout_height="50dp"
        android:layout_marginBottom="60dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:hint="輸入傳送資料"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="4dp"
        android:onClick="sendData"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Bluetooth

藍芽步驟不外乎是:先打開藍芽->進行掃描->選擇裝置配對->輸入配對密碼->進行連線->資料傳輸...等。
而在studio進行設計時,又分了許多藍芽的object,以我今天用到的部分來說:

  • BluetoothDevice
    代表藍芽設備,通常會包含這個設備的名稱、Mac位址、UUid...等資訊。
    查看更多:BluetoothDevice
  • BluetoothAdapter
    藍芽調配器,可判斷藍芽狀態、支不支援藍芽...等。
    查看更多:BluetoothAdapter
  • BluetoothSocket
    用於進行連線,可取得輸入輸出流以此傳遞資料。
    查看更多:BluetoothSocket
    另外還有像是BluetoothServerSocket的Object等,而低功率的主要可能會有BluetoothGatt接callback做使用,如果有興趣的可以看看此Object的官方文件:BluetoothGatt,那麼就開始設計今天的程式。

MainActivity

首先在ui的按鈕寫入了一個pairDevice的監聽方法,假如點下按鈕時藍芽未啟動,則跳藍芽窗問你是否開啟,若已打開藍芽並按下按鈕,則跳藍芽的掃描頁(權限有加入BLUETOOTH_SCAN便可依此打開掃描頁),註解的部分是直接跳轉手機設定的藍芽掃描頁:

//BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    //配對按鈕
    public void pairDevice(View view) {
        //當藍芽未啟動
        if(!adapter.isEnabled()) {
            Toast.makeText(view.getContext(),"先開權限後再點擊按鈕",Toast.LENGTH_SHORT).show();
            //打開藍芽窗(問你是否打開藍芽)
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);
            startActivity(intent);
        }
        else{
            //藍芽scanner
            Toast.makeText(view.getContext(),"PairDevice",Toast.LENGTH_SHORT).show();
            Intent bluetoothPicker = new Intent("android.bluetooth.devicepicker.action.LAUNCH");
            startActivity(bluetoothPicker);
            /*打開手機設定內的藍芽頁面
            Intent intentSettings = new Intent();
            intentSettings.setAction(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
            startActivity(intentSettings);
            */
        }
    }

與此同時,當我掃描頁選擇了裝置後,要讓他抓到這個設備並使其進行配對(createBond),這邊設計了一個廣播:

//onCreate{
    // bluetooth抓到設備發送廣播
        IntentFilter filter = new IntentFilter("android.bluetooth.devicepicker.action.DEVICE_SELECTED");
        if(receiver!=null) {
            registerReceiver(receiver, filter);//廣播
        }
//}
        //廣播回傳
    private BroadcastReceiver receiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d("taggg",""+action);
            device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            deviceName = device.getName();
            deviceAddress = device.getAddress(); // MAC address
            showDevice.setText("配對裝置:" + deviceName + "\n" + "位址:" + deviceAddress);
            try {
                //回傳的選擇裝置進行配對
                device.createBond();
            } catch (Exception e) {
                Log.e("CreateBondError", e.getMessage());
            }
        }
    };

完整程式碼:

public class MainActivity extends AppCompatActivity {
    private BluetoothDevice device;
    private BluetoothAdapter adapter;
    private String deviceName,deviceAddress;
    private TextView showDevice;
    private EditText dataText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        showDevice = findViewById(R.id.textView);
        dataText = findViewById(R.id.editTextTextPersonName);
        //藍芽調配器
        adapter = BluetoothAdapter.getDefaultAdapter();
        // bluetooth抓到設備發送廣播
        IntentFilter filter = new IntentFilter("android.bluetooth.devicepicker.action.DEVICE_SELECTED");
        if(receiver!=null) {
            registerReceiver(receiver, filter);//廣播
        }
    }
    //廣播回傳
    private BroadcastReceiver receiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d("taggg",""+action);
            device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            deviceName = device.getName();
            deviceAddress = device.getAddress(); // MAC address
            showDevice.setText("配對裝置:" + deviceName + "\n" + "位址:" + deviceAddress);
            try {
                //回傳的選擇裝置進行配對
                device.createBond();
            } catch (Exception e) {
                Log.e("CreateBondError", e.getMessage());
            }
        }
    };
    //配對按鈕
    public void pairDevice(View view) {
        //當藍芽未開啟
        if(!adapter.isEnabled()) {
            Toast.makeText(view.getContext(),"先開權限後再點擊按鈕",Toast.LENGTH_SHORT).show();
            //打開藍芽窗(問你是否打開藍芽)
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);
            startActivity(intent);
        }
        else{
            //藍芽scanner
            Toast.makeText(view.getContext(),"PairDevice",Toast.LENGTH_SHORT).show();
            Intent bluetoothPicker = new Intent("android.bluetooth.devicepicker.action.LAUNCH");
            startActivity(bluetoothPicker);
            /*打開手機藍芽頁面
            Intent intentSettings = new Intent();
            intentSettings.setAction(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
            startActivity(intentSettings);
            */
        }
    }
}

成果

https://ithelp.ithome.com.tw/upload/images/20221003/20139259iIjIPO7jEr.jpg
https://ithelp.ithome.com.tw/upload/images/20221003/20139259W66szgJwYV.jpg
https://ithelp.ithome.com.tw/upload/images/20221003/20139259ub4lMSUgBc.jpg
https://ithelp.ithome.com.tw/upload/images/20221003/20139259NFxO8Ezqll.jpg


上一篇
Android Studio 30天學習紀錄-Day 21 Room
下一篇
Android Studio 30天學習紀錄-Day23 Bluetooth連線
系列文
Android Studio 30天學習紀錄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言