Home | History | Annotate | Download | only in bluetoothchat
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.example.android.bluetoothchat;
     18 
     19 import android.app.Activity;
     20 import android.bluetooth.BluetoothAdapter;
     21 import android.bluetooth.BluetoothDevice;
     22 import android.content.BroadcastReceiver;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.content.IntentFilter;
     26 import android.os.Bundle;
     27 import android.view.View;
     28 import android.view.Window;
     29 import android.widget.AdapterView;
     30 import android.widget.ArrayAdapter;
     31 import android.widget.Button;
     32 import android.widget.ListView;
     33 import android.widget.TextView;
     34 
     35 import com.example.android.common.logger.Log;
     36 
     37 import java.util.Set;
     38 
     39 /**
     40  * This Activity appears as a dialog. It lists any paired devices and
     41  * devices detected in the area after discovery. When a device is chosen
     42  * by the user, the MAC address of the device is sent back to the parent
     43  * Activity in the result Intent.
     44  */
     45 public class DeviceListActivity extends Activity {
     46 
     47     /**
     48      * Tag for Log
     49      */
     50     private static final String TAG = "DeviceListActivity";
     51 
     52     /**
     53      * Return Intent extra
     54      */
     55     public static String EXTRA_DEVICE_ADDRESS = "device_address";
     56 
     57     /**
     58      * Member fields
     59      */
     60     private BluetoothAdapter mBtAdapter;
     61 
     62     /**
     63      * Newly discovered devices
     64      */
     65     private ArrayAdapter<String> mNewDevicesArrayAdapter;
     66 
     67     @Override
     68     protected void onCreate(Bundle savedInstanceState) {
     69         super.onCreate(savedInstanceState);
     70 
     71         // Setup the window
     72         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
     73         setContentView(R.layout.activity_device_list);
     74 
     75         // Set result CANCELED in case the user backs out
     76         setResult(Activity.RESULT_CANCELED);
     77 
     78         // Initialize the button to perform device discovery
     79         Button scanButton = (Button) findViewById(R.id.button_scan);
     80         scanButton.setOnClickListener(new View.OnClickListener() {
     81             public void onClick(View v) {
     82                 doDiscovery();
     83                 v.setVisibility(View.GONE);
     84             }
     85         });
     86 
     87         // Initialize array adapters. One for already paired devices and
     88         // one for newly discovered devices
     89         ArrayAdapter<String> pairedDevicesArrayAdapter =
     90                 new ArrayAdapter<String>(this, R.layout.device_name);
     91         mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
     92 
     93         // Find and set up the ListView for paired devices
     94         ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
     95         pairedListView.setAdapter(pairedDevicesArrayAdapter);
     96         pairedListView.setOnItemClickListener(mDeviceClickListener);
     97 
     98         // Find and set up the ListView for newly discovered devices
     99         ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
    100         newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
    101         newDevicesListView.setOnItemClickListener(mDeviceClickListener);
    102 
    103         // Register for broadcasts when a device is discovered
    104         IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    105         this.registerReceiver(mReceiver, filter);
    106 
    107         // Register for broadcasts when discovery has finished
    108         filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    109         this.registerReceiver(mReceiver, filter);
    110 
    111         // Get the local Bluetooth adapter
    112         mBtAdapter = BluetoothAdapter.getDefaultAdapter();
    113 
    114         // Get a set of currently paired devices
    115         Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
    116 
    117         // If there are paired devices, add each one to the ArrayAdapter
    118         if (pairedDevices.size() > 0) {
    119             findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
    120             for (BluetoothDevice device : pairedDevices) {
    121                 pairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
    122             }
    123         } else {
    124             String noDevices = getResources().getText(R.string.none_paired).toString();
    125             pairedDevicesArrayAdapter.add(noDevices);
    126         }
    127     }
    128 
    129     @Override
    130     protected void onDestroy() {
    131         super.onDestroy();
    132 
    133         // Make sure we're not doing discovery anymore
    134         if (mBtAdapter != null) {
    135             mBtAdapter.cancelDiscovery();
    136         }
    137 
    138         // Unregister broadcast listeners
    139         this.unregisterReceiver(mReceiver);
    140     }
    141 
    142     /**
    143      * Start device discover with the BluetoothAdapter
    144      */
    145     private void doDiscovery() {
    146         Log.d(TAG, "doDiscovery()");
    147 
    148         // Indicate scanning in the title
    149         setProgressBarIndeterminateVisibility(true);
    150         setTitle(R.string.scanning);
    151 
    152         // Turn on sub-title for new devices
    153         findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
    154 
    155         // If we're already discovering, stop it
    156         if (mBtAdapter.isDiscovering()) {
    157             mBtAdapter.cancelDiscovery();
    158         }
    159 
    160         // Request discover from BluetoothAdapter
    161         mBtAdapter.startDiscovery();
    162     }
    163 
    164     /**
    165      * The on-click listener for all devices in the ListViews
    166      */
    167     private AdapterView.OnItemClickListener mDeviceClickListener
    168             = new AdapterView.OnItemClickListener() {
    169         public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
    170             // Cancel discovery because it's costly and we're about to connect
    171             mBtAdapter.cancelDiscovery();
    172 
    173             // Get the device MAC address, which is the last 17 chars in the View
    174             String info = ((TextView) v).getText().toString();
    175             String address = info.substring(info.length() - 17);
    176 
    177             // Create the result Intent and include the MAC address
    178             Intent intent = new Intent();
    179             intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
    180 
    181             // Set result and finish this Activity
    182             setResult(Activity.RESULT_OK, intent);
    183             finish();
    184         }
    185     };
    186 
    187     /**
    188      * The BroadcastReceiver that listens for discovered devices and changes the title when
    189      * discovery is finished
    190      */
    191     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    192         @Override
    193         public void onReceive(Context context, Intent intent) {
    194             String action = intent.getAction();
    195 
    196             // When discovery finds a device
    197             if (BluetoothDevice.ACTION_FOUND.equals(action)) {
    198                 // Get the BluetoothDevice object from the Intent
    199                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    200                 // If it's already paired, skip it, because it's been listed already
    201                 if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
    202                     mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
    203                 }
    204                 // When discovery is finished, change the Activity title
    205             } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
    206                 setProgressBarIndeterminateVisibility(false);
    207                 setTitle(R.string.select_device);
    208                 if (mNewDevicesArrayAdapter.getCount() == 0) {
    209                     String noDevices = getResources().getText(R.string.none_found).toString();
    210                     mNewDevicesArrayAdapter.add(noDevices);
    211                 }
    212             }
    213         }
    214     };
    215 
    216 }
    217