8

Wi-Fi(デバイスで生成)経由でハードウェアデバイスに接続し、ソケット接続を介してデータを送信するアプリケーションを開発しています。 問題は、モバイルデータ(3G/4G)がアクティブになっているときに、アンドロイドがWi-Fiがインターネットに接続していないため、デバイスが生成したWi-Fiを介して送信するのではなく、アンドロイドがデータを送信しようとしていることです。 私はConnectivityManager#setNetworkPreference()を使用することを考えていましたが、API 21では廃止されました。モバイルデータを受信したときに無線LAN(インターネットなし)でデータを送信する

モバイルデータインターフェイスではなくデバイスで生成されたWi-Fiを使用してデータを送信するにはどうすればよいですか?

答えて

9

多くの研究とそれを理解しようとすると、これはAndroid 5.0(Lollipop)以前のバージョンでは不可能であることがわかりました。OSは一度に1つのネットワークインターフェイスを維持し、これを支配しないでください。それはあなただけしない場合にはアンドロイド以上がロリポップする場合は、あなたのソケット接続のチェックを行う前に

  1. 、:

    だからロリポップに以上のバージョンでこれを行うには、私は次のことをやりましたあなたが普通にやらなければならないことは何でも。

  2. バージョンは、あなたがこのような何かする必要はロリポップと同じかそれ以上である場合には:あなたはこれでプロセスを結合停止する必要が終了した後

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { 
        final ConnectivityManager manager = (ConnectivityManager) context 
          .getSystemService(Context.CONNECTIVITY_SERVICE); 
        NetworkRequest.Builder builder; 
        builder = new NetworkRequest.Builder(); 
        //set the transport type do WIFI 
        builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); 
        manager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() { 
         @Override 
         public void onAvailable(Network network) { 
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
           manager.bindProcessToNetwork(network); 
          } else { 
           //This method was deprecated in API level 23 
           ConnectivityManager.setProcessDefaultNetwork(network); 
          } 
          try { 
           //do a callback or something else to alert your code that it's ok to send the message through socket now 
          } catch (Exception e) { 
           e.printStackTrace(); 
          } 
          manager.unregisterNetworkCallback(this); 
         } 
        }); 
    } 
    
  3. を:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
        ConnectivityManager manager = (ConnectivityManager) InovePlugApplication.getContext() 
          .getSystemService(Context.CONNECTIVITY_SERVICE); 
        manager.bindProcessToNetwork(null); 
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
        ConnectivityManager.setProcessDefaultNetwork(null); 
    } 
    

この回答は、私がそれを行う方法を理解していないのに役立ちましたhttps://stackoverflow.com/a/29837637/2550932

+0

これが機能するには、マニフェストに ''が必要です。 – AppleGrew

+0

@hygorxaraujo私はあなたのコードを使用していますが、これはandroid nougatでは動作しません。私はMarshamallow以上のためにmanager.bindProcessToNetwork(ネットワーク)をやっています。回避策はありますか? –

+0

@ satpal002申し訳ありませんが、私はAndroid Marshmallowまでこのコードを使用しました(テストするためにNougatを搭載したデバイスはありません)。 https://developer.android.com/reference/android/net/ConnectivityManager.htmlの動作を停止するために、APIに変更が加えられていることに気付かなかった。以前のバージョン(Lollipopの上)で正常に動作していますか? – hygorxaraujo

0

setProcessDefaultNetworkをwifiにした後、ネットワークがモバイルに戻ると、この方法で大きなデータを送信することはできません。この方法で作成されたすべてのソケットが機能しなくなるためです。私は今、完璧な方法を見つけることができません、ここに参照用です。

あなたがrootアクセスを得ることができます1.If、前に無線LANに接続し、この操作を行います。

Process process = runtime.exec("su"); 
DataOutputStream dataOutputStream = new DataOutputStream(process.getOutputStream()); 
dataOutputStream.writeBytes("settings put global captive_portal_server 127.0.0.1\n"); 
dataOutputStream.writeBytes("exit\n"); 
dataOutputStream.flush(); 
int status = process.waitFor(); 

そして、あなたがデータ送信した後、それを削除します。

dataOutputStream.writeBytes("settings delete global captive_portal_server\n"); 

をあなたはWRITE_SECURE_SETTINGSの許可を得ることができます2.Ifは:

Settings.Global.putString(getContentResolver(),"captive_portal_server","127.0.0.1"); 

または:

+0

こんにちは@MADAO、あなたの答えをありがとう、私はあなたも正しいと思います。私はすでにこれに対する答えを見つけて、ここで質問を更新するのを忘れていました。 – hygorxaraujo

関連する問題