Включить 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" в вызове отражения и передайте логический параметр. Он должен работать.