当WIFI打开时通过移动数据发送请求。(Android L)

37

SDK: Android 5.0.1.

Android build: LRX22C.

Device: Nexus 5.

Problem: KITKAT(4.4.4)及以下API。

1)startUsingNetworkFeature(int networkType,String feature)此方法已弃用。 改用更清晰的requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)

2)requestRouteToHost(int networkType,int hostAddress)此方法已弃用。 现在改用requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)setProcessDefaultNetwork(Network)getSocketFactory()

当WIFI和移动数据同时使用时,这些方法用于通过移动数据网络发送请求。

从Android L开始,这些API已过时且不再有效。

新的API/类包括:NetworkRequest.BuilderNetworkRequestConnectivityManager.NetworkCallbackrequestNetworkregisterNetworkCallback有关API使用的详细信息,请单击此处
Android L API's

代码:

ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkRequest.Builder builder = new NetworkRequest.Builder();

builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);

NetworkRequest networkRequest = builder.build();
connectivityManager.requestNetwork(networkRequest, networkCallback);
connectivityManager.registerNetworkCallback(networkRequest, networkCallback);

工作场景:

仅在onAvailable回调中接收到移动数据。

不工作的场景: 移动数据和Wifi都打开且已连接,但未从系统接收到onAvailable回调。因此无法设置setProcessDefaultNetwork, ConnectivityManager.setProcessDefaultNetwork(preferedNetwork);

频繁:始终如此

期望输出:当wifi打开时,获取移动网络可用回调。

我是否漏掉了什么或者固件存在某些问题?

ADB日志:

09-18 18:50:42.617: I/art(1339): Heap transition to ProcessStateJankImperceptible took 64.332086ms saved at least 225KB
09-18 18:50:43.060: I/auditd(16947): type=1400 audit(0.0:899): avc:  denied  { getattr } for  comm="ls" path="/persist" dev="mmcblk0p16" ino=2 scontext=u:r:shell:s0 tcontext=u:object_r:persist_file:s0 tclass=dir
09-18 18:50:43.422: I/ActivityManager(769): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.example.networktest/.MainActivity (has extras)} from pid 1149 on display 0
09-18 18:50:43.423: I/am_create_task(769): [0,20]
09-18 18:50:43.423: I/am_create_activity(769): [0,145055245,20,com.example.networktest/.MainActivity,android.intent.action.MAIN,NULL,NULL,270532608]
09-18 18:50:43.424: I/wm_task_created(769): [20,1]
09-18 18:50:43.424: I/wm_task_moved(769): [20,1,2]
09-18 18:50:43.424: I/am_pause_activity(769): [0,613529891,com.google.android.googlequicksearchbox/com.google.android.launcher.GEL]
09-18 18:50:43.442: I/am_destroy_service(769): [0,453570950,2161]
09-18 18:50:43.444: D/audio_hw_primary(200): select_devices: out_snd_device(2: speaker) in_snd_device(0: )
09-18 18:50:43.447: I/am_on_paused_called(1149): [0,com.google.android.launcher.GEL]
09-18 18:50:43.492: I/am_proc_start(769): [0,16964,10091,com.example.networktest,activity,com.example.networktest/.MainActivity]
09-18 18:50:43.492: I/ActivityManager(769): Start proc com.example.networktest for activity com.example.networktest/.MainActivity: pid=16964 uid=10091 gids={50091, 3003}
09-18 18:50:43.497: I/am_create_service(769): [0,565414612,.LightweightIndexService,10009,1339]
09-18 18:50:43.501: I/art(16964): Late-enabling -Xcheck:jni
09-18 18:50:43.522: I/am_proc_bound(769): [0,16964,com.example.networktest]
09-18 18:50:43.524: I/am_restart_activity(769): [0,145055245,20,com.example.networktest/.MainActivity]
09-18 18:50:43.526: I/art(16964): Profiler disabled.  To enable setprop dalvik.vm.profiler 1
09-18 18:50:43.533: I/am_create_service(769): [0,28763261,.LightweightIndexService$LightweightWorkerService,10009,1339]
09-18 18:50:43.536: I/am_destroy_service(769): [0,28763261,1339]
09-18 18:50:43.575: D/ConnectivityService(769): requestNetwork for NetworkRequest [ id=18, legacyType=-1, [ Transports: CELLULAR Capabilities: NOT_RESTRICTED] ]
09-18 18:50:43.575: D/ConnectivityService(769): handleRegisterNetworkRequest checking NetworkAgentInfo [WIFI ()]
09-18 18:50:43.575: D/ConnectivityService(769): sending new NetworkRequest to factories
09-18 18:50:43.575: D/WIFI(769): got request NetworkRequest [ id=18, legacyType=-1, [ Transports: CELLULAR Capabilities: NOT_RESTRICTED] ] with score 0
09-18 18:50:43.575: D/WIFI(769):   my score=60, my filter=[ Transports: WIFI Capabilities: INTERNET&NOT_RESTRICTED LinkUpBandwidth>=1048576Kbps LinkDnBandwidth>=1048576Kbps]
09-18 18:50:43.575: D/Ethernet(769): got request NetworkRequest [ id=18, legacyType=-1, [ Transports: CELLULAR Capabilities: NOT_RESTRICTED] ] with score 0
09-18 18:50:43.575: D/Ethernet(769):   my score=-1, my filter=[ Transports: ETHERNET Capabilities: INTERNET&NOT_RESTRICTED LinkUpBandwidth>=100000Kbps LinkDnBandwidth>=100000Kbps]
09-18 18:50:43.575: D/TelephonyNetworkFactory(1113): got request NetworkRequest [ id=18, legacyType=-1, [ Transports: CELLULAR Capabilities: NOT_RESTRICTED] ] with score 0
09-18 18:50:43.575: D/TelephonyNetworkFactory(1113):   my score=50, my filter=[ Transports: CELLULAR Capabilities: MMS&SUPL&DUN&FOTA&IMS&CBS&IA&RCS&XCAP&EIMS&INTERNET&NOT_RESTRICTED]
09-18 18:50:43.576: D/TelephonyNetworkFactory(1113): Cellular needs Network for NetworkRequest [ id=18, legacyType=-1, [ Transports: CELLULAR Capabilities: NOT_RESTRICTED] ]
09-18 18:50:43.576: D/ConnectivityService(769): listenForNetwork for NetworkRequest [ id=19, legacyType=-1, [ Transports: CELLULAR Capabilities: NOT_RESTRICTED] ]
09-18 18:50:43.577: D/ConnectivityService(769): handleRegisterNetworkRequest checking NetworkAgentInfo [WIFI ()]
09-18 18:50:43.841: I/am_create_service(769): [0,510459843,.EventLoggerService,10022,2161]
09-18 18:50:43.855: I/am_create_service(769): [0,271933548,.GetToken,10009,1339]
09-18 18:50:43.899: I/am_create_service(769): [0,609002555,.GoogleAccountDataService,10009,1339]
09-18 18:50:43.902: W/GLSUser(1339): GoogleAccountDataService.getToken()
09-18 18:50:43.910: I/am_destroy_service(769): [0,609002555,1339]
09-18 18:50:43.914: I/am_destroy_service(769): [0,271933548,1339]
09-18 18:50:43.996: I/sf_frame_dur(197): [com.google.android.googlequicksearchbox/com.google.android.launcher.GEL,89,0,2,0,1,2,1]
09-18 18:50:44.299: I/am_destroy_service(769): [0,510459843,2161]
09-18 18:50:44.760: I/art(16309): Heap transition to ProcessStateJankImperceptible took 6.712188ms saved at least 830KB
09-18 18:50:48.070: I/auditd(17031): type=1400 audit(0.0:900): avc:  denied  { getattr } for  comm="ls" path="/persist" dev="mmcblk0p16" ino=2 scontext=u:r:shell:s0 tcontext=u:object_r:persist_file:s0 tclass=dir
09-18 18:50:48.579: I/am_on_resume_called(16964): [0,com.example.networktest.MainActivity]
09-18 18:50:48.587: D/CanvasContext(16964): Render dirty regions requested: true
09-18 18:50:48.592: I/am_destroy_service(769): [0,565414612,1339]
09-18 18:50:48.597: I/art(2161): Heap transition to ProcessStateJankImperceptible took 109.715785ms saved at least 2MB
09-18 18:50:48.626: W/Adreno-GSL(16964): <ioctl_kgsl_device_getproperty:663>: mmap failed: errno 22 Invalid argument
09-18 18:50:48.626: I/Adreno-EGL(16964): <qeglDrvAPI_eglInitialize:320>: EGL 1.4 QUALCOMM Build: I10246dbd022c719c705be805d5642cc8fdfbd2a2Date: 03/07/14
09-18 18:50:48.626: I/CanvasContext(16964): Initialized EGL, version 1.4
09-18 18:50:48.644: I/art(1149): Heap transition to ProcessStateJankImperceptible took 75.768178ms saved at least 2MB
09-18 18:50:48.644: D/OpenGLRenderer(16964): Enabling debug mode 0
09-18 18:50:48.650: I/art(1252): Heap transition to ProcessStateJankImperceptible took 92.615158ms saved at least 384KB
09-18 18:50:48.688: I/am_activity_launch_time(769): [0,145055245,com.example.networktest/.MainActivity,5230,5230]
09-18 18:50:48.688: I/ActivityManager(769): Displayed com.example.networktest/.MainActivity: +5s230ms
09-18 18:50:48.904: I/sf_frame_dur(197): [Starting com.example.networktest,1,0,0,0,0,0,0]

编辑:Google提出了错误1Google提出了错误2“没有为此更改输入评论”的含义是什么?

谢谢,Nithin


2
不行,直到KitKat都没有必要这样做。Android L引入了新的API,并清晰地表示:“您可以从回调中使用android.net.Network对象来获取有关网络的其他信息,或将流量定向到使用所选网络。” - NitZRobotKoder
1
@BVB https://developer.android.com/preview/api-overview.html#Wireless - NitZRobotKoder
2
@NitZRobotKoder 哇 :) - LOG_TAG
1
如果更改问题(例如:优先级更改,所有者更改,状态更改),但未留下评论,则会看到“未输入有关此更改的评论”。 - David Wasser
2
如果用户连接到没有互联网连接的WiFi设备(如打印机),并且需要使用3G来访问互联网,这也是很重要的。 - EionRobb
显示剩余18条评论
2个回答

21

好的,最终找到了解决方案。关键是使用 NET_CAPABILITY_INTERNET 作为能力。这与 startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, FEATURE_ENABLE_HIPRI) 相同。

在这里查看固件设计

builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);

在此之后,我能够从系统得到onAvailable回调,然后将我的进程默认网络设置为移动数据。

因此,即使wifi打开,所有请求也都通过移动数据进行。哇!

注意:这在Preview L的初始版本中不起作用。

编辑于19-10-2015:setProcessDefaultNetwork现已过时,请使用bindProcessToNetwork


1
你如何在传输数据完成后回滚到默认模式?@NitZRobotKoder - lyc001
2
@lyc001 我的回答本身已经过时了..请参考setProcessDefaultNetwork方法http://developer.android.com/reference/android/net/ConnectivityManager.html#bindProcessToNetwork(android.net.Network)我如何回滚是使用以下方法。 ConnectivityManager.setProcessDefaultNetwork(null); 或者 releaseNetworkRequest http://developer.android.com/reference/android/net/ConnectivityManager.html#releaseNetworkRequest(android.app.PendingIntent) - NitZRobotKoder
我的移动数据完成后如何释放偏好设置?是否有重置的方法? - Vinoth K

2
以下是一段函数,可以简化您的应用程序对特定类型网络的偏好操作(在编写本文时适用于任何当前的API级别(26)):

private void alwaysPreferNetworksWith(@NonNull int[] capabilities, @NonNull int[] transportTypes) {

    NetworkRequest.Builder request = new NetworkRequest.Builder();

    // add capabilities
    for (int cap: capabilities) {
        request.addCapability(cap);
    }

    // add transport types
    for (int trans: transportTypes) {
        request.addTransportType(trans);
    }

    final ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(CONNECTIVITY_SERVICE);

    connectivityManager.registerNetworkCallback(request.build(), new ConnectivityManager.NetworkCallback() {
        @Override
        public void onAvailable(Network network) {
            try {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                    ConnectivityManager.setProcessDefaultNetwork(network);
                } else {
                    connectivityManager.bindProcessToNetwork(network);
                }
            } catch (IllegalStateException e) {
                Log.e(TAG, "ConnectivityManager.NetworkCallback.onAvailable: ", e);
            }
        }
    });
}

用法:

// Add any NetworkCapabilities.NET_CAPABILITY_...
int[] capabilities = new int[]{ NetworkCapabilities.NET_CAPABILITY_INTERNET };

// Add any NetworkCapabilities.TRANSPORT_...
int[] transportTypes = new int[]{ NetworkCapabilities.TRANSPORT_CELLULAR };

alwaysPreferNetworksWith(capabilities, transportTypes);

完成移动数据的工作后如何释放偏好设置?有重置的方法吗? - Vinoth K
1
@VinothK 使用“connectivitymanager.releaseNetworkRequest”方法来释放首选项。 - Amol Desai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接