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