Android8.0以上版本开启WIFI热点方式

  • Post author:
  • Post category:其他




Android8.0以上版本开启WIFI热点方式



1、打开Wifi热点,需要一些权限

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



2、并且权限应该由用户动态授予

在应用程序高级设置-> 修改系统设置

在这里插入图片描述



3、wifi Hotspot开启关闭方式,以proxy实现

1.定义回调接口

public abstract class TestOnStartTetheringCallback {
        /**
         * Called when tethering has been successfully started.
         */
        public abstract void onTetheringStarted();
 
        /**
         * Called when starting tethering failed.
         */
        public abstract void onTetheringFailed();
 
}

2.proxy类

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.util.Log;
 
import com.android.dx.stock.ProxyBuilder;
 
import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
 
@RequiresApi(api = Build.VERSION_CODES.O)
public class TestOreoWifiManager {
    private static final String TAG = TestOreoWifiManager.class.getSimpleName();
 
    private Context mContext;
    private WifiManager mWifiManager;
    private ConnectivityManager mConnectivityManager;
 
    public TestOreoWifiManager(Context c) {
        mContext = c;
        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
        mConnectivityManager = (ConnectivityManager) mContext.getSystemService(ConnectivityManager.class);
    }
 
    /**
     * This sets the Wifi SSID and password
     * Call this before {@code startTethering} if app is a system/privileged app
     * Requires: android.permission.TETHER_PRIVILEGED which is only granted to system apps
     */
    public void configureHotspot(String name, String password) {
        WifiConfiguration apConfig = new WifiConfiguration();
        apConfig.SSID = name;
        apConfig.preSharedKey = password;
        apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        try {
            Method setConfigMethod = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
            boolean status = (boolean) setConfigMethod.invoke(mWifiManager, apConfig);
            Log.d(TAG, "setWifiApConfiguration - success? " + status);
        } catch (Exception e) {
            Log.e(TAG, "Error in configureHotspot");
            e.printStackTrace();
        }
    }
 
    /**
     * Checks where tethering is on.
     * This is determined by the getTetheredIfaces() method,
     * that will return an empty array if not devices are tethered
     *
     * @return true if a tethered device is found, false if not found
     */
    /*public boolean isTetherActive() {
        try {
            Method method = mConnectivityManager.getClass().getDeclaredMethod("getTetheredIfaces");
            if (method == null) {
                Log.e(TAG, "getTetheredIfaces is null");
            } else {
                String res[] = (String[]) method.invoke(mConnectivityManager, null);
                Log.d(TAG, "getTetheredIfaces invoked");
                Log.d(TAG, Arrays.toString(res));
                if (res.length > 0) {
                    return true;
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "Error in getTetheredIfaces");
            e.printStackTrace();
        }
        return false;
    }
*/
    /**
     * This enables tethering using the ssid/password defined in Settings App>Hotspot & tethering
     * Does not require app to have system/privileged access
     * Credit: Vishal Sharma - https://stackoverflow.com/a/52219887
     */
    public boolean startTethering(final TestOnStartTetheringCallback callback) {
 
        // On Pie if we try to start tethering while it is already on, it will
        // be disabled. This is needed when startTethering() is called programmatically.
        /*if (isTetherActive()) {
            Log.d(TAG, "Tether already active, returning");
            return false;
        }*/
 
        File outputDir = mContext.getCodeCacheDir();
        Object proxy;
        try {
            proxy = ProxyBuilder.forClass(OnStartTetheringCallbackClass())
                    .dexCache(outputDir).handler(new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            switch (method.getName()) {
                                case "onTetheringStarted":
                                    callback.onTetheringStarted();
                                    break;
                                case "onTetheringFailed":
                                    callback.onTetheringFailed();
                                    break;
                                default:
                                    ProxyBuilder.callSuper(proxy, method, args);
                            }
                            return null;
                        }
 
                    }).build();
        } catch (Exception e) {
            Log.e(TAG, "Error in enableTethering ProxyBuilder");
            e.printStackTrace();
            return false;
        }
 
        Method method = null;
        try {
            method = mConnectivityManager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, OnStartTetheringCallbackClass(), Handler.class);
            if (method == null) {
                Log.e(TAG, "startTetheringMethod is null");
            } else {
                method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE, false, proxy, null);
                Log.d(TAG, "startTethering invoked");
            }
            return true;
        } catch (Exception e) {
            Log.e(TAG, "Error in enableTethering");
            e.printStackTrace();
        }
        return false;
    }
 
    public void stopTethering() {
        try {
            Method method = mConnectivityManager.getClass().getDeclaredMethod("stopTethering", int.class);
            if (method == null) {
                Log.e(TAG, "stopTetheringMethod is null");
            } else {
                method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE);
                Log.d(TAG, "stopTethering invoked");
            }
        } catch (Exception e) {
            Log.e(TAG, "stopTethering error: " + e.toString());
            e.printStackTrace();
        }
    }
 
    private Class OnStartTetheringCallbackClass() {
        try {
            return Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
        } catch (ClassNotFoundException e) {
            Log.e(TAG, "OnStartTetheringCallbackClass error: " + e.toString());
            e.printStackTrace();
        }
        return null;
    }
}

3.调用方法

@RequiresApi(api = Build.VERSION_CODES.O)
public static void setHotspotOnPhone(Context mContext, boolean isEnable) {

  if (mTestOreoWifiManager ==null){
    mTestOreoWifiManager = new TestOreoWifiManager(mContext);
  }


  if (isEnable){
    TestOnStartTetheringCallback callback = new TestOnStartTetheringCallback() {
      @Override
      public void onTetheringStarted() {
      }

      @Override
      public void onTetheringFailed() {

      }
    };

    mTestOreoWifiManager.startTethering(callback);
  }else{
    mTestOreoWifiManager.stopTethering();
  }

}

4、上面代码还缺少一个ProxyBuilder类,添加依赖

implementation 'com.linkedin.dexmaker:dexmaker:2.28.3'

运行项目即可!



版权声明:本文为qq_42948831原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。