Android以编程方式打开/关闭WiFi HotSpot

时间:2011-06-18 07:39:34

标签: android wifi android-wifi

是否有API以编程方式打开/关闭Android上的WiFi HotSpot?

我应该用什么方法打开/关闭它?

更新:这个选项可以启用HotSpot,只需打开/关闭WiFi,但对我来说这不是一个好的解决方案。

14 个答案:

答案 0 :(得分:50)

使用以下课程更改/检查Wifi hotspot设置:

import android.content.*;
import android.net.wifi.*;
import java.lang.reflect.*;

public class ApManager {

//check whether wifi hotspot on or off
public static boolean isApOn(Context context) {
    WifiManager wifimanager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);     
    try {
        Method method = wifimanager.getClass().getDeclaredMethod("isWifiApEnabled");
        method.setAccessible(true);
        return (Boolean) method.invoke(wifimanager);
    }
    catch (Throwable ignored) {}
    return false;
}

// toggle wifi hotspot on or off
public static boolean configApState(Context context) {
    WifiManager wifimanager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
    WifiConfiguration wificonfiguration = null;
    try {  
        // if WiFi is on, turn it off
        if(isApOn(context)) {               
            wifimanager.setWifiEnabled(false);
        }               
        Method method = wifimanager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);                   
        method.invoke(wifimanager, wificonfiguration, !isApOn(context));
        return true;
    } 
    catch (Exception e) {
        e.printStackTrace();
    }       
    return false;
}
} // end of class

您需要将以下权限添加到AndroidMainfest:

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

从任何地方使用此独立ApManager类,如下所示:

ApManager.isApOn(YourActivity.this); // check Ap state :boolean
ApManager.configApState(YourActivity.this); // change Ap state :boolean

希望这有助于某人

答案 1 :(得分:8)

Android SDK中没有与WiFi热点功能相关的方法 - 抱歉!

答案 2 :(得分:4)

您可以使用以下代码以编程方式启用,禁用和查询wifi直接状态。

package com.kusmezer.androidhelper.networking;

import java.lang.reflect.Method;
import com.google.common.base.Preconditions;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.util.Log;

public final class WifiApManager {
      private static final int WIFI_AP_STATE_FAILED = 4;
      private final WifiManager mWifiManager;
      private final String TAG = "Wifi Access Manager";
      private Method wifiControlMethod;
      private Method wifiApConfigurationMethod;
      private Method wifiApState;

      public WifiApManager(Context context) throws SecurityException, NoSuchMethodException {
       context = Preconditions.checkNotNull(context);
       mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
       wifiControlMethod = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class,boolean.class);
       wifiApConfigurationMethod = mWifiManager.getClass().getMethod("getWifiApConfiguration",null);
       wifiApState = mWifiManager.getClass().getMethod("getWifiApState");
      }   
      public boolean setWifiApState(WifiConfiguration config, boolean enabled) {
       config = Preconditions.checkNotNull(config);
       try {
        if (enabled) {
            mWifiManager.setWifiEnabled(!enabled);
        }
        return (Boolean) wifiControlMethod.invoke(mWifiManager, config, enabled);
       } catch (Exception e) {
        Log.e(TAG, "", e);
        return false;
       }
      }
      public WifiConfiguration getWifiApConfiguration()
      {
          try{
              return (WifiConfiguration)wifiApConfigurationMethod.invoke(mWifiManager, null);
          }
          catch(Exception e)
          {
              return null;
          }
      }
      public int getWifiApState() {
       try {
            return (Integer)wifiApState.invoke(mWifiManager);
       } catch (Exception e) {
        Log.e(TAG, "", e);
            return WIFI_AP_STATE_FAILED;
       }
      }
}

答案 3 :(得分:3)

对于Android 8.0,有一个新的API来处理热点。据我所知,使用反射的旧方法不再适用。 请参阅:

Android开发者 https://developer.android.com/reference/android/net/wifi/WifiManager.html#startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback,%20android.os.Handler)

void startLocalOnlyHotspot (WifiManager.LocalOnlyHotspotCallback callback, 
                Handler handler)
  

请求本地唯一的热点,应用程序可以使用该热点在连接到创建的WiFi热点的共址设备之间进行通信。此方法创建的网络无法访问Internet。

堆栈溢出
How to turn on/off wifi hotspot programmatically in Android 8.0 (Oreo)

  如果打开热点,将调用

onStarted(WifiManager.LocalOnlyHotspotReservation预留)方法。使用WifiManager.LocalOnlyHotspotReservation引用,调用close()方法关闭热点。

答案 4 :(得分:2)

您最好的选择是查看WifiManager课程。特别是setWifiEnabled(bool)函数。

请参阅以下文档: http://developer.android.com/reference/android/net/wifi/WifiManager.html#setWifiEnabled(boolean)

可以在此处找到有关如何使用它的教程(包括您需要的权限): http://www.tutorialforandroid.com/2009/10/turn-off-turn-on-wifi-in-android-using.html

答案 5 :(得分:1)

这对我很有用:

WifiConfiguration apConfig = null;
Method method = wifimanager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
method.invoke(wifimanager, apConfig, true);

答案 6 :(得分:1)

我发布了非官方的api,它包含的不仅仅是热点转on/offlink

对于API的DOC - link

答案 7 :(得分:1)

仅适用于Oreo + ...

我创建了一个代码here on GitHub的应用,它使用反射和DexMaker来“获取”Oreo的网络共享功能,该功能现在位于ConnectionManager,而不是WifiManager

WifiManager中的内容仅适用于封闭的wifi网络(解释了类名中的Closed位!)。

更多解释https://stackoverflow.com/a/49356255/772333

答案 8 :(得分:0)

**对于Oreo和PIE **我是通过以下方式找到的:through this

private WifiManager.LocalOnlyHotspotReservation mReservation;
private boolean isHotspotEnabled = false;
private final int REQUEST_ENABLE_LOCATION_SYSTEM_SETTINGS = 101;

private boolean isLocationPermissionEnable() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION}, 2);
        return false;
    }
    return true;
}

@RequiresApi(api = Build.VERSION_CODES.O)
private void turnOnHotspot() {
    if (!isLocationPermissionEnable()) {
        return;
    }
    WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

    if (manager != null) {
        // Don't start when it started (existed)
        manager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {

            @Override
            public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
                super.onStarted(reservation);
                //Log.d(TAG, "Wifi Hotspot is on now");
                mReservation = reservation;
                isHotspotEnabled = true;
            }

            @Override
            public void onStopped() {
                super.onStopped();
                //Log.d(TAG, "onStopped: ");
                isHotspotEnabled = false;
            }

            @Override
            public void onFailed(int reason) {
                super.onFailed(reason);
                //Log.d(TAG, "onFailed: ");
                isHotspotEnabled = false;
            }
        }, new Handler());
    }
}

@RequiresApi(api = Build.VERSION_CODES.O)
private void turnOffHotspot() {
    if (!isLocationPermissionEnable()) {
        return;
    }
    if (mReservation != null) {
        mReservation.close();
        isHotspotEnabled = false;
    }
}

@RequiresApi(api = Build.VERSION_CODES.O)
private void toggleHotspot() {
    if (!isHotspotEnabled) {
        turnOnHotspot();
    } else {
        turnOffHotspot();
    }
}

@RequiresApi(api = Build.VERSION_CODES.O)
private void enableLocationSettings() {
    LocationRequest mLocationRequest = new LocationRequest();
    /*mLocationRequest.setInterval(10);
    mLocationRequest.setSmallestDisplacement(10);
    mLocationRequest.setFastestInterval(10);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);*/
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
    builder.addLocationRequest(mLocationRequest)
            .setAlwaysShow(false); // Show dialog

    Task<LocationSettingsResponse> task= LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());

    task.addOnCompleteListener(task1 -> {
        try {
            LocationSettingsResponse response = task1.getResult(ApiException.class);
            // All location settings are satisfied. The client can initialize location
            // requests here.
            toggleHotspot();

        } catch (ApiException exception) {
            switch (exception.getStatusCode()) {
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    // Location settings are not satisfied. But could be fixed by showing the
                    // user a dialog.
                    try {
                        // Cast to a resolvable exception.
                        ResolvableApiException resolvable = (ResolvableApiException) exception;
                        // Show the dialog by calling startResolutionForResult(),
                        // and check the result in onActivityResult().
                        resolvable.startResolutionForResult(HotspotActivity.this, REQUEST_ENABLE_LOCATION_SYSTEM_SETTINGS);
                    } catch (IntentSender.SendIntentException e) {
                        // Ignore the error.
                    } catch (ClassCastException e) {
                        // Ignore, should be an impossible error.
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    // Location settings are not satisfied. However, we have no way to fix the
                    // settings so we won't show the dialog.
                    break;
            }
        }
    });
}

@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
    switch (requestCode) {
        case REQUEST_ENABLE_LOCATION_SYSTEM_SETTINGS:
            switch (resultCode) {
                case Activity.RESULT_OK:
                    // All required changes were successfully made
                    toggleHotspot();
                    Toast.makeText(HotspotActivity.this,states.isLocationPresent()+"",Toast.LENGTH_SHORT).show();
                    break;
                case Activity.RESULT_CANCELED:
                    // The user was asked to change settings, but chose not to
                    Toast.makeText(HotspotActivity.this,"Canceled",Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
            break;
    }
}

UseAge

btnHotspot.setOnClickListenr(view -> {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        // Step 1: Enable the location settings use Google Location Service
        // Step 2: https://stackoverflow.com/questions/29801368/how-to-show-enable-location-dialog-like-google-maps/50796199#50796199
        // Step 3: If OK then check the location permission and enable hotspot
        // Step 4: https://stackoverflow.com/questions/46843271/how-to-turn-off-wifi-hotspot-programmatically-in-android-8-0-oreo-setwifiapen
        enableLocationSettings();
        return;
    }
}

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

implementation 'com.google.android.gms:play-services-location:15.0.1'

答案 9 :(得分:0)

我们可以以编程方式打开和关闭

setWifiApDisable.invoke(connectivityManager, TETHERING_WIFI);//Have to disable to enable
setwifiApEnabled.invoke(connectivityManager, TETHERING_WIFI, false, mSystemCallback,null);

使用回调类,以编程方式打开pie(9.0)中的热点,您需要以编程方式关闭并打开。

答案 10 :(得分:0)

您可以将控制台和服务用于该选项。

我认为您可以解决这个问题。我直接在控制台中进行了测试并启用了热点

我在这篇文章中找到了这个 Is it possible to USB tether an android device using adb through the terminal?

读取接口后,我们可以使用相同的24个,但需要更多参数

  

服务呼叫连通性24 i32 0 i32 1 i32 0 s16随机

答案 11 :(得分:0)

如果您要在Android应用中以编程方式实现wifi热点功能,则以下是完整的解决方案。

API解决方案<26:

对于设备 reflection 来访问私有API。不建议这样做,但是如果您没有其他选择,那么这里有个窍门。

首先,您需要在清单中拥有此权限,

  <uses-permission  
  android:name="android.permission.WRITE_SETTINGS"  
  tools:ignore="ProtectedPermissions"/>

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

您可以在运行时提出以下要求:

 private boolean showWritePermissionSettings() {    
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M  
    && Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { 
  if (!Settings.System.canWrite(this)) {    
    Log.v("DANG", " " + !Settings.System.canWrite(this));   
    Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS); 
    intent.setData(Uri.parse("package:" + this.getPackageName()));  
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    this.startActivity(intent); 
    return false;   
  } 
}   
return true; //Permission already given 
}

然后您可以通过反射访问setWifiEnabled方法。如果您要执行的操作已正确处理(即启用/禁用热点),则返回true。

     public boolean setWifiEnabled(WifiConfiguration wifiConfig, boolean enabled) { 
 WifiManager wifiManager;
try {   
  if (enabled) { //disables wifi hotspot if it's already enabled    
    wifiManager.setWifiEnabled(false);  
  } 

   Method method = wifiManager.getClass()   
      .getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);   
  return (Boolean) method.invoke(wifiManager, wifiConfig, enabled); 
} catch (Exception e) { 
  Log.e(this.getClass().toString(), "", e); 
  return false; 
}   
}

您还可以通过反射获得热点的wifi配置。我已经在StackOverflow上answered使用了该方法来解决这个问题。

PS:如果您不想以编程方式打开热点,则可以启动此intent并打开wifi设置屏幕,以供用户手动将其打开。

API解决方案> = 26:

最后,android为版本> = Oreo发布了官方API。您只能通过Android使用公开的API,即startLocalOnlyHotspot

它打开了无法访问互联网的本地热点。因此可以用来托管服务器或传输文件。

它需要Manifest.permission.CHANGE_WIFI_STATEACCESS_FINE_LOCATION权限。

这是一个简单的示例,说明如何使用此API打开热点。

private WifiManager wifiManager;
WifiConfiguration currentConfig;
WifiManager.LocalOnlyHotspotReservation hotspotReservation;

打开热点的方法:

@RequiresApi(api = Build.VERSION_CODES.O)
public void turnOnHotspot() {

      wifiManager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {

        @Override
        public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
          super.onStarted(reservation);
          hotspotReservation = reservation;
          currentConfig = hotspotReservation.getWifiConfiguration();

          Log.v("DANG", "THE PASSWORD IS: "
              + currentConfig.preSharedKey
              + " \n SSID is : "
              + currentConfig.SSID);

          hotspotDetailsDialog();

        }

        @Override
        public void onStopped() {
          super.onStopped();
          Log.v("DANG", "Local Hotspot Stopped");
        }

        @Override
        public void onFailed(int reason) {
          super.onFailed(reason);
          Log.v("DANG", "Local Hotspot failed to start");
        }
      }, new Handler());
    }
`

在这里,您可以获取本地创建的热点的详细信息

private void hotspotDetaisDialog()
{

    Log.v(TAG, context.getString(R.string.hotspot_details_message) + "\n" + context.getString(
              R.string.hotspot_ssid_label) + " " + currentConfig.SSID + "\n" + context.getString(
              R.string.hotspot_pass_label) + " " + currentConfig.preSharedKey);

}

如果抛出该异常,即使在授予必需的权限后也会出现安全异常,那么您应该尝试使用GPS启用位置。这是solution

最近,我开发了一个名为Spotserve的演示应用程序。这会为所有API> = 15的设备打开wifi热点,并在该热点上托管一个演示服务器。您可以检查更多细节。希望这会有所帮助!

答案 12 :(得分:0)

APManager-接入点管理器

步骤1:将jcenter存储库添加到您的构建文件中
allprojects {
    repositories {
        ...
        jcenter()
    }
}
步骤2:添加依赖项
dependencies {
    implementation 'com.vkpapps.wifimanager:APManager:1.0.0'
}
第3步在您的应用中使用
APManager apManager = APManager.getApManager(this);
apManager.turnOnHotspot(this, new APManager.OnSuccessListener() {

    @Override
    public void onSuccess(String ssid, String password) {
        //write your logic
    }

}, new APManager.OnFailureListener() {

    @Override
    public void onFailure(int failureCode, @Nullable Exception e) {
        //handle error like give access to location permission,write system setting permission,
        //disconnect wifi,turn off already created hotspot,enable GPS provider
        
        //or use DefaultFailureListener class to handle automatically
    }

});

签出源代码 https://github.com/vijaypatidar/AndroidWifiManager

答案 13 :(得分:-3)

WifiManager wifiManager = (WifiManager)this.context.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(status);

状态可以是truefalse

添加权限清单:<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />