How to Change the Scan Mode of Bluetooth Adapter in android.?

纵然是瞬间 提交于 2021-02-07 09:46:41

问题


Currently i am working on a Bluetooth app where i need to change the Scan Mode from SCAN_MODE_CONNECTABLE_DISCOVERABLE to SCAN_MODE_CONNECTABLE on click of a button.

i am setting it Discoverable using following Intent:

Intent discoverableIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent .putExtra( BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISOVERABLE_DURATION);
startActivityForResult(discoverableIntent, REQUEST_DISCOVERABLE_BT);

where i have set DISOVERABLE_DURATION=300;

Now i want to skip the Discoverability in between and want to change its state to SCAN_MODE_CONNECTABLE only.

Kindly provide me an appropriate solution../


回答1:


Well it is quite old question, however you can switch scan mode of bluetooth without any permission of user and (for as far as i have tested) unlimited time. This will require using reflections on Android API, so this is not an official api. Of course, you are using it on your own risk :) Below is code i am using to make BT adapter discoverable:

private boolean setBluetoothScanMode(int scanMode){
    Method method = null;
    final BluetoothAdapter btAdapter = btManager.getAdapter();

    if(!btAdapter.isEnabled()){
        Log.d(LCAT, "BT adapter is off, turning on");
        btAdapter.enable();
    }

    try {
        method = btAdapter.getClass().getMethod("setScanMode", int.class);
    } catch (SecurityException e) {
        return false;
    } catch (NoSuchMethodException e) {
        return false;
    }

    try {
      method.invoke(btAdapter, scanMode);
    } catch (IllegalArgumentException e) {
        return false;
    } catch (IllegalAccessException e) {
        return false;
    } catch (InvocationTargetException e) {
        return false;
    }
    return true;
}

Also you need permissions:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />

After this device should be in scan mode you choose by passing the int scanMode argument. It is working on Android API 23.




回答2:


Start a new intent with SCAN_MODE_NONE to stop scanning and then start again with SCAN_MODE_CONNECTABLE to scan again in connectable mode only.




回答3:


You cannot set the scan mode of Android devices in 4.2 and beyond with a third party (non-kernel/non-system) application. You can only enable discovery (SCAN_MODE_CONNECTABLE_DISCOVERABLE), with an option to set the particular duration with EXTRA_DISCOVERABLE_DURATION. You can effectively cancel discovery by setting the duration parameter to 1.

For evidence, take a glance through the Android Source, focusing on BluetoothAdapter.java:

/**
 * Set the Bluetooth scan mode of the local Bluetooth adapter.
 * <p>The Bluetooth scan mode determines if the local adapter is
 * connectable and/or discoverable from remote Bluetooth devices.
 * <p>For privacy reasons, discoverable mode is automatically turned off
 * after <code>duration</code> seconds. For example, 120 seconds should be
 * enough for a remote device to initiate and complete its discovery
 * process.
 * <p>Valid scan mode values are:
 * {@link #SCAN_MODE_NONE},
 * {@link #SCAN_MODE_CONNECTABLE},
 * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}.
 * <p>If Bluetooth state is not {@link #STATE_ON}, this API
 * will return false. After turning on Bluetooth,
 * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
 * to get the updated value.
 * <p>Requires {@link android.Manifest.permission#WRITE_SECURE_SETTINGS}
 * <p>Applications cannot set the scan mode. They should use
 * <code>startActivityForResult(
 * BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE})
 * </code>instead.
 *
 * @param mode valid scan mode
 * @param duration time in seconds to apply scan mode, only used for
 *                 {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}
 * @return     true if the scan mode was set, false otherwise
 * @hide
 */
public boolean setScanMode(int mode, int duration) {
    if (getState() != STATE_ON) return false;
    try {
        synchronized(mManagerCallback) {
            if (mService != null) return mService.setScanMode(mode, duration);
        }
    } catch (RemoteException e) {Log.e(TAG, "", e);}
    return false;
}

As noted in the source, "Applications cannot set the scan mode". The permission WRITE_SECURE_SETTINGS is needed to manually scan mode outside of the API, which is not possible for third-party applications.



来源:https://stackoverflow.com/questions/14723790/how-to-change-the-scan-mode-of-bluetooth-adapter-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!