android 屏蔽wifi功能,Android:若wifi未开启给出相应弹框
預期效果
用戶正在與本應用程序界面交互時,或本應用程序退到后臺時,只要檢測wifi被關閉,都能彈出相應對話框提示用戶“請打開wifi”,用戶必須點擊對話框中的確定按鈕跳轉到“網絡設置界面”。
請打開wifi.png
思路
1. 監聽wifi開關狀態改變廣播、在廣播接收器中進行邏輯判斷
想要實現上述效果的話,存在這樣一個問題,因為當我們被通知需要打開wifi時可能處于任何一個界面,難道要為每個界面上都編寫一個彈出對話框的邏輯嗎?
不能呀!借助廣播的知識,當wifi開關狀態改變時會收到一條系統廣播,這條廣播就是用于進行處理彈框邏輯的通知。所以“請打開wifi”彈框的邏輯寫在接收這條廣播的廣播接收器中。這樣該邏輯判斷不會依附于任何界面,不管在程序的任何地方,只要發出這樣一條廣播,就可以完成這個邏輯判斷。
系統廣播WifiManager.WIFI_STATE_CHANGED_ACTION,通過監聽wifi開關狀態變化的廣播,
wifi開關狀態
WifiManager.WIFI_STATE_DISABLED ; (1) 關閉
WifiManager..WIFI_STATE_ENABLED ; (3) 打開
WifiManager..WIFI_STATE_DISABLING ;(0) 關閉中
WifiManager..WIFI_STATE_ENABLING ; (2) 打開中
WifiManager..WIFI_STATE_UNKONW ; (4) 未知
2. 廣播接收器注冊、取消注冊的地方
一般廣播接收器是在onResume()中注冊,onPause()中取消注冊。從Activity的生命周期特點可知,onResume()方法被回調后Activity可與用戶交互,onPause()被回調后Activity不可與用戶交互。這樣的做法:保證了始終只有棧頂的活動才能接收到廣播,非棧頂的活動不應該也沒必要去接收這條廣播,當一個活動失去棧頂位置時自動取消廣播接收器的注冊。
但現在,我們的需求是,在Activity可與用戶交互,或不可與用戶交互時都可彈框提示用戶。故選擇在onCreate()中注冊廣播接收器(Activity始終可以接收這條廣播),在onDestroy()中取消注冊。
3.廣播接收器onReceive()方法中的邏輯
onReceive()方法中的邏輯.png
public class WifiListenerReceiver extends BroadcastReceiver {
public static final String MY_WIFI_BROADCAST="MY_WIFI_BROADCAST";
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action) || Constant.WIFI_LISTENER_ACTION.equals(action)) {
int wifiState = DeviceInfoUtil.getWifiState(context);
Log.e("LoginActivity", "收到wifi廣播"+wifiState);
switch (wifiState) {
case WifiManager.WIFI_STATE_DISABLED:
case WifiManager.WIFI_STATE_DISABLING:
case WifiManager.WIFI_STATE_UNKNOWN:
/*
* wifi處于關閉狀態:若“請打開wifi對話框”正在顯示,將該對話框顯示在前臺;
* 未正在顯示:創建新的并顯示
*/
Intent intent1 = new Intent(context, OpenWifiActivity.class);
// 以SingleTask的模式啟動(棧內復用)
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
break;
case WifiManager.WIFI_STATE_ENABLED:
case WifiManager.WIFI_STATE_ENABLING:
/*
* wifi處于開啟狀態:若“請打開wifi對話框”正在顯示,將該對話框關閉;
* 未正在顯示:Nothing
*/
OpenWifiActivityCollector.finishAll();
break;
}
}
}
}
3.1“請打開wifi”框的制作:用Activity做成Dialog的樣式
將OpenWifiActivity主題設置為
@android:color/transparent 設置dialog的背景,此處為系統給定的透明值
@null Dialog的windowFrame框為無
true 是否顯示標題
true 是否浮現在activity之上
true 是否半透明
@null 是否有覆蓋
@android:style/Animation.Dialog 設置Activity出現方式
true 背景是否模糊顯示
3.2可能會出現:連續彈出多個“請打開wifi”框
此處是將Activity做成Dialog的效果顯示出來。故將Activity的啟動模式設置成SingleTask,就可保證棧內復用,始終只有一個彈框
android:name=".module.wifi.OpenWifiActivity"
android:theme="@style/FDialogStyle"
android:launchMode="singleTask">
3.3會出現的情況:“請打開wifi”框正在顯示,通過通知欄打開wifi,但該框未被銷毀
用一個專門的集合類對所有打開的OpenWifiActivity實例進行存儲。當需要關閉OpenWifiActivity時,finish掉集合中保存的該活動的所有實例
public class OpenWifiActivity extends Activity {
@BindView(R.id.btn_openwifi_sure)
Button btn_sure;
@BindView(R.id.btn_openwifi_cancel)
Button btn_cancel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_openwifi);
KnifeKit.bind(this);
// 加入到ActivityCollector中
OpenWifiActivityCollector.addActivity(this);
btn_sure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DeviceInfoUtil.openWifiSetting(getApplicationContext());
finish();
}
});
btn_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
// 從管理類中移除實例
OpenWifiActivityCollector.removeActivity(this);
}
}
public class OpenWifiActivityCollector {
public static List sActivities = new ArrayList<>();
public static void addActivity(Activity activity) {
sActivities.add(activity);
}
public static void removeActivity(Activity activity) {
sActivities.remove(activity);
}
public static void finishAll() {
for (Activity activity : sActivities) {
if (!activity.isFinishing()) {
activity.finish();
}
}
}
}
代碼實現【下面給出相關代碼文件】
1.base
base.png
MyBaseActivity
public abstract class MyBaseActivity extends AppCompatActivity implements MyUiCallback {
public static AlertDialog mAlertDialog;
protected Activity context;
private Unbinder unbinder;
// GPS檢測監聽
private GPSListenerRecevicer receiver;
// Wifi狀態改變監聽
private WifiListenerReceiver mWifiListenerReceiver;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(getClass().getSimpleName(), "onCreate");
this.context = this;
beforeSetConentView(savedInstanceState);
if (getLayoutId() > 0) {
setContentView(getLayoutId());
unbinder = KnifeKit.bind(this);
}
setListener();
initData(savedInstanceState);
/*
* 在onCreate中注冊WiFi廣播監聽,在onDestroy中取消注冊
* ylj
*/
registerWifiReceiver();
}
/**
* 注冊wifi狀態改變廣播接收器
*/
protected void registerWifiReceiver(){
mWifiListenerReceiver = new WifiListenerReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(Constant.WIFI_LISTENER_ACTION);
registerReceiver(mWifiListenerReceiver, filter);
}
@Override
public void beforeSetConentView(Bundle savedInstanceState) {
}
@Override
public void setListener() {
}
@Override
protected void onResume() {
super.onResume();
Log.e(getClass().getSimpleName(), "onResume");
/*
*
* 在每次resume中,發送一條檢測wifi狀態的廣播
*/
sendCheckWifiStateBroadcast();
}
protected void sendCheckWifiStateBroadcast(){
Intent intent = new Intent();
intent.setAction(Constant.WIFI_LISTENER_ACTION);
sendBroadcast(intent);
Log.e(getClass().getSimpleName(), "發出MY_WIFI_BROADCAST廣播");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(getClass().getSimpleName(), "onDestroy");
/*
* 取消注冊wifi狀態改變廣播接收器
* ylj
*/
unregisterWifiReceiver();
}
/**
* 取消注冊wifi狀態改變廣播接收器
* ylj
*/
private void unregisterWifiReceiver() {
if (mWifiListenerReceiver != null) {
unregisterGPSListener();
mWifiListenerReceiver = null;
}
}
}
MyUiCallback
/**
*
* author : 楊麗金
* time : 2018/03/23
* desc :
*
*/
public interface MyUiCallback {
// 在setContentView()之前調用的方法
void beforeSetConentView(Bundle savedInstanceState);
// 下面的三個方法都是在setContentView()之后調用的
void initData(Bundle savedInstanceState);
void setListener();
int getLayoutId();
}
2.wifi
wifi.png
OpenWifiActivity
public class OpenWifiActivity extends Activity {
@BindView(R.id.btn_openwifi_sure)
Button btn_sure;
@BindView(R.id.btn_openwifi_cancel)
Button btn_cancel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_openwifi);
KnifeKit.bind(this);
// 加入到ActivityCollector中
OpenWifiActivityCollector.addActivity(this);
btn_sure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DeviceInfoUtil.openWifiSetting(getApplicationContext());
finish();
}
});
btn_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
// 從管理類中移除實例
OpenWifiActivityCollector.removeActivity(this);
}
}
OpenWifiActivityCollector
/**
*
* author : 楊麗金
* time : 2018/06/05
* desc : 管理OPENWiFiActivity實例
*
*/
public class OpenWifiActivityCollector {
public static List sActivities = new ArrayList<>();
public static void addActivity(Activity activity) {
sActivities.add(activity);
}
public static void removeActivity(Activity activity) {
sActivities.remove(activity);
}
public static void finishAll() {
for (Activity activity : sActivities) {
if (!activity.isFinishing()) {
activity.finish();
}
}
}
}
WifiListenerBroadcast
public class WifiListenerReceiver extends BroadcastReceiver {
public static final String MY_WIFI_BROADCAST="MY_WIFI_BROADCAST";
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action) || Constant.WIFI_LISTENER_ACTION.equals(action)) {
int wifiState = DeviceInfoUtil.getWifiState(context);
Log.e("LoginActivity", "收到wifi廣播"+wifiState);
switch (wifiState) {
case WifiManager.WIFI_STATE_DISABLED:
case WifiManager.WIFI_STATE_DISABLING:
case WifiManager.WIFI_STATE_UNKNOWN:
/*
* wifi處于關閉狀態:若“請打開wifi對話框”正在顯示,將該對話框顯示在前臺;
* 未正在顯示:創建新的并顯示
*/
Intent intent1 = new Intent(context, OpenWifiActivity.class);
// 以SingleTask的模式啟動(棧內復用)
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
break;
case WifiManager.WIFI_STATE_ENABLED:
case WifiManager.WIFI_STATE_ENABLING:
/*
* wifi處于開啟狀態:若“請打開wifi對話框”正在顯示,將該對話框關閉;
* 未正在顯示:Nothing
*/
OpenWifiActivityCollector.finishAll();
break;
}
}
}
}
參考文獻
總結
以上是生活随笔為你收集整理的android 屏蔽wifi功能,Android:若wifi未开启给出相应弹框的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EndNote文献管理(二)基操勿六
- 下一篇: Android -- 传感器使用示例,