如何通过ADB关闭Wifi?

68

我正在为WiFi通话自动化测试过程编写脚本,我想知道是否可以通过adb打开/关闭WiFi?

我希望能够禁用/启用WiFi或关闭WiFi通话(com.movial.wificall)并重新启动它。

是否可以通过adb和shell命令来完成所有这些操作?

到目前为止,我已经找到了:

android.net.wifi.WifiManager
setWifiEnabled(true/false)

我只是不确定如何把它放在一起。


https://gist.github.com/kamleshkarwande/92a2421ee3f1881ed10d59949b6a4e4d - Kamlesh
13个回答

109

通过ADB使用"svc"(需要root权限):

启用:

adb shell su -c 'svc wifi enable'

禁用:

adb shell su -c 'svc wifi disable'

通过ADB使用按键事件:

adb shell am start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings
adb shell input keyevent 20 & adb shell input keyevent 23

第一行启动“wifi.WifiSettings”活动,打开WiFi设置页面。第二行模拟按键操作。

我在Droid X上测试了这两行代码。但是由于不同的设置布局,上面的按键事件可能需要在其他设备上进行编辑。

关于“keyevents”的更多信息,请参见此处


1
非常感谢您的帖子。在我的手机上不完全相同,但由于您发布了输入事件,我发现它是键事件19和23。再次感谢。:) - Nefariis
1
好的,你明白了吗?是的,我在Droid X上测试过了,我不确定你用的是什么手机 :) - Jared Burrows
2
要在Android 5.0中使用这些按键事件来切换wifi,您可能需要与答案中不同的事件相匹配。我会建议使用adb shell input keyevent 19&adb shell input keyevent 19&adb shell input keyevent 23(第一个也可以是20)- 如果在进入wifi设置屏幕时没有选项被选择,则此方法有效(如果有选项被选择,则应跳过第一个事件)。 - Bartek Lipinski
1
svc wifi 启用/禁用仅适用于已取得 root 权限的设备。另一种通过使用 keyevent 自动化的方法无法跨所有安卓设备运行。 - Thejus Krishna
2
这里需要使用 su,就像 @IvanMorgillo 所说的那样:adb shell su -c 'svc wifi disable' - Aquarius Power
显示剩余8条评论

78

我也在寻找如何打开/关闭蓝牙,后来我找到了这个:

adb shell svc wifi enable|disable

3
我已经在6个不同的设备上尝试过这段代码,从Gingerbread到JellyBean,包括rooted和非rooted设备,但是在任何设备上都不能使其工作。请问您能在哪些设备上使用这段代码并使其正常工作? - Nefariis
6
为此,我需要请求adb shell进入设备......然后请求su权限......然后我才能正确地运行这些命令。 Translated: 为了达到这个目的,我需要请求在设备中使用adb shell.....然后请求su权限.....这样我才能顺利地运行这些命令。 - dell116
适用于已root的Sony Ericsson Xperia和Motorola Razr。 - Ari
5
在根据Nexus 5,4.4.2上工作:adb shell su -c "svc wifi disable"翻译:在已经进行过Root处理的Nexus 5手机上,版本为4.4.2,使用以下命令:adb shell su -c "svc wifi disable" 可以禁用WiFi。 - Ivan Morgillo
1
这对于我未经root的三星S8有效,而adb shell su -c 'svc wifi enable'则无法使用(因为它没有root权限)。 - trevren11
显示剩余3条评论

26

非 root 设备上打开 Wi-Fi 的简单方法是使用一个简单的应用程序:

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        WifiManager wfm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        try {
            wfm.setWifiEnabled(Boolean.parseBoolean(getIntent().getStringExtra("wifi")));
        } catch (Exception e) {
        }
        System.exit(0);
    }
}

AndroidManifest.xml:

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

ADB命令:

$ adb shell am start -n org.mytools.config/.MainActivity -e wifi true
$ adb shell am start -n org.mytools.config/.MainActivity -e wifi false

我稍微调整了一下,并将活动更改为广播接收器,以便可以将其添加到任何应用程序中,且不会显示任何 GUI。 - Fernando Gallego
1
@GodMan 在这里找到它 https://plus.google.com/110502863648146989289/posts/Ri1Dcm6cn48 - Fernando Gallego
这对我非常有帮助。非常感谢! - Esenbek Kydyr uulu
我们需要为Android N进行任何更改吗? - Thejus Krishna
@GodMan,你能再发布一次那个apk吗? - RDR
显示剩余3条评论

15

在Android 11和12上通过cmd命令实现(无需root)

启用Wi-Fi(打开):

adb shell cmd -w wifi set-wifi-enabled enabled 

禁用 Wi-Fi(关闭):

adb shell cmd -w wifi set-wifi-enabled disabled

如果运行enable/disable而不是enabled/disabled,则该命令会返回Invalid args for set-wifi-enabled: java.lang.IllegalArgumentException: Expected 'enabled' or 'disabled' as next arg but got 'disable'/[...] but got 'enable'错误。 - user598527
1
谢谢你纠正这个问题,我会立即在我的维基上进行修复。 - wuseman
1
很酷,对我来说完美运行!(Galaxy Tab A7,Android 11) - miva2

7
  1. 前往位置android/android-sdk/platform-tools
  2. Shift+右键单击
  3. 打开命令提示符并输入以下命令

    1. adb shell
    2. su
    3. svc wifi enable/disable
  4. 完成!!!


5

我测试了这个命令:

adb shell am start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings
adb shell input keyevent 19 && adb shell input keyevent 19 && adb shell input keyevent 23

对于只能在Windows提示符下使用的情况,可能是因为某些驱动程序的原因。

adb shell svc wifi enable|disable 解决方案只有在获取了 root 权限后才能使用。


这非常有用:我的Genymotion模拟器随机启动时会出现可用的wifi,但有时未被选中。我使用了以下命令:shell 'am start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings; input keyevent 20; input keyevent 23' - android.weasel

3
如果你使用引号,它将正常工作:
adb shell "svc wifi enable"

我还是无法让它工作,我已经在Note、Note2、一个root过的GS3和一个Amaze上试过了。 - Nefariis
如果您在命令提示符中尝试此操作,它将会起作用。但是它不会打开任何东西,而是在后台执行。 - SanalBathery
我也可以不用引号运行这个。 - reidisaki

2
我只能做:
settings put global wifi_on 0
settings put global wifi_scan_always_enabled 0

有时候,如果在启动过程中进行操作(例如修复像这样的开机循环),可能不会起作用,您可以先开启飞行模式再进行操作。
settings put global airplane_mode_on 1
settings put global wifi_on 0
settings put global wifi_scan_always_enabled 0

另一个选项是强制执行此操作:
while true; do settings put global wifi_on 0; done

在LG G5(SE)上测试,使用Android 7和未root的原始模式。

1
所有这些input keyevent组合都非常依赖于Android/硬件,这真的很痛苦。
然而,我最终找到了适用于我旧的Android 4.1设备的组合:
adb shell am start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings
adb shell "input keyevent KEYCODE_DPAD_LEFT;input keyevent KEYCODE_DPAD_RIGHT;input keyevent KEYCODE_DPAD_CENTER"

1

下面这个方法不需要root权限,应该可以在任何地方使用(根据文档,即使在Android Q+上,只要你保持targetSdkVersion = 28)。

  1. 创建一个空白应用。

  2. 创建一个ContentProvider

    class ApiProvider : ContentProvider() {
    
        private val wifiManager: WifiManager? by lazy(LazyThreadSafetyMode.NONE) {
            requireContext().getSystemService(WIFI_SERVICE) as WifiManager?
        }
    
        private fun requireContext() = checkNotNull(context)
    
        private val matcher = UriMatcher(UriMatcher.NO_MATCH).apply {
            addURI("wifi", "enable", 0)
            addURI("wifi", "disable", 1)
        }
    
        override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? {
            when (matcher.match(uri)) {
                0 -> {
                    enforceAdb()
                    withClearCallingIdentity {
                        wifiManager?.isWifiEnabled = true
                    }
                }
                1 -> {
                    enforceAdb()
                    withClearCallingIdentity {
                        wifiManager?.isWifiEnabled = false
                    }
                }
            }
            return null
        }
    
        private fun enforceAdb() {
            val callingUid = Binder.getCallingUid()
            if (callingUid != 2000 && callingUid != 0) {
                throw SecurityException("只允许使用 shell 或 root 用户。")
            }
        }
    
        private inline fun <T> withClearCallingIdentity(block: () -> T): T {
            val token = Binder.clearCallingIdentity()
            try {
                return block()
            } finally {
                Binder.restoreCallingIdentity(token)
            }
        }
    
        override fun onCreate(): Boolean = true
    
        override fun insert(uri: Uri, values: ContentValues?): Uri? = null
    
        override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<out String>?): Int = 0
    
        override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int = 0
    
        override fun getType(uri: Uri): String? = null
    }
    
  3. AndroidManifest.xml中声明它,并添加必要的权限:

    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    
    <application>
    
        <provider
            android:name=".ApiProvider"
            android:authorities="wifi"
            android:exported="true" />
    </application>
    
  4. 构建应用并安装。

  5. 从ADB调用:

    adb shell content query --uri content://wifi/enable
    adb shell content query --uri content://wifi/disable
    
  6. 创建一个批处理脚本/Shell函数/Shell别名,使用简短的名称调用这些命令。

根据您的设备,您可能需要额外的权限。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接