Franklin84
Franklin84

Reputation: 573

Enable/Disable wifi using Xamarin UiTest

I try to enable/disable wifi programmatically within my Xamarin Ui Test.
I already found this: Android: How to Enable/Disable Wifi or Internet Connection Programmatically. But it seems not to work within the UiTest.

I also tried something like this:

Context appContext = Android.App.Application.Context;
var wifiManager = (WifiManager)appContext.GetSystemService(Context.WifiService);
bool status = false;
wifiManager.SetWifiEnabled(status);

The first line (Android.App.Application.Context) throws an exception:

Message: System.IO.FileNotFoundException : Could not load file or assembly 'Java.Interop, Version=0.1.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065' or one of its dependencies. The system cannot find the file specified.

I'm using following namespaces:

using Android.Net.Wifi;
using Android.Content;

My project has a reference to Mono.Android.

Upvotes: 2

Views: 1825

Answers (1)

Franklin84
Franklin84

Reputation: 573

The backdoor approach works fine for me.

The solution that works for me was a combination of:

1.: Add following line to the AndroidManifest.xml file of the Android project:

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

2.: Add following lines to the MainActivity.cs of the Android project:

using Java.Interop;
using Android.Net.Wifi;

[Export("ChangeWifiState")]
public void ChangeWifiState(bool state)
{
    Context appContext = Android.App.Application.Context;
    var wifiManager = (WifiManager)appContext.GetSystemService(WifiService);
    wifiManager.SetWifiEnabled(state);
}

3.: Call following method out of the Xamarin Ui Test:

app.Invoke("ChangeWifiState", false);    // true to enable wifi, false to disable wifi

PS: I use Xamarin Forms. I've got four different projects: a core project, an Android project, a Ui project, and a test project.

I just found a second solution without using the actual app.
It uses ADB commands to enable/disable wifi:

        var process = new System.Diagnostics.Process();
        var startInfo = new System.Diagnostics.ProcessStartInfo
        {
            WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
            FileName = "cmd.exe",
            Arguments = "/C 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 & adb shell input keyevent 82 & adb shell input tap 500 1000"
        };
        process.StartInfo = startInfo;
        process.Start();

This can be used without a rooted device :).
Steps explained:
adb shell am start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings opens the wifi settings.
adb shell input keyevent 23 enables/disables wifi.
I'm not sure why the command adb shell input keyevent 19 is used, but it works.
adb shell input keyevent 82 clicks the menu button to change back to the original app.
adb shell input tap 500 1000 clicks the coordinate x=500, y=1000 (center of screen).This may need be changed for different solutions.
Sources for this solution:

Upvotes: 4

Related Questions