Android Studio 的藍(lán)牙串口通信(附Demo源碼下載)

原文鏈接https://www.shanya.world/archives/3a0ead9f.html

Android Studio 的藍(lán)牙串口通信

這次做項(xiàng)目用到了藍(lán)牙串口,折騰了兩天總算弄出來(lái)了,記錄一下方便以后回顧。

獲取相關(guān)權(quán)限

獲取藍(lán)牙權(quán)限

在 AndroidManifest.xml文件中加入如下代碼,(其實(shí)這倆句可以先不加,在工程中寫(xiě)到相應(yīng)語(yǔ)句的時(shí)候可以Alt+Enter添加)

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

再加上定位權(quán)限,這是Android 6.0 以上一定需要注意的地方,同時(shí)最好在代碼里加上判斷是否獲取定位權(quán)限的代碼(就是這個(gè)該死的玩意兒耽誤我好長(zhǎng)時(shí)間)

AndroidManifest.xml中

    <uses-feature android:name="android.hardware.location.gps" />
    <uses-feature
        android:name="android.hardware.bluetooth_le"
        android:required="true" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

判斷是否獲取定位權(quán)限(這里我是寫(xiě)在了掃描未配對(duì)藍(lán)牙設(shè)備的地方,當(dāng)然也可以直接放在程序剛開(kāi)始)

    if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){//未開(kāi)啟定位權(quán)限
            //開(kāi)啟定位權(quán)限,200是標(biāo)識(shí)碼
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},200);
        }else{
            // 顯示其它設(shè)備(未配對(duì)設(shè)備)列表
            findViewById(R.id.textView).setVisibility(View.VISIBLE);

            // 關(guān)閉再進(jìn)行的服務(wù)查找
            if (mBluetoothAdapter.isDiscovering()) {
                mBluetoothAdapter.cancelDiscovery();
            }

            mBluetoothAdapter.startDiscovery();
        }
    }

上述判斷發(fā)現(xiàn)未開(kāi)啟之后會(huì)自動(dòng)回調(diào)函數(shù)區(qū)開(kāi)啟,這里手動(dòng)實(shí)現(xiàn)代碼如下

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case 200:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    doDiscovery();
                }else{
                    finish();
                }
                break;
                default:
        }
    }

權(quán)限方面的事情完了(我并不是在程序剛開(kāi)始的地方考慮的,這一點(diǎn)很不好,后續(xù)版本會(huì)改掉 ,這里就懶得弄了,嘿嘿)

接下來(lái)判斷藍(lán)牙是否打開(kāi)

//如果打不開(kāi)藍(lán)牙提示信息,結(jié)束程序
        if (mBluetoothAdapter == null){
            Toast.makeText(getApplicationContext(),"無(wú)法打開(kāi)手機(jī)藍(lán)牙,請(qǐng)確認(rèn)手機(jī)是否有藍(lán)牙功能!",Toast.LENGTH_SHORT).show();
            finish();
            return;
        }

連接按鈕的響應(yīng)

        final Button connectButton = findViewById(R.id.connectButton);
        connectButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (mBluetoothAdapter.isEnabled() == false) {
                    Toast.makeText(getApplicationContext(), " 請(qǐng)先打開(kāi)藍(lán)牙", Toast.LENGTH_LONG).show();
                    return;
                }

                //如果未連接設(shè)備則打開(kāi)DevicesListActivity搜索設(shè)備
                if (mBluetoothSocket == null) {
                    Intent serveIntent = new Intent(getApplicationContext(), DevicesListActivity.class); //跳轉(zhuǎn)活動(dòng)
                    startActivityForResult(serveIntent, 1); //設(shè)置返回宏定義
                } else {
                    //關(guān)閉連接socket
                    try {
                        bRun = false;
                        Thread.sleep(2000);

                        is.close();
                        mBluetoothSocket.close();
                        mBluetoothSocket = null;

                        connectButton.setText("連接");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }
        });

發(fā)送按鈕響應(yīng)

        Button sendButton = (Button) findViewById(R.id.sendButton);
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                int n = 0;
                if (mBluetoothSocket == null) {
                    Toast.makeText(getApplicationContext(), "請(qǐng)先連接設(shè)備", Toast.LENGTH_SHORT).show();
                    return;
                }
                if (sendEditText.getText().length() == 0) {
                    Toast.makeText(getApplicationContext(), "請(qǐng)先輸入數(shù)據(jù)", Toast.LENGTH_SHORT).show();
                    return;
                }
                try {

                    OutputStream os = mBluetoothSocket.getOutputStream();   //藍(lán)牙連接輸出流
                    byte[] bos = sendEditText.getText().toString().getBytes();
                    for (int i = 0; i < bos.length; i++) {
                        if (bos[i] == 0x0a) n++;
                    }
                    byte[] bos_new = new byte[bos.length + n];
                    n = 0;
                    for (int i = 0; i < bos.length; i++) { //手機(jī)中換行為0a,將其改為0d 0a后再發(fā)送
                        if (bos[i] == 0x0a) {
                            bos_new[n] = 0x0d;
                            n++;
                            bos_new[n] = 0x0a;
                        } else {
                            bos_new[n] = bos[i];
                        }
                        n++;
                    }

                    os.write(bos_new);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

設(shè)備可以被搜索設(shè)置(這里就看個(gè)人需求了,我是沒(méi)用上這個(gè))

        new Thread(){
            public void run(){
                if(mBluetoothAdapter.isEnabled()==false){
                    mBluetoothAdapter.enable();
                }
            }
        }.start();

接收活動(dòng)結(jié)果,主要是掃面活動(dòng)傳來(lái)的連接信息

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 1:     //連接結(jié)果,由DeviceListActivity設(shè)置返回
                // 響應(yīng)返回結(jié)果
                if (resultCode == Activity.RESULT_OK) {   //連接成功,由DeviceListActivity設(shè)置返回
                    // MAC地址,由DeviceListActivity設(shè)置返回
                    String address = data.getExtras().getString(DevicesListActivity.EXTRA_DEVICE_ADDRESS);
                    // 得到藍(lán)牙設(shè)備句柄
                    mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(address);

                    // 用服務(wù)號(hào)得到socket
                    try {
                        mBluetoothSocket = mBluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
                    } catch (IOException e) {
                        Toast.makeText(this, "連接失敗!", Toast.LENGTH_SHORT).show();
                    }
                    //連接socket
                    Button connectButton = findViewById(R.id.connectButton);
                    try {
                        mBluetoothSocket.connect();
                        Toast.makeText(this, "連接" + mBluetoothDevice.getName() + "成功!", Toast.LENGTH_SHORT).show();
                        connectButton.setText("斷開(kāi)");
                    } catch (IOException e) {
                        try {
                            Toast.makeText(this, "連接失??!", Toast.LENGTH_SHORT).show();
                            mBluetoothSocket.close();
                            mBluetoothSocket = null;
                        } catch (IOException ee) {
                            Toast.makeText(this, "連接失?。?, Toast.LENGTH_SHORT).show();
                        }

                        return;
                    }

                    //打開(kāi)接收線程
                    try {
                        is = mBluetoothSocket.getInputStream();   //得到藍(lán)牙數(shù)據(jù)輸入流
                    } catch (IOException e) {
                        Toast.makeText(this, "接收數(shù)據(jù)失??!", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    if (bThread == false) {
                        readThread.start();
                        bThread = true;
                    } else {
                        bRun = true;
                    }
                }
                break;
            default:
                break;
        }
    }

接收線程

//接收數(shù)據(jù)線程
    Thread readThread=new Thread(){

        public void run(){
            int num = 0;
            byte[] buffer = new byte[1024];
            byte[] buffer_new = new byte[1024];
            int i = 0;
            int n = 0;
            bRun = true;
            //接收線程
            while(true){
                try{
                    while(is.available()==0){
                        while(bRun == false){}
                    }
                    while(true){
                        if(!bThread)//跳出循環(huán)
                            return;

                        num = is.read(buffer);         //讀入數(shù)據(jù)
                        n=0;

                        String s0 = new String(buffer,0,num);
                        for(i=0;i<num;i++){
                            if((buffer[i] == 0x0d)&&(buffer[i+1]==0x0a)){
                                buffer_new[n] = 0x0a;
                                i++;
                            }else{
                                buffer_new[n] = buffer[i];
                            }
                            n++;
                        }
                        String s = new String(buffer_new,0,n);
                        smsg+=s;   //寫(xiě)入接收緩存
                        if(is.available()==0)break;  //短時(shí)間沒(méi)有數(shù)據(jù)才跳出進(jìn)行顯示
                    }
                    //發(fā)送顯示消息,進(jìn)行顯示刷新
                    handler.sendMessage(handler.obtainMessage());
                }catch(IOException e){
                }
            }
        }
    };

消息顯示的處理隊(duì)列

    Handler handler= new Handler(){
        public void handleMessage(Message msg){
            super.handleMessage(msg);
            tv_in.setText(smsg);   //顯示數(shù)據(jù)
            scrollView.scrollTo(0,tv_in.getMeasuredHeight()); //跳至數(shù)據(jù)最后一頁(yè)
        }
    };

至此,接收發(fā)送部分已經(jīng)全部結(jié)束,然后就是掃描設(shè)備部分了
這部分我直接貼出整個(gè)活動(dòng)的代碼了 注釋比較齊全 就不嗶嗶了

package com.example.btcontroller;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.app.Activity;
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.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
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.util.Set;

public class DevicesListActivity extends AppCompatActivity {

    private static final String TAG = "DevicesListActivity";
    public static String EXTRA_DEVICE_ADDRESS = "設(shè)備地址";

    //成員域
    private BluetoothAdapter mBluetoothAdapter; //藍(lán)牙適配器
    private ArrayAdapter<String> mPairedDevicesArrayAdapter; //已配對(duì)的設(shè)備適配器
    private ArrayAdapter<String> mUnPairedDevicesArrayAdapter; //未配對(duì)的設(shè)備適配器

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

        //設(shè)定默認(rèn)返回值為取消
        setResult(Activity.RESULT_CANCELED);

        // 初使化設(shè)備適配器存儲(chǔ)數(shù)組
        mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
        mUnPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);

        // 設(shè)置已配隊(duì)設(shè)備列表
        ListView pairedListView = (ListView) findViewById(R.id.pairedListView);
        pairedListView.setAdapter(mPairedDevicesArrayAdapter);
        pairedListView.setOnItemClickListener( mDeviceClickListener);

        // 設(shè)置新查找設(shè)備列表
        ListView newDevicesListView = (ListView) findViewById(R.id.unPairedListView);
        newDevicesListView.setAdapter(mUnPairedDevicesArrayAdapter);
        newDevicesListView.setOnItemClickListener(mDeviceClickListener);

        // 注冊(cè)接收查找到設(shè)備action接收器
        this.registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));

        // 注冊(cè)查找結(jié)束action接收器
        //filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.registerReceiver(mReceiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));

        this.registerReceiver(mReceiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED));

        // 得到本地藍(lán)牙句柄
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        // 得到已配對(duì)藍(lán)牙設(shè)備列表
        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();

        //添加已配對(duì)設(shè)備到列表并顯示
        if (pairedDevices.size() > 0) {
            findViewById(R.id.pairedListView).setVisibility(View.VISIBLE);
            for (BluetoothDevice device : pairedDevices) {
                mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
            }
        } else {
            String noDevices = "沒(méi)有找到已配對(duì)的設(shè)備。" ;
            mPairedDevicesArrayAdapter.add(noDevices);
        }

        //取消按鍵的響應(yīng)函數(shù)
        Button cancelButton = (Button) findViewById(R.id.cancelButton);
        cancelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        // 關(guān)閉服務(wù)查找
        if (mBluetoothAdapter != null) {
            mBluetoothAdapter.cancelDiscovery();
        }

        // 注銷action接收器
        this.unregisterReceiver(mReceiver);
    }

    /**
     * 開(kāi)始服務(wù)和設(shè)備查找
     */
    private void doDiscovery() {
//        if (D) Log.d(TAG, "doDiscovery()");

        // 在窗口顯示查找中信息
        setTitle("查找設(shè)備中...");

        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){//未開(kāi)啟定位權(quán)限
            //開(kāi)啟定位權(quán)限,200是標(biāo)識(shí)碼
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},200);
        }else{
            // 顯示其它設(shè)備(未配對(duì)設(shè)備)列表
            findViewById(R.id.textView).setVisibility(View.VISIBLE);

            // 關(guān)閉再進(jìn)行的服務(wù)查找
            if (mBluetoothAdapter.isDiscovering()) {
                mBluetoothAdapter.cancelDiscovery();
            }

            mBluetoothAdapter.startDiscovery();
        }
    }

    //加載菜單
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main,menu);
        return true;
    }

    //菜單項(xiàng)的響應(yīng)
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case R.id.scanItem:

                doDiscovery();

                break;
                default:
        }
        return true;
    }

    // 選擇設(shè)備響應(yīng)函數(shù)
    private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
            // 準(zhǔn)備連接設(shè)備,關(guān)閉服務(wù)查找
            mBluetoothAdapter.cancelDiscovery();

            // 得到mac地址
            String info = ((TextView) v).getText().toString();
            String address = info.substring(info.length() - 17);

            // 設(shè)置返回?cái)?shù)據(jù)
            Intent intent = new Intent();
            intent.putExtra("設(shè)備地址", address);

            // 設(shè)置返回值并結(jié)束程序
            setResult(Activity.RESULT_OK, intent);
            finish();
        }
    };

    // 查找到設(shè)備和搜索完成action監(jiān)聽(tīng)器
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        // 查找到設(shè)備action
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // 得到藍(lán)牙設(shè)備
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // 如果是已配對(duì)的則略過(guò),已得到顯示,其余的在添加到列表中進(jìn)行顯示
            if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                mUnPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
            }else{  //添加到已配對(duì)設(shè)備列表
                mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
            }
            // 搜索完成action
        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
            setTitle("選擇要連接的設(shè)備");
            if (mUnPairedDevicesArrayAdapter.getCount() == 0) {
                String noDevices = "沒(méi)有找到新設(shè)備";
                mUnPairedDevicesArrayAdapter.add(noDevices);
            }
        }
        }
    };

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case 200:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    doDiscovery();
                }else{
                    finish();
                }
                break;
                default:
        }
    }
}

主活動(dòng)的代碼

package com.example.btcontroller;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    private final static String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";   //SPP服務(wù)UUID號(hào)
    private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); //獲取藍(lán)牙實(shí)例

    private EditText sendEditText; //創(chuàng)建發(fā)送 句柄
    private TextView tv_in; //接收顯示句柄
    private ScrollView scrollView; //翻頁(yè)句柄
    private String smsg = ""; //顯示用數(shù)據(jù)緩存

    BluetoothDevice mBluetoothDevice = null; //藍(lán)牙設(shè)備
    BluetoothSocket mBluetoothSocket = null; //藍(lán)牙通信Socket

    boolean bRun = true; //運(yùn)行狀態(tài)
    boolean bThread = false; //讀取線程狀態(tài)
    private InputStream is;    //輸入流,用來(lái)接收藍(lán)牙數(shù)據(jù)

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

        //獲取控件ID
        sendEditText = findViewById(R.id.sendEditText);
        scrollView = findViewById(R.id.receiveScrolView);
        tv_in = findViewById(R.id.in);

        //如果打不開(kāi)藍(lán)牙提示信息,結(jié)束程序
        if (mBluetoothAdapter == null){
            Toast.makeText(getApplicationContext(),"無(wú)法打開(kāi)手機(jī)藍(lán)牙,請(qǐng)確認(rèn)手機(jī)是否有藍(lán)牙功能!",Toast.LENGTH_SHORT).show();
            finish();
            return;
        }

        //連接按鈕響應(yīng)
        final Button connectButton = findViewById(R.id.connectButton);
        connectButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (mBluetoothAdapter.isEnabled() == false) {
                    Toast.makeText(getApplicationContext(), " 請(qǐng)先打開(kāi)藍(lán)牙", Toast.LENGTH_LONG).show();
                    return;
                }

                //如果未連接設(shè)備則打開(kāi)DevicesListActivity搜索設(shè)備
                if (mBluetoothSocket == null) {
                    Intent serveIntent = new Intent(getApplicationContext(), DevicesListActivity.class); //跳轉(zhuǎn)活動(dòng)
                    startActivityForResult(serveIntent, 1); //設(shè)置返回宏定義
                } else {
                    //關(guān)閉連接socket
                    try {
                        bRun = false;
                        Thread.sleep(2000);

                        is.close();
                        mBluetoothSocket.close();
                        mBluetoothSocket = null;

                        connectButton.setText("連接");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }
        });

        //發(fā)送按鈕響應(yīng)
        Button sendButton = (Button) findViewById(R.id.sendButton);
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                int n = 0;
                if (mBluetoothSocket == null) {
                    Toast.makeText(getApplicationContext(), "請(qǐng)先連接設(shè)備", Toast.LENGTH_SHORT).show();
                    return;
                }
                if (sendEditText.getText().length() == 0) {
                    Toast.makeText(getApplicationContext(), "請(qǐng)先輸入數(shù)據(jù)", Toast.LENGTH_SHORT).show();
                    return;
                }
                try {

                    OutputStream os = mBluetoothSocket.getOutputStream();   //藍(lán)牙連接輸出流
                    byte[] bos = sendEditText.getText().toString().getBytes();
                    for (int i = 0; i < bos.length; i++) {
                        if (bos[i] == 0x0a) n++;
                    }
                    byte[] bos_new = new byte[bos.length + n];
                    n = 0;
                    for (int i = 0; i < bos.length; i++) { //手機(jī)中換行為0a,將其改為0d 0a后再發(fā)送
                        if (bos[i] == 0x0a) {
                            bos_new[n] = 0x0d;
                            n++;
                            bos_new[n] = 0x0a;
                        } else {
                            bos_new[n] = bos[i];
                        }
                        n++;
                    }

                    os.write(bos_new);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });


        // 設(shè)置設(shè)備可以被搜索
        new Thread(){
            public void run(){
                if(mBluetoothAdapter.isEnabled()==false){
                    mBluetoothAdapter.enable();
                }
            }
        }.start();
    }

    //接收活動(dòng)結(jié)果,響應(yīng)startActivityForResult()
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 1:     //連接結(jié)果,由DeviceListActivity設(shè)置返回
                // 響應(yīng)返回結(jié)果
                if (resultCode == Activity.RESULT_OK) {   //連接成功,由DeviceListActivity設(shè)置返回
                    // MAC地址,由DeviceListActivity設(shè)置返回
                    String address = data.getExtras().getString(DevicesListActivity.EXTRA_DEVICE_ADDRESS);
                    // 得到藍(lán)牙設(shè)備句柄
                    mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(address);

                    // 用服務(wù)號(hào)得到socket
                    try {
                        mBluetoothSocket = mBluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
                    } catch (IOException e) {
                        Toast.makeText(this, "連接失敗!", Toast.LENGTH_SHORT).show();
                    }
                    //連接socket
                    Button connectButton = findViewById(R.id.connectButton);
                    try {
                        mBluetoothSocket.connect();
                        Toast.makeText(this, "連接" + mBluetoothDevice.getName() + "成功!", Toast.LENGTH_SHORT).show();
                        connectButton.setText("斷開(kāi)");
                    } catch (IOException e) {
                        try {
                            Toast.makeText(this, "連接失敗!", Toast.LENGTH_SHORT).show();
                            mBluetoothSocket.close();
                            mBluetoothSocket = null;
                        } catch (IOException ee) {
                            Toast.makeText(this, "連接失?。?, Toast.LENGTH_SHORT).show();
                        }

                        return;
                    }

                    //打開(kāi)接收線程
                    try {
                        is = mBluetoothSocket.getInputStream();   //得到藍(lán)牙數(shù)據(jù)輸入流
                    } catch (IOException e) {
                        Toast.makeText(this, "接收數(shù)據(jù)失??!", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    if (bThread == false) {
                        readThread.start();
                        bThread = true;
                    } else {
                        bRun = true;
                    }
                }
                break;
            default:
                break;
        }
    }

    //接收數(shù)據(jù)線程
    Thread readThread=new Thread(){

        public void run(){
            int num = 0;
            byte[] buffer = new byte[1024];
            byte[] buffer_new = new byte[1024];
            int i = 0;
            int n = 0;
            bRun = true;
            //接收線程
            while(true){
                try{
                    while(is.available()==0){
                        while(bRun == false){}
                    }
                    while(true){
                        if(!bThread)//跳出循環(huán)
                            return;

                        num = is.read(buffer);         //讀入數(shù)據(jù)
                        n=0;

                        String s0 = new String(buffer,0,num);
                        for(i=0;i<num;i++){
                            if((buffer[i] == 0x0d)&&(buffer[i+1]==0x0a)){
                                buffer_new[n] = 0x0a;
                                i++;
                            }else{
                                buffer_new[n] = buffer[i];
                            }
                            n++;
                        }
                        String s = new String(buffer_new,0,n);
                        smsg+=s;   //寫(xiě)入接收緩存
                        if(is.available()==0)break;  //短時(shí)間沒(méi)有數(shù)據(jù)才跳出進(jìn)行顯示
                    }
                    //發(fā)送顯示消息,進(jìn)行顯示刷新
                    handler.sendMessage(handler.obtainMessage());
                }catch(IOException e){
                }
            }
        }
    };

    //消息處理隊(duì)列
    Handler handler= new Handler(){
        public void handleMessage(Message msg){
            super.handleMessage(msg);
            tv_in.setText(smsg);   //顯示數(shù)據(jù)
            scrollView.scrollTo(0,tv_in.getMeasuredHeight()); //跳至數(shù)據(jù)最后一頁(yè)
        }
    };

    //關(guān)閉程序掉用處理部分
    public void onDestroy(){
        super.onDestroy();
        if(mBluetoothSocket!=null)  //關(guān)閉連接socket
            try{
                mBluetoothSocket.close();
            }catch(IOException e){}
        //  _bluetooth.disable();  //關(guān)閉藍(lán)牙服務(wù)
    }
}

Demo源碼下載 https://download.csdn.net/download/qq_41121080/11954958

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容