// // anyRemote android client // a bluetooth/wi-fi remote control for Linux. // // Copyright (C) 2011-2016 Mikhail Fedotov <anyremote@mail.ru> // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // package anyremote.client.android.util; import android.content.Context; import android.os.Handler; import android.os.Message; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Intent; import android.content.IntentFilter; import anyremote.client.android.R; import anyremote.client.android.anyRemote; import anyremote.client.android.SearchForm; import anyremote.client.android.util.IScanner; import anyremote.client.android.util.ScanMessage; // // Bluetooth scanner // public class BTScanner implements IScanner { Handler searchFormHandler; SearchForm calledFrom; boolean deregStateRcv = false; private BluetoothAdapter mBtAdapter; public BTScanner(Handler hdl, SearchForm sf) { searchFormHandler = hdl; calledFrom = sf; } public void startScan() { // Register for broadcasts when a device is discovered IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); calledFrom.registerReceiver(mReceiver, filter); // Register for broadcasts when discovery has finished filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); calledFrom.registerReceiver(mReceiver, filter); // Get the local Bluetooth adapter mBtAdapter = BluetoothAdapter.getDefaultAdapter(); doDiscovery(); } public void stopScan () { if (mBtAdapter != null && mBtAdapter.isDiscovering()) { anyRemote._log("BTScanner", "stopScan"); mBtAdapter.cancelDiscovery(); } // Make sure we're not doing discovery anymore calledFrom.unregisterReceiver(mReceiver); if (deregStateRcv) { calledFrom.unregisterReceiver(mBTStateReceiver); } } private void informDiscoveryResult(int res) { Message msg = searchFormHandler.obtainMessage(res); msg.sendToTarget(); } private void informDiscoveryResult(String v) { ScanMessage sm = new ScanMessage(); sm.name = v; Message msg = searchFormHandler.obtainMessage(SCAN_PROGRESS, sm); msg.sendToTarget(); } private void doDiscovery() { if (mBtAdapter == null) { informDiscoveryResult(SCAN_FAILED); stopScan(); return; } if (!mBtAdapter.isEnabled()) { switchBluetoothOn(); } else { doRealDiscovery(); } } private void doRealDiscovery() { anyRemote._log("BTScanner", "doRealDiscovery"); // Indicate scanning in the title informDiscoveryResult(SCAN_STARTED); // Request discover from BluetoothAdapter mBtAdapter.startDiscovery(); } public void switchBluetoothOn() { anyRemote._log("BTScanner", "switchBluetoothOn"); String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; deregStateRcv = true; calledFrom.registerReceiver(mBTStateReceiver, new IntentFilter(actionStateChanged)); calledFrom.startActivityForResult(new Intent(actionRequestEnable), 0); } // The BroadcastReceiver that listens for discovered devices and // changes the title when discovery is finished private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { anyRemote._log("BTScanner", "BroadcastReceiver.onReceive discovery "); String action = intent.getAction(); // When discovery finds a device if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); anyRemote._log("BTScanner", "BroadcastReceiver::onReceive discovery GOT ONE "+device.getName()+" "+device.getAddress()); // If it's already paired, skip it, because it's been listed already //if (device.getBondState() != BluetoothDevice.BOND_BONDED) { ScanMessage sm = new ScanMessage(); sm.name = device.getName(); sm.address = "btspp://"+device.getAddress(); Message msg = searchFormHandler.obtainMessage(SCAN_FOUND, sm); msg.sendToTarget(); //} // When discovery is finished, change the Activity title } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { anyRemote._log("BTScanner", "BroadcastReceiver::onReceive discovery FINISHED"); informDiscoveryResult(SCAN_FINISHED); } } }; // The BroadcastReceiver that handles BT state private final BroadcastReceiver mBTStateReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { anyRemote._log("BTScanner", "BroadcastReceiver::onReceive state"); String stateExtra = BluetoothAdapter.EXTRA_STATE; int state = intent.getIntExtra(stateExtra, -1); switch (state) { case (BluetoothAdapter.STATE_TURNING_ON) : { informDiscoveryResult(R.string.bt_on); break; } case (BluetoothAdapter.STATE_ON) : { anyRemote._log("BTScanner", "BroadcastReceiver::onReceive state ON"); informDiscoveryResult(R.string.bt_on); calledFrom.unregisterReceiver(this); deregStateRcv = false; doRealDiscovery(); break; } case (BluetoothAdapter.STATE_TURNING_OFF) : { informDiscoveryResult(R.string.bt_on); break; } case (BluetoothAdapter.STATE_OFF) : { anyRemote._log("BTScanner", "BroadcastReceiver::onReceive state OFF"); informDiscoveryResult(R.string.bt_on); calledFrom.unregisterReceiver(this); deregStateRcv = false; break; } } } }; }