1. 程式人生 > >android Bluetooth 開發(二):開啟、關閉、搜尋、允許搜尋、檢視

android Bluetooth 開發(二):開啟、關閉、搜尋、允許搜尋、檢視

相關專案的下載連結

繼本專案之後實現了語音識別:點選開啟連結


1.承接上一篇文章,本篇文章主要實現了藍芽的開啟 關閉 允許搜尋 檢視配對裝置


2. BluetoothInit,主要實現了部件的初始化,按鈕的點選事件,通過ListVIew顯示本地配對的藍芽裝置,ListView的點選事件,彈出對話方塊,作為客戶端連線伺服器


package com.example.sacnbluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
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.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class BluetoothInit extends AppCompatActivity implements View.OnClickListener,AdapterView.OnItemClickListener{

    private static final String TAG = BluetoothInit.class.getSimpleName();
    private BluetoothAdapter bluetoothAdapter = null;
    private BluetoothDevice bluetoothDevice = null;
    private Button openButton;
    private Button closeButton;
    private Button pairButton;
    private Button discoverableButton;
    private Button serviceButton;
    private Button clientButton;
    private ArrayAdapter<String> arrayAdapter;
    private ListView deviceListview;
    private List<String> deviceList = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.init_layout);
        initView();
        initBluetooth();
    }
    private void initView(){
        openButton = (Button) findViewById(R.id.open_bluetooth);
        closeButton = (Button) findViewById(R.id.close_bluetooth);
        pairButton = (Button) findViewById(R.id.pair_bluetooth);
        discoverableButton = (Button) findViewById(R.id.discoverable_bluetooth);
        serviceButton = (Button) findViewById(R.id.service_bluetooth);
        clientButton = (Button) findViewById(R.id.client_bluetooth);
        //設定Button監聽事件
        openButton.setOnClickListener(this);
        closeButton.setOnClickListener(this);
        pairButton.setOnClickListener(this);
        discoverableButton.setOnClickListener(this);
        serviceButton.setOnClickListener(this);
        clientButton.setOnClickListener(this);

        arrayAdapter = new ArrayAdapter<String>(BluetoothInit.this,
                android.R.layout.simple_expandable_list_item_1,deviceList);
        deviceListview = (ListView) findViewById(R.id.pair_devices_listview);
        deviceListview.setAdapter(arrayAdapter);
        deviceListview.setOnItemClickListener(this);//設定ListView監聽事件
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    }
    private void initBluetooth(){
        if (bluetoothAdapter != null){
            Log.d(TAG, "onClick: 裝置支援藍芽");
        }else {
            Log.d(TAG, "onClick: 無藍芽裝置");
            return;
        }
    }

    @Override//Button點選事件
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.open_bluetooth:
                if (bluetoothAdapter.isEnabled()){
                    Log.d(TAG, "onClick: 已開啟藍芽");
                    Toast.makeText(BluetoothInit.this,"藍芽已開啟,請不要重複點選",Toast.LENGTH_SHORT).show();
                    deviceList.clear();//清空裝置列表
                    arrayAdapter.notifyDataSetChanged();//更新
                }else {
                    Log.d(TAG, "onClick: 正在開啟藍芽");
                    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);//需要BLUETOOTH許可權
                    startActivityForResult(intent,RESULT_OK);
                    deviceList.clear();//清空裝置列表
                    arrayAdapter.notifyDataSetChanged();//更新
                }
                break;
            case R.id.close_bluetooth:
                if (bluetoothAdapter.isEnabled()){
                    Log.d(TAG, "onClick: 正在關閉藍芽");
                    Toast.makeText(BluetoothInit.this,"藍芽已關閉",Toast.LENGTH_SHORT).show();
                    bluetoothAdapter.disable();//需要BLUETOOTH_ADMIN許可權
                    Log.d(TAG, "onClick: 藍芽已關閉");
                }else {
                    Log.d(TAG, "onClick: 藍芽已關閉");
                    Toast.makeText(BluetoothInit.this,"藍芽已關閉,請不要重複點選",Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.pair_bluetooth:
                if (bluetoothAdapter.isEnabled()){
                    Set<BluetoothDevice> devices = bluetoothAdapter.getBondedDevices();//得到本地藍芽集合
                    deviceList.clear();
                    for (BluetoothDevice device:devices){
                        Log.d(TAG, "MainActivity: "+"名字:"+device.getName()+"\n地址:"+device.getAddress());//得到裝置名字和地址
                        deviceList.add("名字:"+device.getName()+"\n地址:"+device.getAddress());
                        arrayAdapter.notifyDataSetChanged();//更新資料
                    }
                }else {
                    Toast.makeText(BluetoothInit.this,"藍芽未開啟",Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.discoverable_bluetooth:
                Log.d(TAG, "onClick: 可被搜尋");
                Intent discoverable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//請求搜尋
                discoverable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,120);//可被搜尋120s
                startActivity(discoverable);//開始
                break;
            case R.id.service_bluetooth:
                Log.d(TAG, "onClick: 服務端");
                BluetoothMsg.serviceOrCilent = BluetoothMsg.ServerOrCilent.SERVICE;//決定是server還是client
                Intent service = new Intent(BluetoothInit.this,SearchBluetoothDevice.class);
                startActivity(service);
                break;
            case R.id.client_bluetooth:
                Log.d(TAG, "onClick: 客戶端");
                BluetoothMsg.serviceOrCilent = BluetoothMsg.ServerOrCilent.CILENT;//決定是server還是client
                Intent client = new Intent(BluetoothInit.this,SearchBluetoothDevice.class);
                startActivity(client);
                break;
        }
    }

    @Override//ListView點選事件
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        final String message = deviceList.get(position);//得到標籤資訊
        //建立一個對話方塊,並設定標題內容
        AlertDialog.Builder dialog = new AlertDialog.Builder(BluetoothInit.this);
        dialog.setTitle("確認連線");
        dialog.setMessage(message);
        //dialog.setCancelable(true);//進位制返回鍵
        dialog.setPositiveButton("連線", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                BluetoothMsg.serviceOrCilent = BluetoothMsg.ServerOrCilent.CILENT;
                BluetoothMsg.BlueToothAddress = message.substring(message.length()-17);
                if(BluetoothMsg.lastblueToothAddress!=BluetoothMsg.BlueToothAddress){
                    BluetoothMsg.lastblueToothAddress=BluetoothMsg.BlueToothAddress;
                }
                Intent intent = new Intent(BluetoothInit.this,BluetoothChat.class);
                startActivity(intent);
            }
        });
        dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                return;
            }
        });
        dialog.show();//顯示
    }
}
3.SearchBluetoothDevice從BluetoothInit的服務端 客戶端 跳轉的介面,從服務端跳轉,本機便作為服務端,客戶端如同,此介面會顯示當前檢測到的所有裝置,包括配對的,為配對的,可分別實現配對設配的連線,未配對裝置的配對


package com.example.sacnbluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
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.ProgressBar;
import android.widget.Toast;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class SearchBluetoothDevice extends AppCompatActivity implements AdapterView.OnItemClickListener{

    private static final String TAG = SearchBluetoothDevice.class.getSimpleName();

    private BluetoothAdapter bluetoothAdapter = null;
    private Set<BluetoothDevice> setBluetoothDevice;
    private BluetoothDevice bluetoothDevice;
    private DiscoveryBluetoothBroadcast discoveryBroadcast;
    private IntentFilter DiscoveryFilter;
    private ProgressBar startBar;

    private Button searchButton;
    private ArrayAdapter<String> arrayAdapter;
    private ListView deviceListView;
    private List<String> deviceList = new ArrayList<String>();
    private Boolean state = true;//新設配標誌
    private String message = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search_layout);
        initView();
        initBluetooth();
    }
    private void initView(){
        startBar = (ProgressBar) findViewById(R.id.start_discovery_bar);
        searchButton = (Button) findViewById(R.id.start_search_button);
        searchButton.setOnClickListener(new searchButtonClick());
        arrayAdapter = new ArrayAdapter<String>(SearchBluetoothDevice.this,
                android.R.layout.simple_expandable_list_item_1,deviceList);
        deviceListView = (ListView) findViewById(R.id.device_ListView);
        deviceListView.setOnItemClickListener(this);
        deviceListView.setAdapter(arrayAdapter);
    }

    private void initBluetooth(){
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();//藍芽介面卡
        setBluetoothDevice = bluetoothAdapter.getBondedDevices();//得到本地藍芽集合
        discoveryBroadcast = new DiscoveryBluetoothBroadcast();

        DiscoveryFilter = new IntentFilter();
        DiscoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);//添加發現裝置廣播
        DiscoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//開始搜尋
        DiscoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//結束搜尋廣播
        this.registerReceiver(discoveryBroadcast,DiscoveryFilter);
        if (bluetoothAdapter.isDiscovering()){
            bluetoothAdapter.cancelDiscovery();
        }
    }


    public class searchButtonClick implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            Log.d(TAG, "onClick: 開始搜尋");
            if (bluetoothAdapter.isEnabled()){
                if (bluetoothAdapter.isDiscovering()){
                    Toast.makeText(SearchBluetoothDevice.this,"正在搜尋,請不要重複點選",Toast.LENGTH_SHORT).show();
                }else {
                    deviceList.clear();
                    arrayAdapter.notifyDataSetChanged();
                    bluetoothAdapter.startDiscovery();//開始搜尋
                }
            }else {
                Toast.makeText(SearchBluetoothDevice.this,"請開啟藍芽",Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivity(intent);
            }

        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        message = deviceList.get(position);//得到裝置資訊
        String DialogTitle = "確認連線";
        String DialogOk = "連線";
        if (message.indexOf("已配對") > -1){//message中查詢到"已配對"
            DialogTitle = "確認連線";
            DialogOk = "連線";
            state = false;
        }else if (message.indexOf("新裝置") > -1){//message中查詢到"新裝置"
            DialogTitle = "確認配對";
            DialogOk = "配對";
            state = true;
        }
        message = message.substring(4);//擷取第四個字元後面字串
        //建立一個對話方塊,並設定標題內容
        AlertDialog.Builder dialog = new AlertDialog.Builder(SearchBluetoothDevice.this);
        dialog.setTitle(DialogTitle);
        dialog.setMessage(message);
        //dialog.setCancelable(true);//進位制返回鍵
        dialog.setPositiveButton(DialogOk, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                BluetoothMsg.BlueToothAddress = message.substring(message.length()-17);//得到硬體地址
                bluetoothDevice = bluetoothAdapter.getRemoteDevice(BluetoothMsg.BlueToothAddress);//得到遠端裝置
                if (bluetoothAdapter.isDiscovering()){
                    bluetoothAdapter.cancelDiscovery();//正在搜尋就關閉搜尋
                    Toast.makeText(SearchBluetoothDevice.this,"搜尋結束",Toast.LENGTH_SHORT).show();
                }
                if (state == true){//新裝置要配對
                    try{
                        Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
                        createBondMethod.invoke(bluetoothDevice);
                    }catch (Exception e){
                        Log.d(TAG, "onClick: 繫結失敗");
                    }
                }else if (state == false){//舊裝置要連線
                    if(BluetoothMsg.lastblueToothAddress!=BluetoothMsg.BlueToothAddress){
                        BluetoothMsg.lastblueToothAddress=BluetoothMsg.BlueToothAddress;
                    }
                    Intent intent = new Intent(SearchBluetoothDevice.this,BluetoothChat.class);
                    startActivity(intent);
                }
            }
        });
        dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                BluetoothMsg.BlueToothAddress = null;
            }
        });
        dialog.show();//顯示
    }

    //關於發現的廣播
    public class DiscoveryBluetoothBroadcast extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction().toString();
            int bondState;
            switch (action){
                case BluetoothDevice.ACTION_FOUND://發現裝置
                    bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);//得到該裝置
                    bondState = bluetoothDevice.getBondState();//獲得狀態
                    if (bondState == BluetoothDevice.BOND_NONE){
                        Log.d(TAG, "onReceive: "+bluetoothDevice.getName()+"被發現");
                        deviceList.add("新裝置\n"+"名字:"+bluetoothDevice.getName()+"\n地址:"+bluetoothDevice.getAddress());
                        arrayAdapter.notifyDataSetChanged();
                    }else if(bondState == BluetoothDevice.BOND_BONDING){
                        Log.d(TAG, "onReceive: "+bluetoothDevice.getName()+"正在繫結");
                    }else if(bondState == BluetoothDevice.BOND_BONDED){
                        Log.d(TAG, "onReceive: "+bluetoothDevice.getName()+"已繫結");
                        deviceList.add("已配對\n"+"名字:"+bluetoothDevice.getName()+"\n地址:"+bluetoothDevice.getAddress());
                        arrayAdapter.notifyDataSetChanged();
                    }
                    break;
                case BluetoothAdapter.ACTION_DISCOVERY_FINISHED://搜尋結束
                    startBar.setVisibility(View.GONE);
                    searchButton.setText("開始搜尋");
                    break;
                case BluetoothAdapter.ACTION_DISCOVERY_STARTED://搜尋開始
                    startBar.setVisibility(View.VISIBLE);
                    searchButton.setText("正在搜尋...");
                    break;
            }
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        this.unregisterReceiver(discoveryBroadcast);
    }
}

4.上一篇文章地址

android Bluetooth 開發1之佈局和許可權點選開啟連結

5.繼續請看下一篇

 android Bluetooth 開發3之資料通訊介面點選開啟連結