2

我正在开发一个 SMS 应用程序并想检查网络(蜂窝)连接。对于 API 级别 29,检查连接需要使用ConnectivityManager.NetworkCallback. 我所管理的是让“onAvailable()”在网络可用时通知我。但是,如果它连接到 WiFi,这也会通知我(所以我可能没有发送 SMS 的服务,但如果 WiFi 连接,则 onAvailable() 将触发)。

我试过了onCapabilitiesChanged().hasTransport(TRANSPORT_CELLULAR)但如果我连接到 WiFi,就会报告错误。

我也想过尝试hasCapability(NET_CAPABILITY_MMS),但这会告知是否可以使用彩信。我不清楚是否存在可以使用短信但不能使用彩信的场景/网络?那么我可以得到这个报告false,因为网络不支持彩信但仍然可以发送短信吗?

检查蜂窝网络是否可用的正确方法是什么?

4

4 回答 4

2

也许你可以尝试以下

Network activeNetwork = connectivityManager.getActiveNetwork();
NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(activeNetwork);
boolean cellular = caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);

if(cellular){
   // do your stuff
}

于 2019-07-24T11:48:26.633 回答
1

迟到了,我不确定 29 岁……我想这很蹩脚……但这就是我的做法:

public boolean isCellularAvailable()
{
    TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    String opetarorName = telephonyManager.getNetworkOperatorName();

    Log.i(LOG_TAG, "#### isCellularAvailable(): NetworkOperatorName is: " + opetarorName );

    if (opetarorName .compareTo("") == 0)
    {
        Log.i(LOG_TAG, "#### isCellularAvailable(): NOPE");
        Toast.makeText(context, "Turn off airplane mode and try again :)", Toast.LENGTH_LONG).show();
        return false;
    }
    else
    {
        Log.i(LOG_TAG, "#### isCellularAvailable(): YES!");
        return true;
    }
}

这里的想法是,如果您连接到蜂窝网络,您应该能够获得网络提供商的名称。

如果你得到一个名字,那么你已经连接到那个网络,并且应该能够使用它。

例如,如果您处于飞行模式,您将无法连接到网络,也不会获得名称。

注意到文档说“结果在 CDMA 网络上可能不可靠”……不管这意味着什么。

但是“telephonyManager”提供了一些类似的功能,例如“getNetworkType()”可能是另一种方法,如果你知道你喜欢网络类型:

public boolean isCellularAvailable()
{
    TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    int networkType = telephonyManager.getNetworkType();// .getNetworkOperatorName();

    Log.i(LOG_TAG, "#### isCellularAvailable(): Network type is: " + networkType);

    switch (networkType)
    {
        // Return true for networks that suits your purpose
        case TelephonyManager.NETWORK_TYPE_1xRTT:    return true;
        case TelephonyManager.NETWORK_TYPE_CDMA:     return true;
        case TelephonyManager.NETWORK_TYPE_EDGE:     return true;
        case TelephonyManager.NETWORK_TYPE_EHRPD:    return true;
        case TelephonyManager.NETWORK_TYPE_EVDO_0:   return true;
        case TelephonyManager.NETWORK_TYPE_EVDO_A:   return true;
        case TelephonyManager.NETWORK_TYPE_EVDO_B:   return true;
        case TelephonyManager.NETWORK_TYPE_GPRS:     return true;
        case TelephonyManager.NETWORK_TYPE_GSM:      return true;
        case TelephonyManager.NETWORK_TYPE_HSDPA:    return true;
        case TelephonyManager.NETWORK_TYPE_HSPA:     return true;
        case TelephonyManager.NETWORK_TYPE_HSPAP:    return true;
        case TelephonyManager.NETWORK_TYPE_HSUPA:    return true;
        case TelephonyManager.NETWORK_TYPE_IDEN:     return true;
        case TelephonyManager.NETWORK_TYPE_IWLAN:    return true;
        case TelephonyManager.NETWORK_TYPE_LTE:      return true;
        //case TelephonyManager.NETWORK_TYPE_NR:     return true;       // Not supported by my API
        case TelephonyManager.NETWORK_TYPE_TD_SCDMA: return true;
        case TelephonyManager.NETWORK_TYPE_UMTS:     return true;

        // Return false for unacceptable networks, UNKNOWN id no network e.g. airplane mode.
        case TelephonyManager.NETWORK_TYPE_UNKNOWN: return false;

        // Future unknown network types, handle as you please.
        default: return false;
    }
于 2019-12-05T21:24:59.053 回答
0

您需要使用网络回调。

try {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkRequest.Builder builder = new NetworkRequest.Builder();

    connectivityManager.registerNetworkCallback(builder.build(),new ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(Network network) {
                    Variables.isNetworkConnected = true; // Global Static Variable
                }
                @Override
                public void onLost(Network network) {
                    Variables.isNetworkConnected = false; // Global Static Variable
                }
            }

    );
    Variables.isNetworkConnected = false;
}catch (Exception e){
    Variables.isNetworkConnected = false;
}

Variables.isNetworkConnected - 这里我使用了一个全局静态变量,所以我可以使用它来访问任何应用程序中的网络状态。

请参阅此要点以获取完整的代码实现。

于 2019-11-23T08:16:44.003 回答
0

尝试使用以下代码检查设备是否连接到互联网。

    ConnectivityManager conMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = conMgr.getActiveNetworkInfo();
    if (netInfo == null) {

        Toast.makeText(this, "Please turn on Internet ", Toast.LENGTH_SHORT).show();

    } else {
        //do what you want
    }
于 2019-07-24T12:57:17.963 回答