Android 蓝牙BLE (蓝牙成长之路)4

其实前面的除了service大家最关注的的 可能还是 中间设备和外围设备他们之间的连接问题(PS:这也是我最关心的问题,本人曾经在百度知道里面花重财富,结果有人回答,但是他的回答,不过是百度,粘贴复制而已,并没有对我有太多的帮助)



在这里 我也想说   我目前也仅仅是 看到了demo  具体能不能实现传递通信,,还需要 你们的验证(PS:单片机部分 的蓝牙模块,我目前还没有涉及,公司另有负责,我目前做这个只是了解下,已备到时候用的到时候可以不像上次那样,不知所措,一脸迷茫。。(PS:上家公司 的业务是做商城app。。。。跟蓝牙是不是丝毫不搭边。。。。(PS:人生也有涯 ,学而无止境。。。(PS:卧槽  是不是很押韵)))) 好了  废话不多说   ,代码奉上。。。。(再加上一句:有哪位BLE高手懂我上面的问题   不吝赐教,我财富值奉上)   如下: (代码的注释  我有的有道了下。。。原谅我这屌丝想法)

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import com.example.bledemo.BLEService;
import com.example.bledemo.R;
import com.example.bledemo.SampleGattAttributes;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;

public class ScanDeviceActivity extends Activity {
	private final static String TAG = ScanDeviceActivity.class
			.getSimpleName();
	public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
	public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";

	private TextView mConnectionState;
	private TextView mDataField;
	private String mDeviceName;
	private String mDeviceAddress;
	private ExpandableListView mGattServicesList;  //listview  下拉列表
	private BLEService mBluetoothLeService;
	private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
	private boolean mConnected = false;
	private BluetoothGattCharacteristic mNotifyCharacteristic;

	private final String LIST_NAME = "NAME";
	private final String LIST_UUID = "UUID";

	// Code to manage Service lifecycle.
	//代码管理服务生命周期
	private final ServiceConnection mServiceConnection = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName componentName,
				IBinder service) {
			mBluetoothLeService = ((BLEService.LocalBinder) service)
					.getService();
			if (!mBluetoothLeService.initialize()) {
				Log.e(TAG, "Unable to initialize Bluetooth"); //无法初始化蓝牙
				finish();
			}
			// Automatically connects to the device upon successful start-up
			// initialization.自动连接到设备成功启动初始化
			mBluetoothLeService.connect(mDeviceAddress);
		}

		@Override
		public void onServiceDisconnected(ComponentName componentName) {
			mBluetoothLeService = null;
		}
	};

	// Handles various events fired by the Service.
	// ACTION_GATT_CONNECTED: connected to a GATT server.
	// ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
	// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
	// ACTION_DATA_AVAILABLE: received data from the device. This can be a
	// result of read
	// or notification operations.
	//处理各种事件的发射服务。
	// ACTION_GATT_CONNECTED:连接到一个服务器关贸总协定。
	// ACTION_GATT_DISCONNECTED:从关贸总协定服务器断开连接。
	// ACTION_GATT_SERVICES_DISCOVERED:关贸总协定发现服务。
	// ACTION_DATA_AVAILABLE:从设备接收的数据。这可能是一个
	//读取的结果
	//或通知操作。
	private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
		@TargetApi(Build.VERSION_CODES.HONEYCOMB)
		@SuppressLint("NewApi")
		@Override
		public void onReceive(Context context, Intent intent) {
			final String action = intent.getAction();
			System.out.println("action = " + action);
			// 连接到一个GATT server
			if (BLEService.ACTION_GATT_CONNECTED.equals(action)) {
				mConnected = true;
				updateConnectionState(R.string.connected);
				invalidateOptionsMenu();
				//从GATT server断开连接
			} else if (BLEService.ACTION_GATT_DISCONNECTED
					.equals(action)) {
				mConnected = false;
				updateConnectionState(R.string.disconnected);
				invalidateOptionsMenu();
				clearUI();
				//发现GATT services
			} else if (BLEService.ACTION_GATT_SERVICES_DISCOVERED
					.equals(action)) {
				// Show all the supported services and characteristics on the
				// user interface.
				displayGattServices(mBluetoothLeService
						.getSupportedGattServices());
				// 从设备接收的数据。这可能是一个读取的结果或通知操作。
			} else if (BLEService.ACTION_DATA_AVAILABLE.equals(action)) {
				displayData(intent.getStringExtra(BLEService.EXTRA_DATA));
			}
		}
	};

	// If a given GATT characteristic is selected, check for supported features.
	// This sample
	// demonstrates 'Read' and 'Notify' features. See
	// http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for
	// the complete  下拉列表的点击事件
	// list of supported characteristic features.
	@SuppressLint("NewApi")
	private final ExpandableListView.OnChildClickListener servicesListClickListner = new ExpandableListView.OnChildClickListener() {
		@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
		@SuppressLint("NewApi")
		@Override
		public boolean onChildClick(ExpandableListView parent, View v,
				int groupPosition, int childPosition, long id) {

			if (mGattCharacteristics != null) {
				final BluetoothGattCharacteristic characteristic = mGattCharacteristics
						.get(groupPosition).get(childPosition);
				final int charaProp = characteristic.getProperties();
				System.out.println("charaProp = " + charaProp + ",UUID = "
						+ characteristic.getUuid().toString());
				Random r = new Random();

				if (characteristic.getUuid().toString()
						.equals("0000fff2-0000-1000-8000-00805f9b34fb")) {
						int time= 0;
						while((time=r.nextInt(9))<=0){
							
						}
						
						String data = time+","+"1,,,,,";
						characteristic.setValue(data.getBytes());
						mBluetoothLeService.wirteCharacteristic(characteristic);
				}				
				if (characteristic.getUuid().toString()
						.equals("0000fff1-0000-1000-8000-00805f9b34fb")) {
					int R = r.nextInt(255);
					int G = r.nextInt(255);
					int B = r.nextInt(255);
					int BB = r.nextInt(100);
					String data = R + "," + G + "," + B + "," + BB;
					while (data.length() < 18) {
						data += ",";
					}
					System.out.println(data);
					characteristic.setValue(data.getBytes());
					mBluetoothLeService.wirteCharacteristic(characteristic);
				}
				if (characteristic.getUuid().toString()
						.equals("0000fff3-0000-1000-8000-00805f9b34fb")) {
					int R = r.nextInt(255);
					int G = r.nextInt(255);
					int B = r.nextInt(255);
					int BB = r.nextInt(100);
					String data = R + "," + G + "," + B + "," + BB;
					while (data.length() < 18) {
						data += ",";
					}
					System.out.println("RT");
					characteristic.setValue("RT".getBytes());
					mBluetoothLeService.wirteCharacteristic(characteristic);
				}
				if (characteristic.getUuid().toString()
						.equals("0000fff5-0000-1000-8000-00805f9b34fb")) {
					characteristic.setValue("S".getBytes());
					mBluetoothLeService.wirteCharacteristic(characteristic);
					System.out.println("send S");
				} else {

					if ((charaProp & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
						// If there is an active notification on a
						// characteristic, clear
						// it first so it doesn't update the data field on the
						// user interface.
						if (mNotifyCharacteristic != null) {
							mBluetoothLeService.setCharacteristicNotification(
									mNotifyCharacteristic, false);
							mNotifyCharacteristic = null;
						}
						mBluetoothLeService.readCharacteristic(characteristic);

					}
				}
				if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {

					if (characteristic.getUuid().toString().equals("0000fff6-0000-1000-8000-00805f9b34fb")||characteristic.getUuid().toString().equals("0000fff4-0000-1000-8000-00805f9b34fb")) {
						System.out.println("enable notification");
						mNotifyCharacteristic = characteristic;
						mBluetoothLeService.setCharacteristicNotification(
								characteristic, true);
						
					}
				}

				return true;
			}
			return false;
		}
	};

	private void clearUI() {
		mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);
		mDataField.setText(R.string.no_data);
	}

	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	@SuppressLint("NewApi")
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.scandevice);

		final Intent intent = getIntent();
		mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
		mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);

		// Sets up UI references.设置界面的引用
		((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress);
		mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);
		mGattServicesList.setOnChildClickListener(servicesListClickListner);
		mConnectionState = (TextView) findViewById(R.id.connection_state);
		mDataField = (TextView) findViewById(R.id.data_value);

		getActionBar().setTitle(mDeviceName);
		getActionBar().setDisplayHomeAsUpEnabled(true);
		Intent gattServiceIntent = new Intent(this, BLEService.class);
		boolean bll = bindService(gattServiceIntent, mServiceConnection,
				BIND_AUTO_CREATE);
		if (bll) {
			System.out.println("---------------");
		} else {
			System.out.println("===============");
		}
	}

//在整个Activity的生命周期的onResume状态时,注册广播 ,检查BluetoothLeService 的链接情况,如果空,则链接
	@Override
	protected void onResume() {
		super.onResume();
//		注册广播
		registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
		
		if (mBluetoothLeService != null) {
			final boolean result = mBluetoothLeService.connect(mDeviceAddress);
			Log.d(TAG, "Connect request result=" + result);
		}
	}
//取消注册广播
	@Override
	protected void onPause() {
		super.onPause();
		unregisterReceiver(mGattUpdateReceiver);
	}
//解除 绑定的 service
	@Override
	protected void onDestroy() {
		super.onDestroy();
		unbindService(mServiceConnection);
		mBluetoothLeService = null;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.gatt_services, menu);
		if (mConnected) {
			menu.findItem(R.id.menu_connect).setVisible(false);
			menu.findItem(R.id.menu_disconnect).setVisible(true);
		} else {
			menu.findItem(R.id.menu_connect).setVisible(true);
			menu.findItem(R.id.menu_disconnect).setVisible(false);
		}
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_connect:
			mBluetoothLeService.connect(mDeviceAddress);
			return true;
		case R.id.menu_disconnect:
			mBluetoothLeService.disconnect();
			return true;
		case android.R.id.home:
			onBackPressed();
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	private void updateConnectionState(final int resourceId) {
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				mConnectionState.setText(resourceId);
			}
		});
	}

	private void displayData(String data) {
		if (data != null) {
			mDataField.setText(data);
		}
	}

	// Demonstrates how to iterate through the supported GATT
	@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
	// Services/Characteristics.
	// In this sample, we populate the data structure that is bound to the
	// ExpandableListView
	// on the UI.
	/*
	 * 演示了如何遍历所支持的GATT服务/特征。在这个示例中,我们填充数据结构绑定到ExpandableListView UI
	 */
	@SuppressLint("NewApi")
	private void displayGattServices(List<BluetoothGattService> gattServices) {
		if (gattServices == null)
			return;
		String uuid = null;
		String unknownServiceString = getResources().getString(
				R.string.unknown_service);
		String unknownCharaString = getResources().getString(
				R.string.unknown_characteristic);
		ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
		ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>();
		mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

		// Loops through available GATT Services.
		for (BluetoothGattService gattService : gattServices) {
			HashMap<String, String> currentServiceData = new HashMap<String, String>();
			uuid = gattService.getUuid().toString();
			currentServiceData.put(LIST_NAME,
					SampleGattAttributes.lookup(uuid, unknownServiceString));
			currentServiceData.put(LIST_UUID, uuid);
			gattServiceData.add(currentServiceData);

			ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>();
			List<BluetoothGattCharacteristic> gattCharacteristics = gattService
					.getCharacteristics();
			ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();

			// Loops through available Characteristics.
			for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
				charas.add(gattCharacteristic);
				HashMap<String, String> currentCharaData = new HashMap<String, String>();
				uuid = gattCharacteristic.getUuid().toString();
				currentCharaData.put(LIST_NAME,
						SampleGattAttributes.lookup(uuid, unknownCharaString));
				currentCharaData.put(LIST_UUID, uuid);
				gattCharacteristicGroupData.add(currentCharaData);
			}
			mGattCharacteristics.add(charas);
			gattCharacteristicData.add(gattCharacteristicGroupData);
		}

		SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
				this, gattServiceData,
				android.R.layout.simple_expandable_list_item_2, new String[] {
						LIST_NAME, LIST_UUID }, new int[] { android.R.id.text1,
						android.R.id.text2 }, gattCharacteristicData,
				android.R.layout.simple_expandable_list_item_2, new String[] {
						LIST_NAME, LIST_UUID }, new int[] { android.R.id.text1,
						android.R.id.text2 });
		mGattServicesList.setAdapter(gattServiceAdapter);
	}

// 广播清单  
	private static IntentFilter makeGattUpdateIntentFilter() {
		final IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(BLEService.ACTION_GATT_CONNECTED);
		intentFilter.addAction(BLEService.ACTION_GATT_DISCONNECTED);
		intentFilter.addAction(BLEService.ACTION_GATT_SERVICES_DISCOVERED);
		intentFilter.addAction(BLEService.ACTION_DATA_AVAILABLE);
		return intentFilter;
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值