国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android 監(jiān)聽網(wǎng)絡(luò)狀態(tài)變化

這篇具有很好參考價(jià)值的文章主要介紹了Android 監(jiān)聽網(wǎng)絡(luò)狀態(tài)變化。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

此篇存在的主要意義在于解決用戶使用app中網(wǎng)絡(luò)狀態(tài)發(fā)生了變化,需要我們?nèi)?dòng)態(tài)監(jiān)聽網(wǎng)絡(luò)連接狀態(tài)(有網(wǎng)、無(wú)網(wǎng))、網(wǎng)絡(luò)類型 (包括wifi、移動(dòng)網(wǎng)絡(luò) -> 3G、4G等等)

android監(jiān)聽網(wǎng)絡(luò)狀態(tài)變化,Android 教程,android,網(wǎng)絡(luò)

門前授課

關(guān)于網(wǎng)絡(luò)狀態(tài)的監(jiān)聽,主要是基于 Android 廣播 - BroadcaseReceiver組件
~

同時(shí)關(guān)于廣播的注冊(cè)方面,從Android7.0開始已經(jīng)初步進(jìn)行限制,所以盡可能采用動(dòng)態(tài)注冊(cè),獻(xiàn)文如下:

Apps targeting Android 7.0 (API level 24) and higher do not receive this
broadcast if they declare the broadcast receiver in their manifest. Apps
will still receive broadcasts if they register their BroadcastReceiver with
Context.registerReceiver() and that context is still valid.
直譯如下
針對(duì)Android 7.0
(API級(jí)別24)或更高的應(yīng)用程序,如果它們?cè)谄鋗anifest中聲明廣播接收器,則不會(huì)接收此廣播。如果應(yīng)用程序?qū)⑵銪roadcastReceiver注冊(cè)為context
. registerreceiver()并且該context仍然有效,那么應(yīng)用程序仍然會(huì)接收廣播

Google在Android7.0時(shí)雖已對(duì)廣播添加了限制,但是Android8.0后基于安全原因又一次加強(qiáng)了限制,且已聲明:
應(yīng)用無(wú)法使用其清單的大部分隱式廣播(即,并非專門針對(duì)此應(yīng)用的廣播)

針對(duì)于此我們?cè)诒酒褂脛?dòng)態(tài)注冊(cè)廣播,稍微科普一下,廣播的兩種注冊(cè)方式 ~

Here:不論使用哪種注冊(cè)方式均需在AndroidMainest清單文件里面進(jìn)行注冊(cè)

  • 靜態(tài)注冊(cè)
    也就是說(shuō)在AndroidManifest文件中對(duì)BroadcastReceiver進(jìn)行注冊(cè),通常還會(huì)加上action用來(lái)過(guò)濾;此注冊(cè)方式即使退出應(yīng)用后,仍然能夠收到相應(yīng)的廣播

  • 動(dòng)態(tài)注冊(cè)
    調(diào)用Context中的registerReceiver對(duì)廣播進(jìn)行動(dòng)態(tài)注冊(cè),使用unRegisterReceiver方法對(duì)廣播進(jìn)行取消注冊(cè)的操作;故此注冊(cè)方式一般都是隨著所在的Activity或者應(yīng)用銷毀以后,不會(huì)再收到該廣播

動(dòng)態(tài)廣播提示:廣播注冊(cè)是一個(gè)創(chuàng)建的過(guò)程,那么必然也要有一個(gè)銷毀的過(guò)程,從而防止內(nèi)存泄露,那么銷毀就在是onDestroy中unregisterReceiver廣播 ~

Activity/Fragment - 注銷廣播

?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-693821.html

java

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //netWorkReceiver 之前已注冊(cè)的廣播
        if (netWorkReceiver != null) {
            unregisterReceiver(netWorkReceiver);
        }
具體實(shí)現(xiàn)

此處就是本文的核心內(nèi)容了,網(wǎng)絡(luò)的實(shí)時(shí)動(dòng)態(tài)監(jiān)聽指的是全局實(shí)時(shí)監(jiān)聽網(wǎng)絡(luò)狀態(tài),針對(duì)的對(duì)象非一個(gè)事件而是整個(gè)APP應(yīng)用項(xiàng)目 ~

AndroidMainfests - 添加權(quán)限

?

java

 <!-- 網(wǎng)絡(luò)狀態(tài) -->
 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

創(chuàng)建 - 廣播接受者

  • 基礎(chǔ)版

這里主要實(shí)時(shí)判斷網(wǎng)絡(luò)連接狀態(tài),同時(shí)判斷網(wǎng)絡(luò)類型 ~

為何說(shuō)是基礎(chǔ)版,因?yàn)檫@里雖然實(shí)現(xiàn)了功能,但是會(huì)重復(fù)收到網(wǎng)絡(luò)變動(dòng)的廣播,太影響業(yè)務(wù)邏輯了!很有可能導(dǎo)致其他并發(fā)情況!

監(jiān)聽效果
android監(jiān)聽網(wǎng)絡(luò)狀態(tài)變化,Android 教程,android,網(wǎng)絡(luò)
監(jiān)聽實(shí)現(xiàn) - NetworkReceiver(廣播接收者)

?

java

package nk.com.networklinstener;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

/**
 * @author MrLiu
 * @date 2020/5/11
 * desc 廣播接收者
 */
public class NetworkReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // 監(jiān)聽網(wǎng)絡(luò)連接,包括wifi和移動(dòng)數(shù)據(jù)的打開和關(guān)閉,以及連接上可用的連接都會(huì)接到監(jiān)聽
        // 特殊注意:如果if條件生效,那么證明當(dāng)前是有連接wifi或移動(dòng)網(wǎng)絡(luò)的,如果有業(yè)務(wù)邏輯最好把esle場(chǎng)景酌情考慮進(jìn)去!
        if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
            //獲取聯(lián)網(wǎng)狀態(tài)的NetworkInfo對(duì)象
            NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
            if (info != null) {
                //如果當(dāng)前的網(wǎng)絡(luò)連接成功并且網(wǎng)絡(luò)連接可用
                if (NetworkInfo.State.CONNECTED == info.getState() && info.isAvailable()) {
                    if (info.getType() == ConnectivityManager.TYPE_WIFI || info.getType() == ConnectivityManager.TYPE_MOBILE) {
                        Log.e("TAG", getConnectionType(info.getType()) + "已連接");
                    }
                } else {
                    Log.e("TAG", getConnectionType(info.getType()) + "已斷開");
                }
            }
        }
    }

    /**
     * 獲取連接類型
     * @param type
     * @return
     */
    private String getConnectionType(int type) {
        String connType = "";
        if (type == ConnectivityManager.TYPE_MOBILE) {
            connType = "3-4G網(wǎng)絡(luò)數(shù)據(jù)";
        } else if (type == ConnectivityManager.TYPE_WIFI) {
            connType = "WIFI網(wǎng)絡(luò)";
        }
        return connType;
    }
}
  • 優(yōu)化版(推薦)

這里在判斷網(wǎng)絡(luò)連接狀態(tài)的同時(shí)主要防止收到多條網(wǎng)絡(luò)連接回調(diào),從而導(dǎo)致邏輯錯(cuò)亂,所以采用時(shí)間校驗(yàn)實(shí)現(xiàn)類似同步鎖的效果

監(jiān)聽效果
android監(jiān)聽網(wǎng)絡(luò)狀態(tài)變化,Android 教程,android,網(wǎng)絡(luò)
監(jiān)聽實(shí)現(xiàn) - NetworkReceiver(廣播接收者)

?

java

package com.nk.machine.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

import com.nk.machine.base.MainActivity;

import java.text.SimpleDateFormat;

/**
 * @author MrLiu
 * @date 2020/5/15
 * desc 廣播接收者
 */
public class NetWorkReceiver extends BroadcastReceiver {
    private static long WIFI_TIME = 0;
    private static long ETHERNET_TIME = 0;
    private static long NONE_TIME = 0;
    private static int LAST_TYPE = -3;
    private static String TAG = "TAG";

    @Override
    public void onReceive(Context context, Intent intent) {
        // 監(jiān)聽網(wǎng)絡(luò)連接,包括wifi和移動(dòng)數(shù)據(jù)的打開和關(guān)閉,以及連接上可用的連接都會(huì)接到監(jiān)聽
        // 特殊注意:如果if條件生效,那么證明當(dāng)前是有連接wifi或移動(dòng)網(wǎng)絡(luò)的,如果有業(yè)務(wù)邏輯最好把esle場(chǎng)景酌情考慮進(jìn)去!
        if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
            long time = getTime();
            if (time != WIFI_TIME && time != ETHERNET_TIME && time != NONE_TIME) {
                final int netWorkState = getNetWorkState(context);
                if (netWorkState == 0 && LAST_TYPE != 0) {
                    WIFI_TIME = time;
                    LAST_TYPE = netWorkState;
                    Log.e(TAG, "wifi:" + time);
                } else if (netWorkState == 1 && LAST_TYPE != 1) {
                    ETHERNET_TIME = time;
                    LAST_TYPE = netWorkState;
                    Log.e(TAG, "數(shù)據(jù)網(wǎng)絡(luò):" + time);
                } else if (netWorkState == -1 && LAST_TYPE != -1) {
                    NONE_TIME = time;
                    LAST_TYPE = netWorkState;
                    Log.e(TAG, "無(wú)網(wǎng)絡(luò):" + time);
                }
            }
        }
    }

    public long getTime() {
        SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
        String date = sDateFormat.format(new java.util.Date());
        return Long.valueOf(date);
    }
    
    private static final int NETWORK_NONE = -1; //無(wú)網(wǎng)絡(luò)連接
    private static final int NETWORK_WIFI = 0; //wifi
    private static final int NETWORK_MOBILE = 1; //數(shù)據(jù)網(wǎng)絡(luò)
    //判斷網(wǎng)絡(luò)狀態(tài)與類型
    public static int getNetWorkState(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
            if (activeNetworkInfo.getType() == (ConnectivityManager.TYPE_WIFI)) {
                return NETWORK_WIFI;
            } else if (activeNetworkInfo.getType() == (ConnectivityManager.TYPE_MOBILE)) {
                return NETWORK_MOBILE;
            }
        } else {
            return NETWORK_NONE;
        }
        return NETWORK_NONE;
    }
}

MainActivity - 動(dòng)態(tài)注冊(cè)廣播

?

java

package nk.com.networklinstener;

import android.annotation.SuppressLint;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    private NetworkReceiver netWorkReceiver;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //注冊(cè)網(wǎng)絡(luò)狀態(tài)監(jiān)聽廣播
        netWorkReceiver = new NetworkReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(netWorkReceiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (netWorkReceiver != null) {
            unregisterReceiver(netWorkReceiver);
        }
    }
}
異常場(chǎng)景

首先AndroidManifest加入以下權(quán)限

?

java

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

此異常場(chǎng)景指的是app在運(yùn)行時(shí)有崩潰異常 - SecurityException,錯(cuò)誤如下 ~

?

java

java.lang.SecurityException: com.xxx.xxx was not granted  either of these permissions: android.permission.CHANGE_NETWORK_STATE, android.permission.WRITE_SETTINGS.
    at android.os.Parcel.readException(Parcel.java:1602)
    at android.os.Parcel.readException(Parcel.java:1555)
    at android.net.IConnectivityManager$Stub$Proxy.requestNetwork(IConnectivityManager.java:2064)
    at android.net.ConnectivityManager.sendRequestForNetwork(ConnectivityManager.java:2470)
    at android.net.ConnectivityManager.requestNetwork(ConnectivityManager.java:2509)
    at com.superrtc.call.NetworkMonitorAutoDetect$ConnectivityManagerDelegate.requestMobileNetwork(NetworkMonitorAutoDetect.java)
    at com.superrtc.call.NetworkMonitorAutoDetect.<init>(NetworkMonitorAutoDetect.java)
    at com.superrtc.mediamanager.XReachability.setAutoDetectConnectivityStateInternal(XReachability.java)
    at com.superrtc.mediamanager.XReachability.startMonitoring(XReachability.java)
    at com.superrtc.mediamanager.EMediaManager$7.run(EMediaManager.java)
    at android.os.Handler.handleCallback(Handler.java:743)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:150)
    at com.superrtc.util.LooperExecutor.run(LooperExecutor.java)

按理說(shuō)android.permission.CHANGE_NETWORK_STATE這一個(gè)權(quán)限,是普通權(quán)限,只在Manifest中聲明就可以獲取。

出現(xiàn)這個(gè)問(wèn)題很不科學(xué)啊,再仔細(xì)去看看錯(cuò)誤日志,發(fā)現(xiàn)報(bào)錯(cuò)只發(fā)生在6.0這個(gè)版本和部分6.0.1版本中。

那問(wèn)題應(yīng)該是出在6.0
版本中,之后去查資料后發(fā)現(xiàn),在6.0版本中這個(gè)權(quán)限默認(rèn)是被拒絕,無(wú)法獲取這個(gè)權(quán)限。所以,在需要個(gè)權(quán)限的時(shí)候會(huì)出現(xiàn)權(quán)限問(wèn)題導(dǎo)致應(yīng)用因?yàn)闄?quán)限問(wèn)題崩潰。這個(gè)在stackoverflow中有人討論過(guò)了,去看看

知道問(wèn)題的原因之后的解決方案就簡(jiǎn)單了,既然CHANGE_NETWORK_STATE權(quán)限獲取不到,那只好想辦法打開WRITE_SETTINGS這個(gè)權(quán)限了。

跳轉(zhuǎn)到應(yīng)用程序設(shè)置頁(yè)打開WRITE_SETTINGS這個(gè)權(quán)限:

?

java

Intent goToSettings = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
goToSettings.setData(Uri.parse("package:" + getPackageName()));
startActivity(goToSettings);
興趣擴(kuò)展

網(wǎng)絡(luò)廣播Actiion的三種類型

WifiManager.WIFI_STATE_CHANGED_ACTION

這個(gè)監(jiān)聽wifi的打開與關(guān)閉,與wifi的連接無(wú)關(guān);示例如下,主要查看一下 wifi連接 - 關(guān)閉過(guò)程

監(jiān)聽效果
android監(jiān)聽網(wǎng)絡(luò)狀態(tài)變化,Android 教程,android,網(wǎng)絡(luò)
示例代碼

?

java

package nk.com.networklinstener;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.util.Log;

/**
 * @author MrLiu
 * @date 2020/5/11
 * desc wifi連接/斷開過(guò)程
 */
public class NetworkReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // 監(jiān)聽wifi的打開與關(guān)閉,與wifi的連接無(wú)關(guān)
        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
            int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
            Log.e("TAG", "wifiState:" + wifiState);
            switch (wifiState) {
                case WifiManager.WIFI_STATE_ENABLING:
                    Log.e("TAG", "wifi狀態(tài):打開中");
                    break;
                case WifiManager.WIFI_STATE_ENABLED://主用:打開狀態(tài)
                    Log.e("TAG", "wifi狀態(tài):已打開");
                    break;
                case WifiManager.WIFI_STATE_DISABLING:
                    Log.e("TAG", "wifi狀態(tài):關(guān)閉中");
                    break;
                case WifiManager.WIFI_STATE_DISABLED://主用:關(guān)閉狀態(tài)
                    Log.e("TAG", "wifi狀態(tài):已關(guān)閉");
                    break;
                case WifiManager.WIFI_STATE_UNKNOWN:
                    Log.e("TAG", "wifi狀態(tài):無(wú)法識(shí)別");
                    break;
                default:
                    Log.e("TAG", "wifi狀態(tài):未知");
                    break;
            }
        }
    }
}

WifiManager.NETWORK_STATE_CHANGED_ACTION

這個(gè)監(jiān)聽wifi的連接狀態(tài)即是否連上了一個(gè)有效無(wú)線路由,當(dāng)上邊廣播的狀態(tài)是WifiManager.WIFI_STATE_DISABLING(wifi
關(guān)閉中)、WIFI_STATE_DISABLED(wifi 已關(guān)閉)的時(shí)候,根本不會(huì)接到這個(gè)廣播。

在上邊廣播接到廣播是WifiManager.WIFI_STATE_ENABLED(wifi
已打開)狀態(tài)的同時(shí)也會(huì)接到這個(gè)廣播,當(dāng)然剛打開wifi肯定還沒(méi)有連接到有效的無(wú)線

示例代碼

?

java

package nk.com.networklinstener;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.util.Log;

/**
 * @author MrLiu
 * @date 2020/5/11
 * desc wifi連接/斷開過(guò)程
 */
public class NetworkReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // 這個(gè)監(jiān)聽wifi的連接狀態(tài)即是否連上了一個(gè)有效無(wú)線路由,具體如上所述
        if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
            Parcelable parcelableExtra = intent
                    .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
            if (null != parcelableExtra) {
                NetworkInfo networkInfo = (NetworkInfo) parcelableExtra;
                State state = networkInfo.getState();
                // 當(dāng)然,這邊可以更精確的確定狀態(tài)
                boolean isConnected = state == State.CONNECTED;
                Log.e(TAG1, "isConnected" + isConnected);
                if (isConnected) {
                    APP.getInstance().setWifi(true);
                } else {
                    APP.getInstance().setWifi(false);
                }
            }
        }
    }
}

ConnectivityManager.CONNECTIVITY_ACTION

這個(gè)監(jiān)聽網(wǎng)絡(luò)連接的設(shè)置,包括wifi和移動(dòng)數(shù)據(jù)的打開和關(guān)閉;

此監(jiān)聽的作用范圍最大!不論wifi的打開、關(guān)閉,或是連接上可用的鏈接都會(huì)接到監(jiān)聽;當(dāng)然有利必有弊,那就是因?yàn)榉秶珡V,所以效率相比上方的倆個(gè)監(jiān)聽要慢一些!

如果上方的倆個(gè)監(jiān)聽需求可用滿足我們的業(yè)務(wù)需求,那么可以優(yōu)先適用上方倆種監(jiān)聽方式搭配使用;但個(gè)人建議如果業(yè)務(wù)需求上面?zhèn)z個(gè)監(jiān)聽滿足不了的話,還是可以采用懶人方式直接用此監(jiān)聽!

Of Course :這里所謂的示例代碼,就是最早看到的動(dòng)態(tài)監(jiān)聽的實(shí)現(xiàn)部分了!

監(jiān)聽常用

此處主要借鑒與此

  • 獲取ConnectivityManager對(duì)象

    java

    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context
    .CONNECTIVITY_SERVICE);

  • 獲取 NetworkInfo對(duì)象

    java

    //但是這個(gè)方法已經(jīng)過(guò)時(shí),官網(wǎng)的解釋如下:This method was deprecated in API level 23. This method does not support multiple connected networks of the same type. Use getAllNetworks() and
    getNetworkInfo(int networkType)
    getNetworkInfo(android.net.Network) instead.
    getNetworkInfo(Network network)
    getActiveNetwork()
    Returns a Network object corresponding to the currently active default data network.
    getActiveNetworkInfo(),Returns details about the currently active default data network.
    //這個(gè)方法已經(jīng)過(guò)時(shí),Use getAllNetworks() and getNetworkInfo(android.net.Network) instead.
    getAllNetworkInfo()

  • 綜上所述,我們?nèi)绻喇?dāng)前Mobile網(wǎng)絡(luò)或者WiFi網(wǎng)絡(luò)是否已經(jīng)連接上,總共有兩種方法

方法一:API23時(shí)已過(guò)時(shí)

?

java

	//猜測(cè):APP.getInstance()應(yīng)該是一個(gè)關(guān)于網(wǎng)絡(luò)相關(guān)的單例模式,主要用于app其他地方使用
    void getNetwork(Context context){
        State wifiState = null;
        State mobileState = null;

        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context
                .CONNECTIVITY_SERVICE);
        wifiState = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
        mobileState = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();

        Log.d(TAG1,"wifi狀態(tài):" + wifiState + "\n mobile狀態(tài):" + mobileState);

        // 手機(jī)網(wǎng)絡(luò)連接成功
        if (wifiState != null && mobileState != null
                && State.CONNECTED != wifiState
                && State.CONNECTED == mobileState) {
            Log.d("tag", "手機(jī)2g/3g/4g網(wǎng)絡(luò)連接成功");

            APP.getInstance().setMobile(true);
            APP.getInstance().setWifi(false);
            APP.getInstance().setConnected(true);
        }
        // 無(wú)線網(wǎng)絡(luò)連接成功
        else if (wifiState != null && State.CONNECTED == wifiState) {
            Log.d("tag", "無(wú)線網(wǎng)絡(luò)連接成功");

            APP.getInstance().setMobile(false);
            APP.getInstance().setWifi(true);
            APP.getInstance().setConnected(true);

        }
        // 手機(jī)沒(méi)有任何的網(wǎng)絡(luò)
        else if (wifiState != null && mobileState != null
                && State.CONNECTED != wifiState
                && State.CONNECTED != mobileState) {
            Log.d("tag", "手機(jī)沒(méi)有任何的網(wǎng)絡(luò)");

            APP.getInstance().setMobile(false);
            APP.getInstance().setWifi(false);
            APP.getInstance().setConnected(false);
        }
    }

方法二:此處和我在上方的網(wǎng)絡(luò)實(shí)時(shí)監(jiān)聽大致相同

?

java

	//猜測(cè):APP.getInstance()應(yīng)該是一個(gè)關(guān)于網(wǎng)絡(luò)相關(guān)的單例模式,主要用于app其他地方使用
    void getNetwork(Context context) {
        ConnectivityManager manager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        Log.i("tag", "CONNECTIVITY_ACTION");

        NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
        // connected to the internet
        if (activeNetwork != null) {
            if (activeNetwork.isConnected()) {
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    // connected to wifi
                    APP.getInstance().setWifi(true);
                    Log.e("tag", "當(dāng)前WiFi連接可用 ");
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    // connected to the mobile provider's data plan
                    APP.getInstance().setMobile(true);
                    Log.e("tag", "當(dāng)前移動(dòng)網(wǎng)絡(luò)連接可用 ");
                }
            } else {
                Log.e("tag", "當(dāng)前沒(méi)有網(wǎng)絡(luò)連接,請(qǐng)確保你已經(jīng)打開網(wǎng)絡(luò) ");
            }
        } // not connected to the internet
        else {
            Log.e("tag", "當(dāng)前沒(méi)有網(wǎng)絡(luò)連接,請(qǐng)確保你已經(jīng)打開網(wǎng)絡(luò) ");
            APP.getInstance().setWifi(false);
            APP.getInstance().setMobile(false);
            APP.getInstance().setConnected(false);
        }
    }

閑來(lái)無(wú)事正好看到了屏幕打開/關(guān)閉的的監(jiān)聽廣播,特此記錄一番

?

java

package nk.com.networklinstener;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * @author MrLiu
 * @date 2020/5/12
 * desc 此時(shí)APP可以后臺(tái)運(yùn)行,廣播依然有效,但是如果被殺死則無(wú)法收到廣播。
 *
 */
public class ScreenReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        switch (intent.getAction()) {
            case Intent.ACTION_SCREEN_OFF:
                Log.e("屏幕廣播","屏幕被關(guān)閉");
                break;
            case Intent.ACTION_SCREEN_ON:
                Log.e("屏幕廣播","屏幕被打開");
                break;
        }
    }
}

ConnectivityManager監(jiān)聽網(wǎng)絡(luò)更改

ConnectivityManager API 提供一個(gè)更強(qiáng)大的方法,用于僅在滿足指定的網(wǎng)絡(luò)條件時(shí)請(qǐng)求回調(diào)。首先我們獲取到系統(tǒng)的
ConnectivityManager 服務(wù), 并且使用 registerNetworkCallbackNetworkRequest
對(duì)象傳遞給系統(tǒng),最終系統(tǒng)會(huì)通過(guò) ConnectivityManager.NetworkCallback 回調(diào),將網(wǎng)絡(luò)變更情況告知給應(yīng)用。

?

java

//獲取ConnectivityManager 
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
//定義ConnectivityManager.NetworkCallback回調(diào)方法
callback = new ConnectivityManager.NetworkCallback() {
    // 可用網(wǎng)絡(luò)接入
    public void onCapabilitiesChanged(@NotNull Network network, @NotNull NetworkCapabilities networkCapabilities) {
        super.onCapabilitiesChanged(network, networkCapabilities);
        LogUtils.d("onCapabilitiesChanged");
        checkNetworkCapabilities(networkCapabilities);
    }

    @Override
    public void onLost(@NonNull Network network) {
        super.onLost(network);
        if (cm != null) {
            Network activeNetwork = cm.getActiveNetwork();
            if (activeNetwork == null) {
                //連接不到可用網(wǎng)絡(luò)
                return;
            }
            NetworkCapabilities networkCapabilities = cm.getNetworkCapabilities(activeNetwork);
            checkNetworkCapabilities(networkCapabilities);
        }
    }
};
NetworkRequest.Builder builder = new NetworkRequest.Builder();
if (cm != null) {
    cm.registerNetworkCallback(builder.build(), callback);
}

//判斷當(dāng)前網(wǎng)絡(luò)連接情況
private void checkNetworkCapabilities(NetworkCapabilities networkCapabilities) {
    if (networkCapabilities == null) {
        return;
    }
    // 表明網(wǎng)絡(luò)連接成功
    if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
                networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE)) {
            // 使用WI-FI
            LogUtils.d("WIFI network");
        } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
            // 使用蜂窩網(wǎng)絡(luò)
            LogUtils.d("mobile network");
        } else {
            // 未知網(wǎng)絡(luò),包括藍(lán)牙、VPN、LoWPAN
            LogUtils.d("unknown network");
        }
    } else {
        //網(wǎng)絡(luò)連接失敗
    }
}

到了這里,關(guān)于Android 監(jiān)聽網(wǎng)絡(luò)狀態(tài)變化的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Android 如何優(yōu)雅地監(jiān)聽SystemProperties屬性值變化

    我司項(xiàng)目中會(huì)頻繁用到persist.sys.xxx的屬性值,系統(tǒng)中預(yù)埋接口,通過(guò)屬性值控制,以應(yīng)對(duì)客戶多樣化的需求定制。 以往都是先設(shè)置屬性值,再重啟設(shè)備使能生效,抽空研究一下實(shí)時(shí)監(jiān)聽屬性值變化,最后在csdn上查到監(jiān)聽SystemProperties變化 這篇文章。 博主的實(shí)現(xiàn)方法給了我很

    2024年02月05日
    瀏覽(31)
  • Android 藍(lán)牙狀態(tài)的監(jiān)聽

    客戶在使用我公司的Flutter插件時(shí),要求有一個(gè)藍(lán)牙與設(shè)備重連的功能,我用公司提供的Android SDK只能實(shí)現(xiàn)超出和進(jìn)入藍(lán)牙范圍進(jìn)行重連,但是無(wú)法在藍(lán)牙打開進(jìn)行重連,這不得不讓我使用Android手寫一個(gè)廣播監(jiān)聽。 1. 添加權(quán)限 2. 創(chuàng)建一個(gè)類繼承 BroadcastReceiver 3. 動(dòng)態(tài)注冊(cè)和注銷

    2024年02月10日
    瀏覽(26)
  • Android監(jiān)測(cè)手機(jī)網(wǎng)絡(luò)狀態(tài)變化的廣播

    Android監(jiān)測(cè)手機(jī)網(wǎng)絡(luò)狀態(tài)變化的廣播

    @Override public void onReceive(Context context, Intent intent) { int netWorkStates = NetworkUtil.getNetWorkStates(context); switch (netWorkStates) { case NetworkUtil.TYPE_NONE: //斷網(wǎng)了 break; case NetworkUtil.TYPE_MOBILE: //打開了移動(dòng)網(wǎng)絡(luò) break; case NetworkUtil.TYPE_WIFI: //打開了WIFI break; default: break; } } } 上述代碼中使用到了Ne

    2024年04月12日
    瀏覽(20)
  • vue3 實(shí)現(xiàn)監(jiān)聽store里state狀態(tài)變化

    需要注意: 不能直接監(jiān)聽對(duì)象的屬性值,需要寫成getter函數(shù)。 總結(jié): watch 的第一個(gè)參數(shù)可以是不同形式的數(shù)據(jù)源,它可以是一個(gè)ref(包括計(jì)算屬性),一個(gè)響應(yīng)式對(duì)象,一個(gè)getter函數(shù),或多個(gè)數(shù)據(jù)源組成的數(shù)組。 不能直接監(jiān)聽響應(yīng)式對(duì)象的屬性: 這里需要寫成返回對(duì)象屬

    2024年02月17日
    瀏覽(19)
  • 【微信小程序】通過(guò)監(jiān)聽 WebSocket 的狀態(tài)變化來(lái)判斷Socket是否已經(jīng)建立連接

    在微信小程序中,可以通過(guò)監(jiān)聽 WebSocket 的狀態(tài)變化來(lái)判斷是否已經(jīng)建立連接。具體的操作步驟如下: 創(chuàng)建 WebSocket 對(duì)象并進(jìn)行連接: 監(jiān)聽 WebSocket 的狀態(tài)變化: 通過(guò)監(jiān)聽上述的狀態(tài)變化,可以判斷 WebSocket 是否已經(jīng)建立連接。當(dāng)連接成功時(shí), onSocketOpen 會(huì)被觸發(fā);連接失敗時(shí)

    2024年02月07日
    瀏覽(26)
  • Android 網(wǎng)絡(luò)狀態(tài)判斷

    1、獲取網(wǎng)絡(luò)信息,首先需要獲取權(quán)限 2.1我們通過(guò)ConnectivityManager可以獲取狀態(tài),但是我們需要考慮到Android版本不同獲取方式不同。 2.1.1hasCapability可以判斷網(wǎng)絡(luò)是否連接,常用參數(shù)如下: ?NetworkCapabilities.NET_CAPABILITY_INTERNET:判斷是否連上網(wǎng) NetworkCapabilities.NET_CAPABILITY_VALIDATED: 判

    2024年03月13日
    瀏覽(18)
  • Android設(shè)置app開機(jī)自啟,網(wǎng)絡(luò)監(jiān)聽,主線程完成UI渲染,HTTP網(wǎng)絡(luò)請(qǐng)求工具,json數(shù)據(jù)處理,android使用sqlite,Android定時(shí)任務(wù),日志打印

    在AndroidManifest.xml文件中添加權(quán)限 在AndroidManifest.xml文件中注冊(cè)接收廣播配置, 添加到manifest application節(jié)點(diǎn)下 在AndroidManifest.xml文件中添加節(jié)點(diǎn)屬性, 指定安裝目錄為內(nèi)部存儲(chǔ)器, 而非SD卡 開機(jī)啟動(dòng)執(zhí)行代碼 gson是谷歌… implementation ‘gson-2.8.5’ 依賴無(wú)法下載, 直接使用jar包, 將ja

    2024年02月03日
    瀏覽(22)
  • Android 獲取網(wǎng)絡(luò)連接狀態(tài)新方法

    Android 獲取網(wǎng)絡(luò)連接狀態(tài)新方法

    ????????Android12上,有的app模塊判斷當(dāng)前網(wǎng)絡(luò)的類型和連接狀態(tài)時(shí),還是使用的舊的API,導(dǎo)致返回的結(jié)果不準(zhǔn)確,影響代碼邏輯判斷,本篇文章就這一問(wèn)題,整理一下判斷網(wǎng)絡(luò)類型和連接狀態(tài)的新方法。 ????????在Android 10以前的版本,大家都是通過(guò)NetworkInfo.java 的get

    2024年02月08日
    瀏覽(21)
  • uniapp 安卓端實(shí)時(shí)監(jiān)聽網(wǎng)絡(luò)狀態(tài)

    寫在uniapp的APP.vue的onShow方法中 uni.onNetworkStatusChange(function(res) { ?? ??? ??? ??? ?if (res.isConnected) { ?? ??? ??? ??? ??? ?uni.showModal({ ?? ??? ??? ??? ??? ??? ?title: \\\'系統(tǒng)提示\\\', ?? ??? ??? ??? ??? ??? ?content: \\\'當(dāng)前設(shè)備網(wǎng)絡(luò)已恢復(fù)\\\', ?? ??? ??? ??? ??

    2024年02月05日
    瀏覽(20)
  • Android 14 媒體權(quán)限變化

    允許部分訪問(wèn)照片和視頻 在Android 14設(shè)備上與您的應(yīng)用程序交互的用戶現(xiàn)在可以在應(yīng)用程序請(qǐng)求Android 13(API級(jí)別33)中引入的任何視覺(jué)媒體權(quán)限(READ_media_IMAGES或READ_media-VIDEO)時(shí)授予對(duì)其視覺(jué)媒體庫(kù)(照片/視頻)的部分訪問(wèn)權(quán)限。 新對(duì)話框包含以下選項(xiàng): 選擇照片和視頻:

    2024年02月05日
    瀏覽(22)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包