Back to project page accessory-samples.
The source code is released under:
Copyright (c) 2012 Wireless Designs, LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in ...
If you think the Android project accessory-samples listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.example.bluetoothgatt; //from w w w .j av a 2 s .c o m import android.annotation.TargetApi; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.bluetooth.le.BluetoothLeScanner; import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanSettings; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.ParcelUuid; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; /** * Created by Dave Smith * Double Encore, Inc. * BeaconActivity */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public class BeaconLollipopActivity extends Activity { private static final String TAG = "BeaconActivity"; private BluetoothAdapter mBluetoothAdapter; private BluetoothLeScanner mBluetoothLeScanner; /* Collect unique devices discovered, keyed by address */ private HashMap<String, TemperatureBeacon> mBeacons; private BeaconAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setProgressBarIndeterminate(true); /* * We are going to display all the device beacons that we discover * in a list, using a custom adapter implementation */ ListView list = new ListView(this); mAdapter = new BeaconAdapter(this); list.setAdapter(mAdapter); setContentView(list); /* * Bluetooth in Android 4.3+ is accessed via the BluetoothManager, rather than * the old static BluetoothAdapter.getInstance() */ BluetoothManager manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE); mBluetoothAdapter = manager.getAdapter(); mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); mBeacons = new HashMap<String, TemperatureBeacon>(); } @Override protected void onResume() { super.onResume(); /* * We need to enforce that Bluetooth is first enabled, and take the * user to settings to enable it if they have not done so. */ if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { //Bluetooth is disabled Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivity(enableBtIntent); finish(); return; } /* * Check for Bluetooth LE Support. In production, our manifest entry will keep this * from installing on these devices, but this will allow test devices or other * sideloads to report whether or not the feature exists. */ if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this, "No LE Support.", Toast.LENGTH_SHORT).show(); finish(); return; } //Begin scanning for LE devices startScan(); } @Override protected void onPause() { super.onPause(); //Cancel scan in progress stopScan(); } private void startScan() { //Scan for devices advertising the thermometer service ScanFilter beaconFilter = new ScanFilter.Builder() .setServiceUuid(TemperatureBeacon.THERM_SERVICE) .build(); ArrayList<ScanFilter> filters = new ArrayList<ScanFilter>(); filters.add(beaconFilter); ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); mBluetoothLeScanner.startScan(filters, settings, mScanCallback); } private void stopScan() { mBluetoothLeScanner.stopScan(mScanCallback); } private ScanCallback mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { Log.d(TAG, "onScanResult"); processResult(result); } @Override public void onBatchScanResults(List<ScanResult> results) { Log.d(TAG, "onBatchScanResults: "+results.size()+" results"); for (ScanResult result : results) { processResult(result); } } @Override public void onScanFailed(int errorCode) { Log.w(TAG, "LE Scan Failed: "+errorCode); } private void processResult(ScanResult result) { Log.i(TAG, "New LE Device: " + result.getDevice().getName() + " @ " + result.getRssi()); /* * Create a new beacon from the list of obtains AD structures * and pass it up to the main thread */ TemperatureBeacon beacon = new TemperatureBeacon(result.getScanRecord(), result.getDevice().getAddress(), result.getRssi()); mHandler.sendMessage(Message.obtain(null, 0, beacon)); } }; /* * We have a Handler to process scan results on the main thread, * add them to our list adapter, and update the view */ private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { TemperatureBeacon beacon = (TemperatureBeacon) msg.obj; mBeacons.put(beacon.getName(), beacon); mAdapter.setNotifyOnChange(false); mAdapter.clear(); mAdapter.addAll(mBeacons.values()); mAdapter.notifyDataSetChanged(); } }; /* * A custom adapter implementation that displays the TemperatureBeacon * element data in columns, and also varies the text color of each row * by the temperature values of the beacon */ private static class BeaconAdapter extends ArrayAdapter<TemperatureBeacon> { public BeaconAdapter(Context context) { super(context, 0); } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(getContext()) .inflate(R.layout.item_beacon_list, parent, false); } TemperatureBeacon beacon = getItem(position); //Set color based on temperature final int textColor = getTemperatureColor(beacon.getCurrentTemp()); TextView nameView = (TextView) convertView.findViewById(R.id.text_name); nameView.setText(beacon.getName()); nameView.setTextColor(textColor); TextView tempView = (TextView) convertView.findViewById(R.id.text_temperature); tempView.setText(String.format("%.1f\u00B0C", beacon.getCurrentTemp())); tempView.setTextColor(textColor); TextView addressView = (TextView) convertView.findViewById(R.id.text_address); addressView.setText(beacon.getAddress()); addressView.setTextColor(textColor); TextView rssiView = (TextView) convertView.findViewById(R.id.text_rssi); rssiView.setText(String.format("%ddBm", beacon.getSignal())); rssiView.setTextColor(textColor); return convertView; } private int getTemperatureColor(float temperature) { //Color range from 0 - 40 degC float clipped = Math.max(0f, Math.min(40f, temperature)); float scaled = ((40f - clipped) / 40f) * 255f; int blue = Math.round(scaled); int red = 255 - blue; return Color.rgb(red, 0, blue); } } }