com.filterdevice.ProfileScanningFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.filterdevice.ProfileScanningFragment.java

Source

/*
 * Copyright Cypress Semiconductor Corporation, 2014-2015 All rights reserved.
 * 
 * This software, associated documentation and materials ("Software") is
 * owned by Cypress Semiconductor Corporation ("Cypress") and is
 * protected by and subject to worldwide patent protection (UnitedStates and foreign), United States copyright laws and international
 * treaty provisions. Therefore, unless otherwise specified in a separate license agreement between you and Cypress, this Software
 * must be treated like any other copyrighted material. Reproduction,
 * modification, translation, compilation, or representation of this
 * Software in any other form (e.g., paper, magnetic, optical, silicon)
 * is prohibited without Cypress's express written permission.
 * 
 * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY
 * KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
 * NONINFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE. Cypress reserves the right to make changes
 * to the Software without notice. Cypress does not assume any liability
 * arising out of the application or use of Software or any product or
 * circuit described in the Software. Cypress does not authorize its
 * products for use as critical components in any products where a
 * malfunction or failure may reasonably be expected to result in
 * significant injury or death ("High Risk Product"). By including
 * Cypress's product in a High Risk Product, the manufacturer of such
 * system or application assumes all risk of such use and in doing so
 * indemnifies Cypress against all liability.
 * 
 * Use of this Software may be limited by and subject to the applicable
 * Cypress software license agreement.
 * 
 * 
 */

package com.filterdevice;

import android.app.ActionBar;
import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.SwipeRefreshLayout;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.android.bluetoothlegatt.BluetoothLeService;
import com.example.android.bluetoothlegatt.R;
import com.filterdevice.Constants;
import com.filterdevice.Logger;
import com.filterdevice.Utils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

public class ProfileScanningFragment extends Fragment {

    BluetoothLeService bluetoothLeService = new BluetoothLeService();
    // Stops scanning after 2 seconds.
    private static final long SCAN_PERIOD_TIMEOUT = 5000;
    private Timer mScanTimer;
    private boolean mScanning;

    // Connection time out after 10 seconds.
    private static final long CONNECTION_TIMEOUT = 8000;
    private Timer mConnectTimer;
    private boolean mConnectTimerON = false;

    // Activity request constant
    private static final int REQUEST_ENABLE_BT = 1;

    // device details
    public static String mDeviceName = "name";
    public static String mDeviceAddress = "address";

    //Pair status button and variables
    public static Button mPairButton;

    //Bluetooth adapter
    private static BluetoothAdapter mBluetoothAdapter;

    // Devices list variables
    private static ArrayList<BluetoothDevice> mLeDevices;
    private static int[][] mRssiValues;

    private LeDeviceListAdapter mLeDeviceListAdapter;
    private SwipeRefreshLayout mSwipeLayout;
    private Map<String, Integer> mDevRssiValues;

    //GUI elements
    private ListView mProfileListView;
    private TextView mRefreshText;
    private ProgressDialog mProgressdialog;

    //  Flags
    private boolean mSearchEnabled = false;
    public static boolean isInFragment = false;

    //Delay Time out
    private static final long DELAY_PERIOD = 500;

    /**
     * Call back for BLE Scan
     * This call back is called when a BLE device is found near by.
     */
    byte[] scandata;
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {

        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
            Activity mActivity = getActivity();
            if (mActivity != null) {
                mActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (!mSearchEnabled) {
                            scandata = scanRecord;
                            if (scandata[11] == (byte) 0xF0 && scandata[12] == (byte) 0xFF
                                    && scandata[13] == (byte) 0x0E) {
                                mLeDeviceListAdapter.addDevice(device, rssi);
                                try {
                                    mLeDeviceListAdapter.notifyDataSetChanged();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                });
            }

        }
    };

    /**
     * BroadcastReceiver for receiving the GATT communication status
     */
    private final BroadcastReceiver mGattConnectReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            // Status received when connected to GATT Server
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
                mProgressdialog.setMessage(getString(R.string.alert_message_bluetooth_connect));
                if (mScanning) {
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    mScanning = false;
                }
                mProgressdialog.dismiss();
                mLeDevices.clear();
                if (mConnectTimer != null)
                    mConnectTimer.cancel();
                mConnectTimerON = false;
                updateWithNewFragment();
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                /**
                 * Disconnect event.When the connect timer is ON,Reconnect the device
                 * else show disconnect message
                 */
                if (mConnectTimerON) {
                    bluetoothLeService.reconnect();
                } else {
                    Toast.makeText(getActivity(), R.string.profile_cannot_connect_message, Toast.LENGTH_SHORT)
                            .show();
                }
            }
        }
    };
    /**
     * Textwatcher for filtering the list devices
     */
    private TextWatcher textWatcher = new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            mLeDeviceListAdapter.notifyDataSetInvalidated();
            mLeDeviceListAdapter.getFilter().filter(s.toString());
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View mrootView = inflater.inflate(R.layout.fragment_profile_scan, container, false);
        mDevRssiValues = new HashMap<String, Integer>();
        mSwipeLayout = (SwipeRefreshLayout) mrootView.findViewById(R.id.swipe_container);
        mSwipeLayout.setColorScheme(R.color.dark_blue, R.color.medium_blue, R.color.light_blue, R.color.faint_blue);
        mProfileListView = (ListView) mrootView.findViewById(R.id.listView_profiles);
        mRefreshText = (TextView) mrootView.findViewById(R.id.no_dev);
        mLeDeviceListAdapter = new LeDeviceListAdapter();
        mProfileListView.setAdapter(mLeDeviceListAdapter);
        mProfileListView.setTextFilterEnabled(true);
        setHasOptionsMenu(true);

        mProgressdialog = new ProgressDialog(getActivity());
        mProgressdialog.setCancelable(false);

        checkBleSupportAndInitialize();
        prepareList();

        /**
         * Swipe listener,initiate a new scan on refresh. Stop the swipe refresh
         * after 5 seconds
         */
        mSwipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {

            @Override
            public void onRefresh() {
                if (!mScanning) {
                    // Prepare list view and initiate scanning
                    if (mLeDeviceListAdapter != null) {
                        mLeDeviceListAdapter.clear();
                        try {
                            mLeDeviceListAdapter.notifyDataSetChanged();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    scanLeDevice(true);
                    mScanning = true;
                    mSearchEnabled = false;
                    mRefreshText.setText(getResources().getString(R.string.profile_control_device_scanning));
                }

            }

        });

        /**
         * Creating the dataLogger file and
         * updating the datalogger history
         */
        Logger.createDataLoggerFile(getActivity());
        mProfileListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                if (mLeDeviceListAdapter.getCount() > 0) {
                    final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
                    if (device != null) {
                        scanLeDevice(false);
                        connectDevice(device, true);
                    }
                }
            }
        });

        return mrootView;
    }

    private void checkBleSupportAndInitialize() {
        // Use this check to determine whether BLE is supported on the device.
        if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(getActivity(), R.string.device_ble_not_supported, Toast.LENGTH_SHORT).show();
            getActivity().finish();
        }
        // Initializes a Blue tooth adapter.
        final BluetoothManager bluetoothManager = (BluetoothManager) getActivity()
                .getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();

        if (mBluetoothAdapter == null) {
            // Device does not support Blue tooth
            Toast.makeText(getActivity(), R.string.device_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
            getActivity().finish();
        }
    }

    /**
     * Method to connect to the device selected. The time allotted for having a
     * connection is 8 seconds. After 8 seconds it will disconnect if not
     * connected and initiate scan once more
     *
     * @param device
     */

    private void connectDevice(BluetoothDevice device, boolean isFirstConnect) {
        mDeviceAddress = device.getAddress();
        mDeviceName = device.getName();
        // Get the connection status of the device
        if (bluetoothLeService.getConnectionState() == bluetoothLeService.STATE_DISCONNECTED) {
            Logger.v("BLE DISCONNECTED STATE");
            // Disconnected,so connect
            bluetoothLeService.connect(mDeviceAddress);
            showConnectAlertMessage(mDeviceName, mDeviceAddress);
        } else {
            Logger.v("BLE OTHER STATE-->" + bluetoothLeService.getConnectionState());
            // Connecting to some devices,so disconnect and then connect
            bluetoothLeService.disconnect();
            Handler delayHandler = new Handler();
            delayHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    bluetoothLeService.connect(mDeviceAddress);
                    showConnectAlertMessage(mDeviceName, mDeviceAddress);
                }
            }, DELAY_PERIOD);

        }
        if (isFirstConnect) {
            startConnectTimer();
            mConnectTimerON = true;
        }

    }

    private void showConnectAlertMessage(String devicename, String deviceaddress) {
        mProgressdialog.setTitle(getResources().getString(R.string.alert_message_connect_title));
        mProgressdialog.setMessage(getResources().getString(R.string.alert_message_connect) + "\n" + devicename
                + "\n" + deviceaddress + "\n" + getResources().getString(R.string.alert_message_wait));

        if (!getActivity().isDestroyed() && mProgressdialog != null) {
            mProgressdialog.show();
        }
    }

    /**
     * Method to scan BLE Devices. The status of the scan will be detected in
     * the BluetoothAdapter.LeScanCallback
     *
     * @param enable
     */
    private void scanLeDevice(final boolean enable) {
        if (enable) {
            if (!mScanning) {
                startScanTimer();
                mScanning = true;
                mRefreshText.setText(getResources().getString(R.string.profile_control_device_scanning));
                mBluetoothAdapter.startLeScan(mLeScanCallback);
                mSwipeLayout.setRefreshing(true);
            }
        } else {
            mScanning = false;
            mSwipeLayout.setRefreshing(false);
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }

    }

    /**
     * Preparing the BLE Devicelist
     */
    public void prepareList() {
        // Initializes ActionBar as required
        setUpActionBar();
        // Prepare list view and initiate scanning
        mLeDeviceListAdapter = new LeDeviceListAdapter();
        mProfileListView.setAdapter(mLeDeviceListAdapter);
        scanLeDevice(true);
        mSearchEnabled = false;
    }

    @Override
    public void onResume() {
        super.onResume();
        Logger.e("Scanning onResume");
        isInFragment = true;
        if (checkBluetoothStatus()) {
            prepareList();
        }
        Logger.e("Registering receiver in Profile scannng");
        getActivity().registerReceiver(mGattConnectReceiver, Utils.makeGattUpdateIntentFilter());

    }

    @Override
    public void onPause() {
        Logger.e("Scanning onPause");
        isInFragment = false;
        if (mProgressdialog != null && mProgressdialog.isShowing()) {
            mProgressdialog.dismiss();
        }
        Logger.e("UN Registering receiver in Profile scannng");
        getActivity().unregisterReceiver(mGattConnectReceiver);
        super.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        scanLeDevice(false);
        isInFragment = false;
        if (mLeDeviceListAdapter != null)
            mLeDeviceListAdapter.clear();
        if (mLeDeviceListAdapter != null) {
            try {
                mLeDeviceListAdapter.notifyDataSetChanged();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        mSwipeLayout.setRefreshing(false);
    }

    private void updateWithNewFragment() {
        if (mLeDeviceListAdapter != null) {
            mLeDeviceListAdapter.clear();
            try {
                mLeDeviceListAdapter.notifyDataSetChanged();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //  getActivity().unregisterReceiver(mGattConnectReceiver);
        FragmentManager fragmentManager = getFragmentManager();
        ServiceDiscoveryFragment serviceDiscoveryFragment = new ServiceDiscoveryFragment();
        fragmentManager.beginTransaction()
                .remove(getFragmentManager().findFragmentByTag(Constants.PROFILE_SCANNING_FRAGMENT_TAG)).commit();
        fragmentManager.beginTransaction()
                .replace(R.id.container, serviceDiscoveryFragment, Constants.SERVICE_DISCOVERY_FRAGMENT_TAG)
                .commit();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // User chose not to enable BlueTooth.
        if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
            getActivity().finish();
        } else {
            // Check which request we're responding to
            if (requestCode == REQUEST_ENABLE_BT) {

                // Make sure the request was successful
                if (resultCode == Activity.RESULT_OK) {
                    Toast.makeText(getActivity(), getResources().getString(R.string.device_bluetooth_on),
                            Toast.LENGTH_SHORT).show();
                    mLeDeviceListAdapter = new LeDeviceListAdapter();
                    mProfileListView.setAdapter(mLeDeviceListAdapter);
                    scanLeDevice(true);
                } else {
                    getActivity().finish();
                }
            }
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.clear();
        inflater.inflate(R.menu.global, menu);
        final EditText mEditText = (EditText) menu.findItem(R.id.search).getActionView();
        mEditText.addTextChangedListener(textWatcher);

        MenuItem pairCache = menu.findItem(R.id.pairing);
        if (Utils.getBooleanSharedPreference(getActivity(), Constants.PREF_PAIR_CACHE_STATUS)) {
            pairCache.setChecked(true);
        } else {
            pairCache.setChecked(false);
        }

        MenuItem mSearch = menu.findItem(R.id.search);
        mSearch.setVisible(true);
        mSearch.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                // Do something when collapsed
                View view = getActivity().getCurrentFocus();
                if (view != null) {
                    InputMethodManager imm = (InputMethodManager) getActivity()
                            .getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                }
                Logger.e("Collapsed");
                return true; // Return true to collapse action view
            }

            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                Logger.e("Expanded");
                mEditText.requestFocus();
                View view = getActivity().getCurrentFocus();
                if (view != null) {
                    InputMethodManager inputManager = (InputMethodManager) getActivity()
                            .getSystemService(Context.INPUT_METHOD_SERVICE);
                    inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
                }
                return true; // Return true to expand action view
            }
        });

        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return super.onOptionsItemSelected(item);
    }

    /**
     * Setting up the ActionBar
     */
    void setUpActionBar() {
        ActionBar actionBar = getActivity().getActionBar();
        if (actionBar != null) {
            actionBar.setIcon(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
        }
        if (actionBar != null) {
            actionBar.setTitle(R.string.profile_scan_fragment);
        }
    }

    //For Pairing
    private void pairDevice(BluetoothDevice device) {
        try {
            Method m = device.getClass().getMethod("createBond", (Class[]) null);
            m.invoke(device, (Object[]) null);

        } catch (Exception e) {
            if (mProgressdialog != null && mProgressdialog.isShowing()) {
                mProgressdialog.dismiss();
            }
        }

    }

    //For UnPairing
    private void unpairDevice(BluetoothDevice device) {
        try {
            Method m = device.getClass().getMethod("removeBond", (Class[]) null);
            m.invoke(device, (Object[]) null);

        } catch (Exception e) {
            if (mProgressdialog != null && mProgressdialog.isShowing()) {
                mProgressdialog.dismiss();
            }
        }

    }

    public boolean checkBluetoothStatus() {
        /**
         * Ensures Blue tooth is enabled on the device. If Blue tooth is not
         * currently enabled, fire an intent to display a dialog asking the user
         * to grant permission to enable it.
         */
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            return false;
        }
        return true;
    }

    /**
     * Holder class for the list view view widgets
     */
    static class ViewHolder {
        TextView deviceName;
        TextView deviceAddress;
        TextView deviceRssi;
        Button pairStatus;
    }

    /**
     * Connect Timer
     */
    private void startConnectTimer() {
        mConnectTimer = new Timer();
        mConnectTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                mProgressdialog.dismiss();
                Logger.v("CONNECTION TIME OUT");
                mConnectTimerON = false;
                bluetoothLeService.disconnect();
                if (getActivity() != null) {
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getActivity(), R.string.profile_cannot_connect_message,
                                    Toast.LENGTH_SHORT).show();
                            if (mLeDeviceListAdapter != null)
                                mLeDeviceListAdapter.clear();
                            if (mLeDeviceListAdapter != null) {
                                try {
                                    mLeDeviceListAdapter.notifyDataSetChanged();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                            scanLeDevice(true);
                            mScanning = true;
                        }
                    });
                }

            }
        }, CONNECTION_TIMEOUT);
    }

    public final class ComparatorValues implements Comparator<BluetoothDevice> {

        @Override
        public int compare(BluetoothDevice object1, BluetoothDevice object2) {
            int m1 = mDevRssiValues.get(object1.getAddress());
            int m2 = mDevRssiValues.get(object2.getAddress());
            int result = 0;
            if (m1 > m2) {
                result = -1;
            }
            if (m1 < m2) {
                result = 1;
            }
            return result;
        }

    }

    /**
     * Swipe refresh timer
     */
    public void startScanTimer() {
        mScanTimer = new Timer();
        mScanTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                Collections.sort(mLeDevices, new ComparatorValues());
                sendMessage(0);
                mScanning = false;
                mBluetoothAdapter.stopLeScan(mLeScanCallback);
                mRefreshText.post(new Runnable() {
                    @Override
                    public void run() {
                        mRefreshText.setText(getResources().getString(R.string.profile_control_no_device_message)
                                + ":" + String.valueOf(mLeDevices.size()));
                    }
                });
                mSwipeLayout.setRefreshing(false);
                scanLeDevice(false);
            }
        }, SCAN_PERIOD_TIMEOUT);
    }

    /**
     * List Adapter for holding devices found through scanning.
     */
    private class LeDeviceListAdapter extends BaseAdapter implements Filterable {

        ArrayList<BluetoothDevice> mFilteredDevices = new ArrayList<BluetoothDevice>();
        private LayoutInflater mInflator;
        private int rssiValue;
        private ItemFilter mFilter = new ItemFilter();

        public LeDeviceListAdapter() {
            super();
            mLeDevices = new ArrayList<BluetoothDevice>();
            mInflator = getActivity().getLayoutInflater();
        }

        private void addDevice(BluetoothDevice device, int rssi) {
            this.rssiValue = rssi;
            // New device found
            if (!mLeDevices.contains(device)) {
                if (mDevRssiValues.get(device.getAddress()) != null) {
                    mDevRssiValues.put(device.getAddress(), (mDevRssiValues.get(device.getAddress()) + rssi) / 2);
                } else {
                    mDevRssiValues.put(device.getAddress(), rssi);
                }
                if (rssi > -70) {
                    if (device.getAddress().equals("D0:B5:C2:8D:7C:E7")
                            || device.getAddress().equals("D0:B5:C2:8F:A2:DC")
                            || device.getAddress().equals("D0:B5:C2:8F:A5:9E")
                            || device.getAddress().equals("D0:B5:C2:8F:A3:0B")
                            || device.getAddress().equals("7C:EC:79:D4:83:AE")
                            || device.getAddress().equals("7C:EC:79:D4:65:9D")
                            || device.getAddress().equals("D0:B5:C2:8D:7A:AE")
                            || device.getAddress().equals("D0:B5:C2:8F:A5:0A")
                            || device.getAddress().equals("D0:B5:C2:8F:A5:E3")
                            || device.getAddress().equals("D0:B5:C2:8D:7A:A3")) {
                        mLeDevices.add(device);
                    }
                }
            } else {
                mDevRssiValues.put(device.getAddress(), rssi);
                if (rssi < -60) {
                    mLeDevices.remove(mLeDevices.indexOf(device));
                }
            }
            if (device.getAddress().equals("D0:B5:C2:8D:7C:E7") || device.getAddress().equals("D0:B5:C2:8F:A2:DC")
                    || device.getAddress().equals("D0:B5:C2:8F:A5:9E")
                    || device.getAddress().equals("D0:B5:C2:8F:A3:0B")
                    || device.getAddress().equals("7C:EC:79:D4:83:AE")
                    || device.getAddress().equals("7C:EC:79:D4:65:9D")
                    || device.getAddress().equals("D0:B5:C2:8D:7A:AE")
                    || device.getAddress().equals("D0:B5:C2:8F:A5:0A")
                    || device.getAddress().equals("D0:B5:C2:8F:A5:E3")
                    || device.getAddress().equals("D0:B5:C2:8D:7A:A3")) {
                Log.i("RSSI", String.valueOf(rssi));
            }
        }

        public int getRssiValue() {
            return rssiValue;
        }

        /**
         * Getter method to get the blue tooth device
         *
         * @param position
         * @return BluetoothDevice
         */
        public BluetoothDevice getDevice(int position) {
            return mLeDevices.get(position);
        }

        /**
         * Clearing all values in the device array list
         */
        public void clear() {
            mLeDevices.clear();
        }

        @Override
        public int getCount() {
            return mLeDevices.size();
        }

        @Override
        public Object getItem(int i) {
            return mLeDevices.get(i);
        }

        @Override
        public long getItemId(int i) {
            return i;
        }

        @Override
        public View getView(final int position, View view, ViewGroup viewGroup) {
            final ViewHolder viewHolder;
            // General ListView optimization code.
            if (view == null) {
                view = mInflator.inflate(R.layout.listitem_device, viewGroup, false);
                viewHolder = new ViewHolder();
                viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
                viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
                viewHolder.deviceRssi = (TextView) view.findViewById(R.id.device_rssi);
                viewHolder.pairStatus = (Button) view.findViewById(R.id.btn_pair);
                view.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) view.getTag();
            }

            /**
             * Setting the name and the RSSI of the BluetoothDevice. provided it
             * is a valid one
             */
            final BluetoothDevice device = mLeDevices.get(position);
            final String deviceName = device.getName();
            if (deviceName != null && deviceName.length() > 0) {
                try {
                    viewHolder.deviceName.setText(deviceName);
                    viewHolder.deviceAddress.setText(device.getAddress());
                    byte rssival = (byte) mDevRssiValues.get(device.getAddress()).intValue();
                    if (rssival != 0) {
                        viewHolder.deviceRssi.setText(String.valueOf(rssival));
                    }
                    String pairStatus = (device.getBondState() == BluetoothDevice.BOND_BONDED)
                            ? getActivity().getResources().getString(R.string.bluetooth_pair)
                            : getActivity().getResources().getString(R.string.bluetooth_unpair);
                    viewHolder.pairStatus.setText(pairStatus);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            } else {
                viewHolder.deviceName.setText(R.string.device_unknown);
                viewHolder.deviceName.setSelected(true);
                viewHolder.deviceAddress.setText(device.getAddress());
            }
            viewHolder.pairStatus.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mPairButton = (Button) view;
                    mDeviceAddress = device.getAddress();
                    mDeviceName = device.getName();
                    String status = mPairButton.getText().toString();
                    if (status.equalsIgnoreCase(getResources().getString(R.string.bluetooth_pair))) {
                        unpairDevice(device);
                    } else {
                        pairDevice(device);
                    }
                }
            });
            return view;
        }

        @Override
        public Filter getFilter() {
            return mFilter;
        }

        private class ItemFilter extends Filter {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {

                String mFilterString = constraint.toString().toLowerCase();

                FilterResults mResults = new FilterResults();

                final ArrayList<BluetoothDevice> list = mLeDevices;

                int count = list.size();
                final ArrayList<BluetoothDevice> nlist = new ArrayList<BluetoothDevice>(count);

                for (int i = 0; i < count; i++) {
                    if (list.get(i).getName() != null
                            && list.get(i).getName().toLowerCase().contains(mFilterString)) {
                        nlist.add(list.get(i));
                    }
                }

                mResults.values = nlist;
                mResults.count = nlist.size();
                return mResults;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                mFilteredDevices = (ArrayList<BluetoothDevice>) results.values;
                clear();
                int count = mFilteredDevices.size();
                for (int i = 0; i < count; i++) {
                    BluetoothDevice mDevice = mFilteredDevices.get(i);
                    mLeDeviceListAdapter.addDevice(mDevice, mLeDeviceListAdapter.getRssiValue());
                    notifyDataSetChanged(); // notifies the data with new filtered values
                }
            }
        }
    }

    public void sendMessage(int what) {
        Message message = new Message();
        message.what = what;
        handler.sendMessage(message);
    }

    final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            switch (msg.what) {
            case 0:
                mLeDeviceListAdapter.notifyDataSetChanged();
                //Toast.makeText(getApplicationContext(), "?????", Toast.LENGTH_SHORT).show();
                break;
            }
        }
    };
}