首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android O预览:移除ConnectivityManager的方法不向后兼容

Android O预览:移除ConnectivityManager的方法不向后兼容
EN

Stack Overflow用户
提问于 2017-04-12 17:20:44
回答 5查看 2.6K关注 0票数 8

前提条件和构建配置:我正在尝试通过设置下面的AndroidStudio O perview设备的构建配置参数,compileSdkVersion ' Android -O‘buildToolsVersion '25.0.0’compileOptions.encoding = 'ISO-8859-1‘minSdkVersion 16 targetSdkVersion 'O’//启用多索引支持,使用android 2.4版本5构建我的应用。multiDexEnabled true

问题描述:我的应用程序在使用旧版安卓系统的设备上使用以下这些ConnectivityManager类的弃用方法。-ConnectivityManager.startUsingNetworkFeature() - ConnectivityManager.stopUsingNetworkFeature() - ConnectivityManager.requestRouteToHost()

当我尝试构建具有上述api的应用程序时,它给出了如下编译时错误,

错误:(626,48)错误:找不到符号方法startUsingNetworkFeature(int,String)错误:(7393,27)错误:找不到符号方法stopUsingNetworkFeature(int,String)错误:(69,36)错误:找不到符号方法requestRouteToHost(int,int)

理想情况下,出于向后兼容目的,这些api不应该给出编译时错误。请告诉我如何解决这些编译时错误。

我不能从代码中删除这些方法,因为它们是使用较旧android版本(低于Android L版本)的设备所必需的。

EN

回答 5

Stack Overflow用户

发布于 2017-10-17 20:11:35

在你的项目中创建一个新的android库模块。确保这个库有compileSdkVersion 25。然后将以下类放入库中:

代码语言:javascript
复制
@SuppressWarnings("Deprecation")
public class NetworkFeaturesCompat {
    public static NetworkFeaturesCompat from(final ConnectivityManager cm) {
        return new NetworkFeaturesCompat(cm);
    }

    private final ConnectivityManager mConnectivityManager;

    private NetworkFeaturesCompat(final ConnectivityManager cm) {
        mConnectivityManager = cm;
    }

    public int startUsingNetworkFeature(final int networkType, final String feature) {
        return mConnectivityManager.startUsingNetworkFeature(networkType, feature);
    }

    public int stopUsingNetworkFeature(final int networkType, final String feature) {
        return mConnectivityManager.stopUsingNetworkFeature(networkType, feature);
    }

    public boolean requestRouteToHost(final int networkType, final int hostAddress) {
        return mConnectivityManager.requestRouteToHost(networkType, hostAddress);
    }
}

现在,通过修改它的build.gradle文件,让你的主模块依赖于这个库:

代码语言:javascript
复制
dependencies {
    compile project(":your-new-library-module-name")
}

构建您的项目。

现在你可以从你的主项目中使用这个助手类了。

您可能需要将此添加到您的proguard规则中(我还没有实际测试过这一点):

代码语言:javascript
复制
-dontwarn android.net.ConnectivityManager

请注意,这种方法仍然会在Android 6+上抛出UnsupportedOperationException

为什么这是可行的?

原来的方法仍然存在于SDK中,它们只是对SDK 26中的公共API隐藏起来。这就是它在运行时不会崩溃的原因。

库模块是针对SDK 25编译的,其中方法仍然是公共API的一部分。这就是它在编译时不会崩溃的原因。

由于整个项目都是在SDK26上编译的,proguard可能会抱怨缺少方法。在这种情况下,忽略投诉就可以了。

票数 3
EN

Stack Overflow用户

发布于 2018-07-03 04:26:44

因为我不能对Antilope的答案添加注释,所以我将在这里更正它。

应该是method.invoke(connectivityManager, ConnectivityManager.TYPE_MOBILE, "enableHIPRI");

因此,通常代码看起来像这样:

代码语言:javascript
复制
try{
    java.lang.reflect.Method method = connectivityManager.getClass().getMethod("startUsingNetworkFeature",
    int.class, String.class); 
    resultInt = (int) method.invoke(connectivityManager, ConnectivityManager.TYPE_MOBILE, 
"enableHIPRI");
} catch (Exception e) { 
    //Do something 
}

代码语言:javascript
复制
try{
    java.lang.reflect.Method method = connectivityManager.getClass().getMethod("requestRouteToHost", int.class, int.class);
    resultBool = (boolean) method.invoke(connectivityManager, ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);
} catch (Exception e) { 
    //Do something 
}

上面的代码适用于targetSDK 27

票数 3
EN

Stack Overflow用户

发布于 2018-05-29 21:45:56

正如这些bug报告线程(https://issuetracker.google.com/issues/64992660)所建议的那样,尽管反射可以在以API27为目标的情况下进行调用。在不同的设备上测试,甚至在配备Oreo的Galaxy Note8 (8.0.0)上也是如此。

我之前所说的:

代码语言:javascript
复制
resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");

现在可以这样调用:

代码语言:javascript
复制
try{
    java.lang.reflect.Method method = connectivityManager.getClass().getMethod("startUsingNetworkFeature",
    int.class, String.class); resultInt = (int) method.invoke(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");
} catch (Exception e) { 
    //Do something 
}

也适用于:

代码语言:javascript
复制
resultBool = connectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);

现在可以这样调用:

代码语言:javascript
复制
try{
    java.lang.reflect.Method method = connectivityManager.getClass().getMethod("requestRouteToHost", int.class, int.class);
    resultBool = (boolean) method.invoke(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);
} catch (Exception e) { 
    //Do something 
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43365391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档