Включить Bluetooth-модем для Android программно

Я пытаюсь создать приложение типа "Bluetooth-модем" в магазине игр. Я читал на форуме, что Android очень заботится о безопасности и не включит этот параметр без взаимодействия с пользователем.

Мне нужно несколько пояснений о том, как включить модем Bluetooth.

Спасибо

4 ответа

Я не знаю, является ли это все еще проблемой или нет, но я обнаружил, что с помощью connect метод в отражении вызова работает. Отработка кода, который использовал pmont по ссылке в Lorelorelore:

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Class<?> classBluetoothPan = null;
Constructor<?> BTPanCtor = null;
Object BTSrvInstance = null;
Method mBTPanConnect;

try {
    classBluetoothPan = Class.forName("android.bluetooth.BluetoothPan");
    mBTPanConnect = classBluetoothPan.getDeclaredMethod("connect", BluetoothDevice.class);
    BTPanCtor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
    BTPanCtor.setAccessible(true);
    BTSrvInstance = BTPanCtor.newInstance(myContext, new BTPanServiceListener(myContext));
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (Exception e) {
    e.printStackTrace();
}

Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
    // Loop through paired devices
    for (BluetoothDevice device : pairedDevices) {
        try{
            mBTPanConnect.invoke(BTSrvInstance, device);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Конечно, это предполагает, что Bluetooth включен, и у вас есть только одно сопряженное устройство. Но включить Bluetooth довольно просто, используя стандартные (не отражающие) вызовы, и вы можете просто проверить подключенное устройство, к которому вы хотите подключиться, в for петля. Кроме того, не забывайте BTPanServiceListener класс от другого ответа, а также.

Надеюсь это поможет.

Приведенное выше решение потребовало некоторой модификации, чтобы работать на меня. В частности, код для включения привязки должен быть в методе OnServiceConnected(). Также у меня есть следующие разрешения, установленные в манифесте:

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

Вот мое решение:

public class BluetoothTethering extends ActionBarActivity {

    Object instance = null;
    Method setTetheringOn = null;
    Method isTetheringOn = null;
    Object mutex = new Object();

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth_tethering);
        String sClassName = "android.bluetooth.BluetoothPan";

        try {

            Class<?> classBluetoothPan = Class.forName(sClassName);

            Constructor<?> ctor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
            ctor.setAccessible(true);
            //  Set Tethering ON
            Class[] paramSet = new Class[1];
            paramSet[0] = boolean.class;

            synchronized (mutex) {
                setTetheringOn = classBluetoothPan.getDeclaredMethod("setBluetoothTethering", paramSet);
                isTetheringOn = classBluetoothPan.getDeclaredMethod("isTetheringOn", null);
                instance = ctor.newInstance(getApplicationContext(), new BTPanServiceListener(getApplicationContext()));
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public class BTPanServiceListener implements BluetoothProfile.ServiceListener {

        private final Context context;

        public BTPanServiceListener(final Context context) {
            this.context = context;
        }

        @Override
        public void onServiceConnected(final int profile,
                                       final BluetoothProfile proxy) {
            //Some code must be here or the compiler will optimize away this callback.

            try {
                synchronized (mutex) {
                    setTetheringOn.invoke(instance, true);
                    if ((Boolean)isTetheringOn.invoke(instance, null)) {
                        Toast.makeText(getApplicationContext(), "BT Tethering is on", Toast.LENGTH_LONG).show();
                    }
                    else {
                        Toast.makeText(getApplicationContext(), "BT Tethering is off", Toast.LENGTH_LONG).show();
                    }
                }
            }
            catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(final int profile) {
        }
    }
}

Приведенный ниже код отлично работает для меня

String sClassName = "android.bluetooth.BluetoothPan";

try {  

    Class<?> classBluetoothPan = Class.forName(sClassName);

    Constructor<?> ctor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
    ctor.setAccessible(true);
    Object instance = ctor.newInstance(getApplicationContext(), new BTPanServiceListener(getApplicationContext()));                 
    //  Set Tethering ON
    Class[] paramSet = new Class[1];
    paramSet[0] = boolean.class;

    Method setTetheringOn = classBluetoothPan.getDeclaredMethod("setBluetoothTethering", paramSet);

    setTetheringOn.invoke(instance,true);

} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (Exception e) {
    e.printStackTrace();
}

public class BTPanServiceListener implements BluetoothProfile.ServiceListener {

    private final Context context;

    public BTPanServiceListener(final Context context) {
        this.context = context;
    }

    @Override
    public void onServiceConnected(final int profile,
            final BluetoothProfile proxy) {
        //Some code must be here or the compiler will optimize away this callback.
        Log.e("MyApp", "BTPan proxy connected");

    }

    @Override
    public void onServiceDisconnected(final int profile) {
    }
}

Здесь вы найдете похожий вопрос: Bluetooth вопрос

Просто замените "isTetheringOn" на "setBluetoothTethering" в вызове отражения и передайте логический параметр. Он должен работать.

Другие вопросы по тегам