Android 8.0 WiFi Ap 热点控制接口

1. Android 7.0 及其以前的 WiFi 热点接口

    /**
     * Gets the Wi-Fi enabled state.
     *
     * @return One of {@link #WIFI_AP_STATE_DISABLED},
     * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
     * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
     * @see #isWifiApEnabled()
     */
    public static boolean isWiFiApOpened(Context mContext) {
        WifiManager mWifiManager = ((WifiManager) mContext.getSystemService(Context.WIFI_SERVICE));
        int state = mWifiManager.getWifiApState();
        return (state == WifiManager.WIFI_AP_STATE_ENABLING || state == WifiManager.WIFI_AP_STATE_ENABLED);
    }

    /**
     * Start AccessPoint mode with the specified configuration. If the radio is
     * already running in AP mode, update the new configuration Note that
     * starting in access point mode disables station mode operation
     *
     * @param wifiConfig SSID, security and channel details as part of
     *                   WifiConfiguration
     * @return {@code true} if the operation succeeds, {@code false} otherwise
     */
    public static void setWiFiApEnable(Context mContext, boolean value) {
        WifiManager mWifiManager = ((WifiManager) mContext.getSystemService(Context.WIFI_SERVICE));
        mWifiManager.setWifiApEnabled(null, value);
    }

2. Android 8.0 的 WiFi 热点接口

2.1 判断 WiFi Ap 是否打开
========================================================
private WiFiApReceiver mWiFiApReceiver;

        mWiFiApReceiver = new WiFiApReceiver();
        // 注册广播事件
        mWiFiApReceiver.setListening(true);

========================================================
    /**
     * Android 8.0 WiFi Ap Listener
     */
    private static int isWiFiApState = WifiManager.WIFI_AP_STATE_FAILED;

    public static boolean isWiFiApOpened_O() {
        return (isWiFiApState == WifiManager.WIFI_AP_STATE_ENABLING || isWiFiApState == WifiManager.WIFI_AP_STATE_ENABLED);
    }

    private final class WiFiApReceiver extends BroadcastReceiver {
        private boolean mRegistered;

        public void setListening(boolean listening) {
            if (listening && !mRegistered) {
                Log.d(TAG, "Registering receiver");
                final IntentFilter filter = new IntentFilter();
                filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
                mContext.registerReceiver(this, filter);
                mRegistered = true;
            } else if (!listening && mRegistered) {
                Log.d(TAG, "Unregistering receiver");
                mContext.unregisterReceiver(this);
                mRegistered = false;
            }
        }

        public void onReceive(Context context, Intent intent) {
            isWiFiApState = intent.getIntExtra(
                    WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
            String result = null;

            switch (isWiFiApState) {
                case WifiManager.WIFI_AP_STATE_DISABLED:
                    result = "DISABLED";
                    break;
                case WifiManager.WIFI_AP_STATE_DISABLING:
                    result =  "DISABLING";
                    break;
                case WifiManager.WIFI_AP_STATE_ENABLED:
                    result =  "ENABLED";
                    break;
                case WifiManager.WIFI_AP_STATE_ENABLING:
                    result =  "ENABLING";
                    break;
                case WifiManager.WIFI_AP_STATE_FAILED:
                    result =  "FAILED";
                    break;
            }

            Log.d(TAG, "WiFi state : " + result);
        }
    }
2.2 控制 WiFi Ap 打开与关闭
2.2.1 需要的权限
    <!-- WiFi AP startTethering -->
    <uses-permission android:name="android.permission.TETHER_PRIVILEGED" />
2.2.2 Android 8.0 WiFi 热点打开与关闭接口
    /**
     * Android 8.0 WiFi Ap Settings
     * <uses-permission android:name="android.permission.TETHER_PRIVILEGED" />
     */
    public static void setWiFiApEnable_O(Context mContext, boolean value) {
        ConnectivityManager mConnectivityManager= (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (value) {
            mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI, false, new ConnectivityManager.OnStartTetheringCallback() {
                @Override
                public void onTetheringStarted() {
                    Log.d(TAG, "onTetheringStarted");
                    // Don't fire a callback here, instead wait for the next update from wifi.
                }

                @Override
                public void onTetheringFailed() {
                  Log.d(TAG, "onTetheringFailed");
                  // TODO: Show error.
                }
            });
        } else {
            mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
        }
    }
2.2.3 相关源码

frameworks/base/core/java/android/net/ConnectivityManager.java

    @SystemApi
    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
    public void startTethering(int type, boolean showProvisioningUi,
            final OnStartTetheringCallback callback) {
        startTethering(type, showProvisioningUi, callback, null);
    }

    /**
     * Runs tether provisioning for the given type if needed and then starts tethering if
     * the check succeeds. If no carrier provisioning is required for tethering, tethering is
     * enabled immediately. If provisioning fails, tethering will not be enabled. It also
     * schedules tether provisioning re-checks if appropriate.
     *
     * @param type The type of tethering to start. Must be one of
     *         {@link ConnectivityManager.TETHERING_WIFI},
     *         {@link ConnectivityManager.TETHERING_USB}, or
     *         {@link ConnectivityManager.TETHERING_BLUETOOTH}.
     * @param showProvisioningUi a boolean indicating to show the provisioning app UI if there
     *         is one. This should be true the first time this function is called and also any time
     *         the user can see this UI. It gives users information from their carrier about the
     *         check failing and how they can sign up for tethering if possible.
     * @param callback an {@link OnStartTetheringCallback} which will be called to notify the caller
     *         of the result of trying to tether.
     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
    public void startTethering(int type, boolean showProvisioningUi,
            final OnStartTetheringCallback callback, Handler handler) {
        Preconditions.checkNotNull(callback, "OnStartTetheringCallback cannot be null.");

        ResultReceiver wrappedCallback = new ResultReceiver(handler) {
            @Override
            protected void onReceiveResult(int resultCode, Bundle resultData) {
                if (resultCode == TETHER_ERROR_NO_ERROR) {
                    callback.onTetheringStarted();
                } else {
                    callback.onTetheringFailed();
                }
            }
        };

        try {
            String pkgName = mContext.getOpPackageName();
            Log.i(TAG, "startTethering caller:" + pkgName);
            mService.startTethering(type, wrappedCallback, showProvisioningUi, pkgName);
        } catch (RemoteException e) {
            Log.e(TAG, "Exception trying to start tethering.", e);
            wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);
        }
    }

    /**
     * Stops tethering for the given type. Also cancels any provisioning rechecks for that type if
     * applicable.
     *
     * @param type The type of tethering to stop. Must be one of
     *         {@link ConnectivityManager.TETHERING_WIFI},
     *         {@link ConnectivityManager.TETHERING_USB}, or
     *         {@link ConnectivityManager.TETHERING_BLUETOOTH}.
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
    public void stopTethering(int type) {
        try {
            String pkgName = mContext.getOpPackageName();
            Log.i(TAG, "stopTethering caller:" + pkgName);
            mService.stopTethering(type, pkgName);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

3. 参考 SystemUI 的热点关闭

3.1 字符串

通知栏面板的快捷开关

    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"热点"</string>
3.2 搜索调用位置

grep -irn “quick_settings_hotspot_label” vendor/mediatek/proprietary/packages/apps/SystemUI/

root@69959bbb90c6:/home/suhuazhi/8.1/liangxiang# grep -irn "quick_settings_hotspot_label" vendor/mediatek/proprietary/packages/apps/SystemUI/

vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java:107:        return mContext.getString(R.string.quick_settings_hotspot_label);

vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java:115:        state.label = mContext.getString(R.string.quick_settings_hotspot_label);
3.3 WiFi 热点功能是否支持
package com.android.systemui.statusbar.policy;

public class HotspotControllerImpl implements HotspotController {

    @Override
    public boolean isHotspotSupported() {
        return mConnectivityManager.isTetheringSupported()
                && mConnectivityManager.getTetherableWifiRegexs().length != 0
                && UserManager.get(mContext).isUserAdmin(ActivityManager.getCurrentUser());
    }
3.4 WiFi 热点功能是否打开
package com.android.systemui.statusbar.policy;

public class HotspotControllerImpl implements HotspotController {

    @Override
    public boolean isHotspotEnabled() {
        return mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED;
    }
3.5 WiFi 热点功能控制
package com.android.systemui.statusbar.policy;

public class HotspotControllerImpl implements HotspotController {

    @Override
    public void setHotspotEnabled(boolean enabled) {
        if (enabled) {
            OnStartTetheringCallback callback = new OnStartTetheringCallback();
            mWaitingForCallback = true;
            if (DEBUG) Log.d(TAG, "Starting tethering");
            mConnectivityManager.startTethering(
                    ConnectivityManager.TETHERING_WIFI, false, callback);
            fireCallback(isHotspotEnabled());
        } else {
            mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
        }
    }

    private void fireCallback(boolean isEnabled) {
        synchronized (mCallbacks) {
            for (Callback callback : mCallbacks) {
                callback.onHotspotChanged(isEnabled);
            }
        }
    }
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Android 8.0 及以上版本,为了增强应用程序的安全性,Android 引入了后台限制,禁止未在前台运行的应用程序启动服务。如果您想在后台启动服务,需要使用 `startForegroundService()` 方法。这个方法会启动一个前台服务,然后你可以在服务启动后在通知栏显示一个通知,以此来告知用户服务正在运行。 以下是一个使用 `startForegroundService()` 的示例代码: ``` if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 创建一个 NotificationChannel NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT); // 向系统注册 NotificationChannel NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(channel); } // 创建一个 Intent,启动你的服务 Intent serviceIntent = new Intent(this, YourService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 在 Android 8.0 及以上版本上,需要调用 startForegroundService() 方法启动服务。 startForegroundService(serviceIntent); } else { // 在 Android 8.0 以下版本上,可以直接调用 startService() 方法启动服务。 startService(serviceIntent); } ``` 注意:如果你使用的是 `startForeground()` 方法,会在 Android 8.0 及以上版本上抛出 `IllegalStateException` 异常,因为 Android 8.0 及以上版本禁止在后台启动服务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值