0

I'm working on an app that has to take udp packets form a local wifi netwotrk and send them to a server via 3g. I have a hardly working solution for Android 4.4. But for 5.0 and newer I cannot find a solution.

This is the solution for 4.4. It drops often, so it also needs fixing.

  public static boolean forceMobileConnectionForAddress(Context context, String address) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (null == connectivityManager) {
        Log.d(TAG_LOG, "ConnectivityManager is null, cannot try to force a mobile connection");
        return false;
    }

    //check if mobile connection is available and connected
    State state = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState();
    //Log.d(TAG_LOG, "TYPE_MOBILE_HIPRI network state: " + state);
    if (0 == state.compareTo(State.CONNECTED) || 0 == state.compareTo(State.CONNECTING)) {
        return true;
    }

    //activate mobile connection in addition to other connection already activated
    int resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableWIFI");
    //Log.d(TAG_LOG, "startUsingNetworkFeature for enableHIPRI result: " + resultInt);

    //-1 means errors
    // 0 means already enabled
    // 1 means enabled
    // other values can be returned, because this method is vendor specific
    if (-1 == resultInt) {
        Log.e(TAG_LOG, "Wrong result of startUsingNetworkFeature, maybe problems");
        return false;
    }
    if (0 == resultInt) {
        Log.d(TAG_LOG, "No need to perform additional network settings");
        return true;
    }

    //find the host name to route
    String hostName = extractAddressFromUrl(address);
    //Log.d(TAG_LOG, "Source address: " + address);
    //Log.d(TAG_LOG, "Destination host address to route: " + hostName);
    if (TextUtils.isEmpty(hostName)) hostName = address;

    //create a route for the specified address
    int hostAddress = lookupHost(hostName);
    if (-1 == hostAddress) {
        Log.e(TAG_LOG, "Wrong host address transformation, result was -1");
        return false;
    }
    //wait some time needed to connection manager for waking up
    try {
        for (int counter=0; counter<30; counter++) {
            State checkState = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState();
            if (0 == checkState.compareTo(State.CONNECTED))
                break;
            Thread.sleep(1000);
        }
    } catch (InterruptedException e) {
        //nothing to do
    }
    boolean resultBool = connectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);
    //Log.d(TAG_LOG, "requestRouteToHost result: " + resultBool);
    if (!resultBool)
        Log.e(TAG_LOG, "Wrong requestRouteToHost result: expected true, but was false");

    state = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState();
    //Log.d(TAG_LOG, "TYPE_MOBILE_HIPRI network state after routing: " + state);

    return resultBool;
}
Lyubomir Dinchev
  • 330
  • 3
  • 12

1 Answers1

0

Here is the code I've been using, which uses ConnectivityManager's requestNetwork() instead of startUsingNetworkFeature() and requestRouteToHost():

ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder req = new NetworkRequest.Builder();
req.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
req.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);

cm.requestNetwork(req.build(), new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(Network network) {
    network.openConnection(new URL(someUrlAddress));
    // do other stuff here
  }
});