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得升級意見,小夥伴們可以自