当前位置: 首页 > 知识库问答 >
问题:

除非我的应用程序批准,否则阻止Android手机连接到WiFi网络?

臧令
2023-03-14

我想开发一个应用程序,可以防止连接到WiFi网络,除非我批准它。我希望能够查询接入点的MAC地址,并将其与对应于SSID的已知地址列表进行比较。该应用程序的目标是保护用户避免意外连接到恶意访问点,例如菠萝设备可以产生的类型。

从我的研究中,我不清楚我将如何实现这个目标。有关wifi网络状态更改的通知方式等问题?解释如何检测已发生的连接,但对于我的用例来说,这已经太晚了。

无论是ConnectivityManager还是WifiManager似乎都没有提供添加侦听器的方法,这些侦听器可能会中断正在进行的连接。

我对解决方案的一些想法:

>

  • 将我自己安装为代理,并决定是否允许数据通过。然而,这似乎不是一个基于Android代理设置是否适用于设备上所有应用的选项?(提示:答案是“否”)。

    用我自己创造的东西替换现有的WiFi管理器。然而,我真的很难在Android开发者指南中找到任何关于更换系统组件的信息。因此,我不确定这在无根手机上是否可行。

    找到一些方法防止Android自动连接到已知网络(即以前使用过的网络或存储有密码的网络)。然后我可以管理我应用程序中的所有连接/断开连接。但是,我看不出如何在手机上手动执行此操作,因此我怀疑这是否可以通过编程实现。

    有人能提出一种在无根电话上有效的方法吗?


  • 共有3个答案

    哈骞仕
    2023-03-14

    正如您所知,当连接到Wifi时,sifi manager应用程序会在正在连接的Wifi名称下显示一条提示消息,

    比如连接、验证、获取IP。。。等

    因此,我尝试搜索如何检测连接到Wifi网络的那些阶段。我得到了一个答案,说明了这是如何完成的,它是使用a接收器来执行的,以请求者的状态\u更改\u操作

    我试图实现它添加代码只是为了断开连接。。。这是成功的,因为Wifi从未连接,图标没有出现在通知栏上,日志不断重复这些步骤,尽管有些人说它是如何连接的(在日志中),但实际上设备本身没有显示任何内容,因此可能它连接了10毫秒左右

    无论如何,下面是我使用的代码:

    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。断开连接() 这就是我中断连接的原因。这里剩下的是获取网络名称或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>
    

    谢谢

    商曦
    2023-03-14

    您可以监听wifi的连接更改,并对该事件采取行动以启用禁用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));
                }
            }
        }
    };
    
    费秦迟
    2023-03-14

    如果不生根设备,就无法实现非常健壮的系统。我想这是你能得到的最接近的:

    1. 使用getConfiguredNetworks()获取用户设备上当前配置的网络列表

    或者,对于步骤(2.),您可以为每个配置的网络调用disableNetwork(),并根据BSSID有选择地启用它们。请注意,MAC地址仍然很容易被欺骗。

     类似资料:
    • 我在Android应用程序,涉及连接一个特定的WiFi SSID没有密码。每当用户进入应用程序时,应用程序都会通过BLE检测特定的信标。之后,该应用程序尝试使用WifiManager连接应用程序代码中编程的WiFi。在这里,我面临一些问题: 1)如果WiFi已经禁用在手机-应用程序启用WiFi并尝试连接到已经配置的WiFi(可能是字母顺序)。在这种情况下,它可能会连接另一个可用的WiFi,并在手机

    • 嗨,伙计们,我正在为我的覆盆子Pi家庭服务器写一个智能家庭扩展。为此,我想通过检查智能手机是否连接到本地网络来了解何时有人在家。 不幸的是,到目前为止,ping Android设备在最好的情况下是不可靠的。这取决于睡眠状态,Nexus5x根本不响应ping。我也不去摆弄睡眠设置,因为那会减少电池寿命。 我的路由器说设备已经连接,但我不知道如何中继这个信息。我有什么办法可以确定任何智能手机都是用Py

    • 我有一个Spring Boot应用程序,它使用IBMSpring Boot启动器连接到IBMMessageQueue服务: 我有一个组件类侦听队列,它有以下注释来启用/禁用连接到队列: 我的应用程序中还有以下属性。属性: 当我连接到ActiveMQ时,此注释用于禁用队列连接,但在将代码库更改为连接到IBM MQ时,连接似乎不受ConditionalUnproperty的影响,并且总是尝试连接。 是

    • 我正在制作一个用户登录应用程序,当执行模拟器时,我可以注册用户,验证用户在我的数据库中的股票,但是当我在手机上执行应用程序时,它不能连接到我的数据库。 这是我与数据库的连接代码:

    • 我正在开发一个应用程序,我需要扫描WiFi网络,并显示所有连接设备的列表。 允许用户点击一个设备,应用程序应该显示该特定设备的所有硬件信息。这里我说的硬件是指内存、存储介质、存储容量、设备名称、设备IP地址等。 现在,这个设备可以是任何东西,比如xbox,带有Linux/Windows的笔记本电脑,iPhone之类的手机,或者任何基于Android的智能手机,甚至是打印机。 我如何扫描WiFi网络

    • 我创建了一个android wear应用程序,并上传到play Store。当安装在手机上时,它不会自动在连接的android设备上安装wear应用程序(在本例中是Moto360)。我三次检查了android wear和android phone项目中的权限、应用程序id和软件包名称。它们是一样的。由于谷歌不允许在开发过程中安装手机应用程序时自动安装android wear应用程序的功能,上传到p