標籤:程式設計語言 藍芽 android
需求:BLE串連和通訊(目前做到-裝置開啟-搜尋裝置-串連裝置)資源:來自網路的一些Demo和官方文檔
:
1-BLE是Android4.3版本以上才提供的API- 一些概念性的東西還是有必要瞭解一下
目前Android真機只能接受和控制產品-也就是client端-server端目前只能是產品-而蘋果方面貌似手機可以作為接收端也可以作為發送端-
基本概念就是中央和周邊--手機作為中央--產品作為周邊--而兩者通過BLE進行串連--
我是這麼理解資訊傳遞的--GATT協議中是以ATT作為基礎的--他們包含的資訊集合是Server -- server裡面可以有很多的characti...而每一個特徵就是我們需要的固定資訊
如果理解有不當的地方可以指出來--畢竟我對於這一塊的理解和認知也才幾天-
2-下面進入正式的講解分段吧
APP的許可權問題==調用藍牙裝置需要聲明的許可權==
<span style="font-size:14px;"><uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /></span>
==有時候我們的APP的各部分功能的實現是以藍芽為基礎的 那麼我們需要說明該裝置僅藍芽適用==
<span style="font-size:14px;"><uses-feature android:name="android.hardware.bluetooth_le" android:required="true" /></span>
3-建立一個新的工程-TestBlueTooth
貼出MainActivity.java的代碼
package com.example.testbluetooth;import java.util.ArrayList;import android.app.Activity;import android.app.ListActivity;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothAdapter.LeScanCallback;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothManager;import android.content.Context;import android.content.Intent;import android.content.pm.PackageManager;import android.os.Bundle;import android.os.Handler;import android.util.Log;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends ListActivity {private final static String TAG = "BlueToohth_Test";private LeDeviceListAdapter mLeDeviceListAdapter;private BluetoothAdapter mBluetoothAdapter;private boolean mScanning;private Handler mHandler;private static final int REQUEST_ENABLE_BT = 1;// Stops scanning after 10 seconds.private static final long SCAN_PERIOD = 10000;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);getActionBar().setTitle(R.string.title_devices);mHandler = new Handler();// 判斷是否支援BLELog.i(TAG, "wheter_support_BLE");if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();finish();}Log.i(TAG, "get_about_BLE_API");final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); if (mBluetoothAdapter == null) { Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show(); finish(); return; }}@Overrideprotected void onResume() {super.onResume();//進行藍芽串連的判斷// Ensures Bluetooth is enabled on the device. If Bluetooth is notLog.i(TAG, "connect_ble");if (!mBluetoothAdapter.isEnabled()) {if (!mBluetoothAdapter.isEnabled()) {Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);}}// Initializes list view adapter.mLeDeviceListAdapter = new LeDeviceListAdapter();setListAdapter(mLeDeviceListAdapter);scanLeDevice(true);}/** * 對搜尋到的藍牙裝置進行現實 * 裝置每一次進行掃描並且獲得裝置會進行一個提示重新整理-通過notifyDataSetChange方法 * @author Admin * */private class LeDeviceListAdapter extends BaseAdapter {private ArrayList<BluetoothDevice> mLeDevices;private LayoutInflater mInflator;public LeDeviceListAdapter() {super();mLeDevices = new ArrayList<BluetoothDevice>();mInflator = MainActivity.this.getLayoutInflater();}//添加裝置進列表中public void addDevice(BluetoothDevice device) {if (!mLeDevices.contains(device)) {mLeDevices.add(device);}}//擷取子項中對應的裝置public BluetoothDevice getDevice(int position) {return mLeDevices.get(position);}//清空列表的資料public void clear() {mLeDevices.clear();}@Overridepublic int getCount() {return mLeDevices.size();}@Overridepublic Object getItem(int i) {return mLeDevices.get(i);}@Overridepublic long getItemId(int i) {return i;}@Overridepublic View getView(int i, View view, ViewGroup viewGroup) {ViewHolder viewHolder;// General ListView optimization code.if (view == null) {view = mInflator.inflate(R.layout.listitem_device, null);viewHolder = new ViewHolder();viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);view.setTag(viewHolder);} else {viewHolder = (ViewHolder) view.getTag();}//對應的裝置進行處理BluetoothDevice device = mLeDevices.get(i);final String deviceName = device.getName();if (deviceName != null && deviceName.length() > 0)viewHolder.deviceName.setText(deviceName);elseviewHolder.deviceName.setText(R.string.unknown_device);viewHolder.deviceAddress.setText(device.getAddress());return view;}}static class ViewHolder {TextView deviceName;TextView deviceAddress;}/** * 掃描裝置 * @param enable */private void scanLeDevice(final boolean enable) { if (enable) { // Stops scanning after a pre-defined scan period. mHandler.postDelayed(new Runnable() { @Override public void run() { mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); invalidateOptionsMenu(); } }, SCAN_PERIOD); mScanning = true; mBluetoothAdapter.startLeScan(mLeScanCallback); } else { mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); } invalidateOptionsMenu();//更新功能表列的資訊 }// 掃描到的藍牙裝置的響應設定 private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { runOnUiThread(new Runnable() { @Override public void run() { mLeDeviceListAdapter.addDevice(device); mLeDeviceListAdapter.notifyDataSetChanged(); } }); } }; @Override protected void onPause() { super.onPause(); scanLeDevice(false); mLeDeviceListAdapter.clear(); } //掃描和暫停選項 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); if (!mScanning) { menu.findItem(R.id.menu_stop).setVisible(false); menu.findItem(R.id.menu_scan).setVisible(true); menu.findItem(R.id.menu_refresh).setActionView(null); } else { menu.findItem(R.id.menu_stop).setVisible(true); menu.findItem(R.id.menu_scan).setVisible(false); menu.findItem(R.id.menu_refresh).setActionView( R.layout.actionbar_indeterminate_progress); } return true; } //點擊事件 @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_scan: mLeDeviceListAdapter.clear(); scanLeDevice(true); break; case R.id.menu_stop: scanLeDevice(false); break; } return true; } /* 對每個子項進行事件的監聽 * @see android.app.ListActivity#onListItemClick(android.widget.ListView, android.view.View, int, long) */ @Override protected void onListItemClick(ListView l, View v, int position, long id) { final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position); if (device == null) return; final Intent intent = new Intent(this, DeviceControlActivity.class); intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME, device.getName()); intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress()); if (mScanning) { mBluetoothAdapter.stopLeScan(mLeScanCallback); mScanning = false; } startActivity(intent); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // User chose not to enable Bluetooth. if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) { finish(); return; } super.onActivityResult(requestCode, resultCode, data); }}
3.1-貼出---listitem_device.xml
</pre><pre name="code" class="java"><pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/device_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="24dp"/> <TextView android:id="@+id/device_address" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="12dp"/></LinearLayout>
未完待續