Запретить Android-телефон подключаться к сети WiFi, если мое приложение не одобрит его?
Я хочу разработать приложение, которое может препятствовать подключению к сети WiFi, если я не одобрю его. Я хочу иметь возможность запросить MAC-адрес точки доступа и сравнить его со списком известных адресов, соответствующих SSID. Цель приложения - защитить пользователей от случайного подключения к вредоносным точкам доступа, таким как типы, которые могут быть созданы с помощью ананасных устройств.
Я не понимаю из своего исследования, как я достиг бы этой цели. Вопросы, такие как Как получить уведомление о изменении статуса сети Wi-Fi? объясняют, как обнаружить соединение, но для моего случая использования, который уже слишком поздно.
Ни ConnectivityManager
, ни WifiManager
, похоже, не предлагают способы добавления слушателей, которые могут прервать соединение.
Некоторые мысли, которые я имел для решения:
-
Установите себя как прокси-сервер и принимайте решение о том, разрешать ли данные. Однако это не похоже на опцию Устанавливаются ли настройки прокси-сервера Android для всех приложений на устройстве? (подсказка: ответ "Нет" ).
-
Замените существующий менеджер WiFi чем-то вроде моего собственного создания. Тем не менее, я действительно пытался найти любую информацию в руководствах разработчика Android относительно замены компонентов системы. Следовательно, я не уверен, что это возможно на ненарушенных телефонах.
-
Сохраните сетевые пароли в моем приложении и установите пароли в диспетчере WiFi на бессмысленные значения. Затем закрепите широковещательное сообщение, которое предупреждает о неудавшемся соединении (предположительно, что-то вроде WifiManager.WPS_AUTH_FAILURE
) и выборочно решает снова подключиться к этой сети. Возможно, это возможное (если не уродливое) решение, но могу ли я установить пароль обратно на бессмысленное значение, пока сеть все еще подключена, чтобы мы не могли спокойно подключиться к другому SSID с тем же именем? Я не уверен. Мне кажется, что устройства ананаса, вероятно, будут принимать любой пароль, тем самым делая этот подход недействительным.
-
Найдите способ запретить Android автоматически подключаться к известным сетям (т.е. сети, которые использовались до этого или иметь с ними пароль). Тогда я смогу управлять всеми подключениями/отключением от своего приложения. Однако я не могу понять, как это сделать вручную на моем телефоне, поэтому я сомневаюсь, что это возможно программно.
Может ли кто-нибудь предложить подход, который будет работать на некорневом телефоне?
Ответы
Ответ 1
Вы не можете реализовать очень надежную систему без укорачивания устройства. Здесь, ближе всего вы можете получить, я думаю:
В качестве альтернативы для шага (2.) вы можете вызвать disableNetwork() для каждой настроенной сети и выборочно включить их на основе BSSID. Обратите внимание, что MAC-адреса все еще могут быть легко подделаны.
Ответ 2
вы можете прослушивать изменение соединения Wi-Fi и действовать на этих событиях, чтобы отключить wifi
private ConnectivityManager connectionManager;
boolean previousConnectivityStatus;
private WifiManager wifiManager;
/* Register Connectivity Receiver */
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
context.registerReceiver(networkBroadcastReceiver, intentFilter);
/* Register Wifi State Listener */
IntentFilter wifiStateIntentFilter = new IntentFilter();
wifiStateIntentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
context.registerReceiver(wifiStateReceiver, wifiStateIntentFilter);
connectionManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
private BroadcastReceiver wifiStateReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
Utility.traceM("NetworkController.wifiStateReceiver.new BroadcastReceiver() {...}::onReceive");
int extraWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
switch (extraWifiState)
{
case WifiManager.WIFI_STATE_DISABLED:
{
Utility.trace("Broadcast Wifi State Disabled");
if(isWifiStateEventsEnabled)
{
EventBus.getDefault().post(new NetworkEvent(NetworkEventType.WIFI_DISABLED));
}
break;
}
case WifiManager.WIFI_STATE_ENABLED:
{
Utility.trace("Broadcast Wifi State Enabled");
if(isWifiStateEventsEnabled)
{
EventBus.getDefault().post(new NetworkEvent(NetworkEventType.WIFI_ENABLED));
}
break;
}
}
}
};
private BroadcastReceiver networkBroadcastReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
Utility.traceM("NetworkController.networkBroadcastReceiver.new BroadcastReceiver() {...}::onReceive");
boolean connectivityStatus = isInternetConnectivityAvailable();
if (previousConnectivityStatus != connectivityStatus)
{
if (connectivityStatus)
{
previousConnectivityStatus = true;
Utility.trace("Broadcast Internet Available");
EventBus.getDefault().post(new NetworkEvent(NetworkEventType.INTERNET_CONNECTED));
}
else
{
previousConnectivityStatus = false;
Utility.trace("Broadcast Internet Disconnected");
EventBus.getDefault().post(new NetworkEvent(NetworkEventType.INTERNET_DISCONNECTED));
}
}
}
};
Ответ 3
как вы знаете при подключении к Wi-Fi, приложение sifi manager отображает сообщение подсказки под именем Wifi, которое подключается,
как подключение, аутентификация, получение IP-адреса и т.д.
поэтому я попытался найти, как определить те этапы подключения к сети Wi-Fi
я пришел к ответу, показывая, как это делается,
это было сделано с помощью приемника до SUPPLICANT_STATE_CHANGED_ACTION
и я попытался реализовать его, добавив код, чтобы просто отключиться... и это было успешным, поскольку Wi-Fi никогда не подключался, значок не появлялся на панели уведомлений
и журналы продолжают повторять шаги, хотя некоторые из них говорят о соединении (в журналах), но на самом устройстве ничего не появляется, поэтому, возможно, он подключился к подобным (10 MS)
так или иначе, ниже приведен код, который я использовал:
public class MyNetworkMonitor extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// EXTRA_BSSID
// SUPPLICANT_STATE_CHANGED_ACTION
// EXTRA_NEW_STATE
// Log.i("YAZAN", intent.getAction() + " " +
// intent.getStringExtra(WifiManager.EXTRA_BSSID));
// Log.i("YAZAN", intent.getAction() + " "
// +intent.getStringExtra(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION));
// Log.i("YAZAN", intent.getAction() + " "
// +intent.getStringExtra(WifiManager.EXTRA_NEW_STATE));
//Log.i("YAZAN", intent.getAction() + " " + intent.getStringExtra(WifiManager.EXTRA_BSSID));
String action = intent.getAction();
if(action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)){
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Log.d("YAZAN", ">>>>SUPPLICANT_STATE_CHANGED_ACTION<<<<<<");
SupplicantState supl_state=((SupplicantState)intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE));
switch(supl_state){
case ASSOCIATED:Log.i("YAZAN", "ASSOCIATED");
break;
case ASSOCIATING:
Log.i("YAZAN", "ASSOCIATING");
wifi.disconnect();
Log.i("YAZAN", "disconnect()");
break;
case AUTHENTICATING:Log.i("YAZAN", "Authenticating...");
wifi.disconnect();
Log.i("YAZAN", "disconnect()");
break;
case COMPLETED:Log.i("YAZAN", "Connected");
break;
case DISCONNECTED:Log.i("YAZAN", "Disconnected");
break;
case DORMANT:Log.i("YAZAN", "DORMANT");
wifi.disconnect();
Log.i("YAZAN", "disconnect()");
break;
case FOUR_WAY_HANDSHAKE:Log.i("YAZAN", "FOUR_WAY_HANDSHAKE");
wifi.disconnect();
Log.i("YAZAN", "disconnect()");
break;
case GROUP_HANDSHAKE:Log.i("YAZAN", "GROUP_HANDSHAKE");
wifi.disconnect();
Log.i("YAZAN", "disconnect()");
break;
case INACTIVE:Log.i("YAZAN", "INACTIVE");
break;
case INTERFACE_DISABLED:Log.i("YAZAN", "INTERFACE_DISABLED");
break;
case INVALID:Log.i("YAZAN", "INVALID");
break;
case SCANNING:Log.i("YAZAN", "SCANNING");
break;
case UNINITIALIZED:Log.i("YAZAN", "UNINITIALIZED");
break;
default:Log.i("YAZAN", "Unknown");
break;
}
int supl_error=intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1);
if(supl_error==WifiManager.ERROR_AUTHENTICATING){
Log.i("YAZAN", "ERROR_AUTHENTICATING!");
}
}//if
}// onReceive()
где вы находите wifi.disconnect();
, как я прервал соединение.
то, что остается здесь, заключается в том, чтобы получить имя сети или адрес mac, чтобы разрешить или запретить завершение процесса
Права доступа:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
добавление широковещательного приемника:
<receiver android:name=".MyNetworkMonitor" >
<intent-filter>
<action android:name="android.net.wifi.supplicant.STATE_CHANGE" />
<action android:name="android.net.wifi.supplicant.CONNECTION_CHANGE" />
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</receiver>
спасибо