Android實現藍牙串口通訊

本文實例為大傢分享瞭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();
    }
}

基本上操作就這些。

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: