Android Studio 藍芽 示例程式碼(轉)

一贴灵發表於2024-04-23
原文:https://blog.csdn.net/qq_40511184/article/details/122698077
因為android studio升級,下面程式碼中的startactivityresult函式有變化 ,不能使用,需要更換為
public ActivityResultLauncher<Intent> register;
ActivityResultLauncher<Intent> startBlueTooth = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>()
  • 首先在app/src/main/AndroidManifest.xml中新增許可權
Android Studio 藍芽 示例程式碼(轉)
<?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>
View Code
  • Acitivity_main.xml
Android Studio 藍芽 示例程式碼(轉)
<?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>
View Code

MainActivity.java

Android Studio 藍芽 示例程式碼(轉)
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();
    }
}
View Code

list_item.xml

Android Studio 藍芽 示例程式碼(轉)
<?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>
View Code

BlueToothController.java

Android Studio 藍芽 示例程式碼(轉)
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();
    }
}
View Code

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();
   }
}

相關文章