1. 程式人生 > >Android 8.0 WiFi Ap 熱點控制介面

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);
            }
        }
    }

相關推薦

Android 8.0 WiFi Ap 熱點控制介面

1. Android 7.0 及其以前的 WiFi 熱點介面 /** * Gets the Wi-Fi enabled state. * * @return One of {@link #WIFI_AP_STATE_D

Android 9.0 (P版本) 亮度控制介面變更

1. Android 9.0 之前的亮度控制介面 import android.os.IPowerManager; import android.provider.Settings; import android.content.Context; /

Android 8.0無法獲取wifi ssid (unknow ssid)解決方案

一直都在做wifi相關的東西 今天遇到一個問題是8.0的機型無法獲取到ssid 然後就查詢了一番 終於找到解決方案 wifi名稱獲取程式碼 WifiManager my_wifiManager = ((WifiManager) getApplicationContext

android 8.0 自定義控制元件onmesure獲取寬度為0

最近專案需要適配8.0版本,自定義控制元件出現了下面的問題 第一次顯示此彈窗字型出現了偏移,找到原因是textpaint在繪製文字的時候 canvas.drawText(itemText, x + (controlWidth / 2) -textRect.width

Android 8.0 Settings往介面新增選單

1、SettingsActivity.java 檔案下的doUpdateTilesList方法裡新增: setTileEnabled(new ComponentName(packageName, Settings.WtkSecurityLockersActivity.class.ge

Android 8.0 系統學習(6)---Linux核心介面要求

您可以將以下配置設定用作 Android 核心配置的基礎。設定會整理到 android-base、android-base-<arch> 和 android-recommended.cfg 檔案中:android-base。這些選項可實現核心 Android 功能,並且應配置為所有裝置指定的選項。

Android 8.0 上面關於wifi 的一些坑

背景 現在安卓系統已經更新到8.0了。曾經開啟手機wifi以及搜尋wifi的方法可能對8.0的安卓系統不管用了。這裡就提一些在開發中遇到的坑。 一. 開啟wifi 以及 關閉wifi 首先需要開啟修改系統設定的許可權: private void c

Android 8.0 AlarmManager 後臺定時任務

blank 也有 情況 pre ati ng- TP 問題 manage 以前在Android 4.0時,alarmManager 沒什麽問題。後來android為了優化系統耗電情況,引入了doze模式,參見此頁 https://developer.android.com/

android 通知(android 8.0可用)

通知 bsp null uil build eat 正常 nag HA final String CHANNEL_ID = "channel_id_1"; final String CHANNEL_NAME = "channel_name_1"; Notificatio

Android 8.0 的部分坑及對應解決方法

channel 資料 兼容 androi adb install 只需要 方法 tps 雖然 Android 9.0 都已經面世了,本篇文章寫的有點遲了。 但是遲到好過不到,因此基於此這邊還是記錄一下項目中遇到的 Android 8.0 的坑及對應解決方法。 每次系統

解決:Android 8.0檢測不到當前的activity

detail itl href 9.png 8.0 target cti htm EDA 前兩天從Android 7.0升級到Android 8.0,今天在用 adb shell dumpsys activity | findstr "mFocusedActivity"來獲

Android 8.0 system app載入so Permission denied 解決

在預置包含react native 的Android app 預置到mtk 6739的系統中,此app 具體 platform 簽名。此app啟動會載入一些 facebook的so庫 發現此app 如果預置到system/app下,啟動會報錯。開始以為是沒有把相關的so庫 放到 sys

Android 8.0踩坑記錄——Only fullscreen opaque activities can request orientation

原文地址:https://www.jianshu.com/p/d0d907754603   前言 各位小夥伴大家好啊,昨天屁顛屁顛把專案適配到8.0,本來覺得美滋滋,結果app一啟動直接crash,搞得我一臉懵逼。。。不能忍啊,趕緊去看一下日誌,於是就看到了如下圖 &nbs

Android 學習之那些年我們遇到的BUG2:Android 8.0 自定義廣播接收失敗

自學安卓的過程中遇到的一個問題,在嘗試實現郭霖大佬的《第一行程式碼》第二版中的第五章的傳送自定義廣播時,發現自定義的廣播接收失敗! 按照要求完成相應的程式碼編寫後,發現點選按鈕,Toast未顯示,表明廣播接收器沒能接收到自定義的廣播。 解決方法: 高版本的Android對於廣播的

Android 8.0 電池顯示,電池定製

這篇文章主要說的是android8.0SystemUI電池顯示方面。 好像是從android8.0起,電池是通過程式碼繪製的,並非往常版本是使用drawable下的圖片直接顯示的,這樣的話,修改起來就比較麻煩。 一、電池佈局 frameworks\base\packages\SystemUI\r

螢幕適配——系統升級android 8.0 部分UI出現錯亂——“可用螢幕解析度”

這兩天將自己的mate9從7.0升級到8.0發現一個問題,app的某個ui介面部分錯亂了;因為螢幕適配使用了dimens適配,所以猜測有可能螢幕規格沒有覆蓋到;但是發現mate9的螢幕解析度為1920*1080,查看了dimens檔案是有覆蓋的,為什麼7.0時候沒有問題,升級到8.0出現

Android 8.0通知欄推送及適配

上一篇我們確保了我們開啟了通知欄的許可權,那麼接下來就是傳送推送了,廢話不多說,上程式碼。 首先我們判斷手機版本號,Android版本大於8.0的時候呢,我們需要進行一下通道的操作才可:判斷版本號程式碼接好 //此處判斷安卓版本號是否大於或者等於Android8.0 if (Build.VE

Android 8.0通知欄許可權開啟適配

使用手機時,我們經常會碰到各種通知,例如微信,QQ,瀏覽器等等,不厭其煩的給你各種推送,本文將演示通知的大致流程 首先,我們在一個適當的時機檢查我們App的通知欄許可權 boolean Jurisdiction = NotificationManagerCompat.from(AppAppl

相容 android 8.0 通知

import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; imp

Android 8.0 升級筆記(適配圖片、通知欄、ContentProvider、Receiver)

Android 8.0 升級筆記 前言 Google 在2017年就釋出了Android 8.0,並且強制AppStore上得應用都要升級,國內得不曉得。為了防止出現之前升級6.0 得時候許可權問題導致Crash這種情況得發生…這次很小心得去看了Google得升級意見,小夥伴們可以自