首頁 > 軟體

Android實現藍芽串列埠通訊

2022-08-15 14:02:46

本文範例為大家分享了Android實現藍芽串列埠通訊的具體程式碼,供大家參考,具體內容如下

最近在弄藍芽串列埠,參考了不少網上的大佬,加上自己早期對C#的學習,寫一個給自己的備忘錄,如果有大佬看到還請多多指教。

1.簡介

Android裝置中提供了一整套藍芽的API,我這邊只取了其中需要的部分。

初期許可權

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

1.BluetoothAdapter

BluetoothAdapter是本地藍芽介面卡的物件,是所有藍芽互動操作的入口。

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
 
 
private BluetoothAdapter mBluetoothAdapter = null;
public ArrayList<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>();
 
 
// 初始化藍芽
private void BlueInit()
{
    // 獲取藍芽介面卡
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    // 請求開啟藍芽
    if (!mBluetoothAdapter.isEnabled()) 
    {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        ((Activity)_context).startActivityForResult(enableBtIntent, 1);
    }
}

這裡我只獲取了已經匹配好的藍芽模組,Android本身自帶搜尋匹配藍芽裝置功能。太麻煩了,還有匹配,還要輸PIN碼。

直接搜尋已經匹配的藍芽模組。

2.BluetoothDevice

表示遠端的藍芽裝置可進行遠端藍芽裝置的連線請求,以及查詢該藍芽裝置的資訊,例如名稱,地址等。

protected void onResume() 
{
    // 將已配對的裝置新增到列表中
    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    deviceList.clear();
    if (pairedDevices.size() > 0) 
    {
        String[] nameList = new String[pairedDevices.size()];
        int i=0;
        for (BluetoothDevice device : pairedDevices)
        {
               deviceList.add(device);
            nameList[i] = device.getName() + "n" + device.getAddress();
            i++;
     }
        //建立一個ArrayAdapter
        ArrayAdapter<?> adapter=new ArrayAdapter<Object>((Activity)_context,android.R.layout.simple_expandable_list_item_1,nameList);
        DeviceView.setAdapter(adapter);
        //註冊一個元素單擊事件監聽方法
        DeviceView.setOnItemClickListener(new DeviceClick());
    }
}

然後直接返回給主表單

//事件按鈕觸發
public class DeviceClick implements AdapterView.OnItemClickListener 
{
    @Override
    public void onItemClick(AdapterView<?> arg0, View view, int position, long id) 
    {
        onConfirmListener.confirm(deviceList.get(position));
    }
         
}
public interface OnConfirmListener 
{
    public void confirm(BluetoothDevice device);
}

這裡其實用了一個Activity的作為一個Dialog。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="bluetoothtoserial.DeviceActivity" >
 
    <ListView
        android:id="@+id/DeviceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >
    </ListView>
</RelativeLayout>

也是方便後面呼叫

package bluetoothtoserial;
 
import java.util.ArrayList;
import java.util.Set;
import android.app.Activity;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
 
public class DeviceActivity extends Dialog 
{
    Context _context;
    public OnConfirmListener onConfirmListener;
    private ListView DeviceView;
    private BluetoothAdapter mBluetoothAdapter = null;
    public ArrayList<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>();
 
    public DeviceActivity(Context context) 
    {
        super(context);
        this._context = context;
        // TODO Auto-generated constructor stub
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_device);
        DeviceView = (ListView)findViewById(R.id.DeviceView);
        BlueInit();
        onResume();
    }
    // 初始化藍芽
    private void BlueInit()
    {
        // 獲取藍芽介面卡
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        // 請求開啟藍芽
        if (!mBluetoothAdapter.isEnabled()) 
        {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            ((Activity)_context).startActivityForResult(enableBtIntent, 1);
        }
    }
    protected void onResume() 
    {
        // 將已配對的裝置新增到列表中
        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        deviceList.clear();
        if (pairedDevices.size() > 0) 
        {
            String[] nameList = new String[pairedDevices.size()];
            int i=0;
            for (BluetoothDevice device : pairedDevices)
            {
                deviceList.add(device);
                nameList[i] = device.getName() + "n" + device.getAddress();
                i++;
            }
            //建立一個ArrayAdapter
            ArrayAdapter<?> adapter=new ArrayAdapter<Object>((Activity)_context,android.R.layout.simple_expandable_list_item_1,nameList);
            DeviceView.setAdapter(adapter);
            //註冊一個元素單擊事件監聽方法
            DeviceView.setOnItemClickListener(new DeviceClick());
        }
    }
    //事件按鈕觸發
      public class DeviceClick implements AdapterView.OnItemClickListener 
      {
        @Override
        public void onItemClick(AdapterView<?> arg0, View view, int position, long id) 
        {
            onConfirmListener.confirm(deviceList.get(position));
        }
          
      }
      public interface OnConfirmListener 
    {
        public void confirm(BluetoothDevice device);
    }
}

3.BluetoothSocket

BluetoothSocket 藍芽的socket介面,與TCP Socket類似,裝置新增完成可以開始連線裝置。

這裡我直接寫了一個Session通訊類

package Channel;
 
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Message;
 
public class Session extends Thread 
{
    private BluetoothDevice _device = null;
    private BluetoothSocket _socket = null;
    private OutputStream _outStream;
    private InputStream _inStream = null; 
    public boolean IsConnect = false;
    public String Name="";
    public String Address="";
    Handler _handler;
    public Session(BluetoothDevice _device,Handler _handler)
    {
        this._handler = _handler;
        this._device = _device;
        this.Name = this._device.getName();
        this.Address = this._device.getAddress();
        IsConnect = false;
        try 
          {
              // 藍芽串列埠服務對應的UUID。如使用的是其它藍芽服務,需更改下面的字串
            // UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
              _socket = _device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
          } catch (Exception e) 
          {
              return;
          }
    }
    public void connect()
    {
        try 
        {
            _socket.connect();
            _outStream = _socket.getOutputStream();
            _inStream = _socket.getInputStream();
            IsConnect = true;
        }
        catch (IOException e) 
        {
            IsConnect = false;
            try {
                _socket.close();
            } catch (IOException e1) 
            {
            }
              return;
        }
    }
    @Override
    public void run() 
    {  
        byte [] buffer = new byte [1024];
        int len = 0;
        while(true) 
        {
             //從InputStream讀取
            try 
            {
                len = _inStream.read(buffer);
            } catch (IOException e) 
            {
                continue;
            }
            if(len> 0)
            { 
                Message msg = _handler.obtainMessage();
                msg.what = 0; 
                try 
                {
                    msg.obj=new String(buffer,"UTF-8");
                } catch (UnsupportedEncodingException e) 
                {
                }
                _handler.sendMessage(msg);
            }
        }
    }
    public void Send(String _value) throws IOException
    {
        _outStream.write(_value.getBytes());
    }
    public void Close() throws IOException
    {
        IsConnect = false;
        _socket.close();
    }
}

接下來就是使用,彈窗選擇裝置。

public void btnDevice_Click(View v)//選擇裝置
{
    final DeviceActivity _deviceDialog = new DeviceActivity(this);
    _deviceDialog.onConfirmListener = new  OnConfirmListener() 
    {
        @Override
        public void confirm(BluetoothDevice device)
        {
            _device = device;
            txtDevice.setText(device.getName()+"n"+device.getAddress());
            _deviceDialog.dismiss();
            btnConnect.setText("連線裝置");
            btnConnect.setVisibility(View.VISIBLE);
            btnSend.setVisibility(View.INVISIBLE);
        }
    };
    _deviceDialog.show();
}

選擇完裝置,建立Session連線裝置。

public void btnConnect_Click(View v)//連線裝置
{
      _session = new Session(_device,_handler);
      setTitle(_session.Name);
      _session.connect();
      if (_session.IsConnect)
      {
          _session.start();
          btnConnect.setVisibility(View.INVISIBLE);
          btnSend.setVisibility(View.VISIBLE);
          btnSend.setText("傳送訊息");
    }
      else
      {
          Toast.makeText(MainActivity.this,
                  "連線失敗",
                  Toast.LENGTH_LONG).show();
          btnSend.setVisibility(View.INVISIBLE);
    }
}

建立回撥函數。

Handler _handler=new Handler(Looper.getMainLooper())
{
    @Override
    public void handleMessage(Message msg)
    {
        super.handleMessage(msg);
        edxMessage.setText(edxMessage.getText()+"n"+msg.obj);
    }
};

傳送訊息。

public void btnSend_Click(View v)//傳送訊息
{
      try
      {
        _session.Send(edxContent.getText().toString());
    } catch (IOException e) 
      {
        Toast.makeText(MainActivity.this,
                  "傳送失敗",
                  Toast.LENGTH_LONG).show();
    }
}

基本上操作就這些。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com