Wi-fi ONかつMobile ON状態で
使用する通信回線を切り替えるアプリを作成しています。
Wi-fi→Mobile, もしくはMobile→Wi-fiの通信切り替えのリクエストをしているのですが
2回目のリクエストが反映されず困っております。
対象はSDKバージョン 28で、リクエストにはConectivityManagerクラスを使用しております。
現象は以下となります。
モバイル通信リクエスト後、アプリ内Webviewでサイト閲覧 | → | Wi-fi通信リクエスト後、アプリ内Webviewでサイト閲覧 | |
---|---|---|---|
モバイル通信量 | 通信量アップ(想定通り) | → | 通信量アップ(想定通りではない) |
Wi-fi 通信量 | 変化なし(想定通り) | → | 変化なし(想定通りではない) |
Wi-fi通信リクエスト後、アプリ内Webviewでサイト閲覧 | → | モバイル通信リクエスト後、アプリ内Webviewでサイト閲覧 | |
---|---|---|---|
モバイル通信量 | 変化なし(想定通り) | → | 変化なし(想定通りではない) |
Wi-fi 通信量 | 通信量アップ(想定通り) | → | 通信量アップ(想定通りではない) |
通信リクエスト時は、onAvailable()の通知が来た際にbindProcessNetwork(network)を行い、
通信回線をバインドしております。
https://developer.android.com/reference/android/net/ConnectivityManager
「ConnectivityManager」
registerNetworkCallback(NetworkRequest request, ConnectivityManager.NetworkCallback networkCallback)
bindProcessToNetwork(Network network)
現象としては、1回目のリクエスト時の何かが残っているのではないかと疑ったのですが
2回目のリクエスト時に以下の終了処理をしているため、1回目のリクエストは残っていないはず・・と思っております。
・unregisterNetworkCallback (networkCallback) ←コールバック登録の解除
・networkCallback = null; ←コールバックインスタンスをNull
AndroidはWi-fiとMobileが両方ONになっているときにWi-fiを優先するのは理解していますが
私のConectivityManagerの使い方が間違っているか、Android OSのせいなのか。
※ちなみにWi-fi通信のリクエスト(2回目のリクエスト)をした際、onAvailable()ではnetworkはWi-fiが返ってきており
bindProcessToNetwork()の戻り値はtrueとなっており、バインドはうまくいっているが
その後、モバイルに強制的に切り替わっているようです。
何か解決案がありましたら、先生方にご教授頂ければと思っております。よろしくお願い致します。
(2019/05/22 追記)
やりたい事としては、ファイルのDLのみモバイル通信で行うことです。
DownloadManagerクラスに、ファイルDLをする際、指定した通信でDLを許可するメソッドがあります。
こちらも試してみましたが、mobileのみを許可したのにwi-fi接続でDLをしており、うまく動いてくれませんでした。
(2019/06/11 追記)
MainActivity.java
private ConnectivityManager.NetworkCallback mCallback = null; @Override protected void onCreate(Bundle savedInstanceState) { button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String res = initCheck(); switch (res) { case "Wi-fi通信": // モバイル通信リクエスト networkChange(NetworkCapabilities.TRANSPORT_CELLULAR); break; case "モバイル通信": // Wi-fi通信リクエスト networkChange(NetworkCapabilities.TRANSPORT_WIFI); break; default: break; } init(); } private String initCheck() { ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE); Network[] allNetwork = connectivityManager.getAllNetworks(); String res = null; for (Network network : allNetwork) { NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network); if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { // WiFi network res = "Wi-fi通信"; } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { // Mobile network res = "モバイル通信"; } else { // Other network res = "それ以外"; } } return res; private void init() { //request permissions int CODE_WRITE_SETTINGS_PERMISSION = 6789; boolean permission; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { permission = Settings.System.canWrite(this); } else { permission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED; } if (permission) { //Write allowed } else { //Write not allowed if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + this.getPackageName())); this.startActivityForResult(intent, CODE_WRITE_SETTINGS_PERMISSION); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_SETTINGS}, CODE_WRITE_SETTINGS_PERMISSION); } } } private void networkChange(int request) { ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE); // リクエストしたいNetworkを取得するためにNetworkRequestを作成 NetworkRequest.Builder builder = new NetworkRequest.Builder(); // Networkの種類を指定 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); // Transportタイプを指定 builder.addTransportType(request); NetworkRequest networkRequest = builder.build(); // ネットワークリセット resetDefaultNetwork(connectivityManager); try { Thread.sleep(1000); } catch (InterruptedException e) { } mCallback = new NetworkChangeCallback(connectivityManager); // NetworkRequestとNetworkCallbackを使ってNetworkをリクエストする connectivityManager.requestNetwork(networkRequest, mCallback); } private void resetDefaultNetwork(ConnectivityManager manager) { // すでにプロセスのネットワークが設定されている時はnullを設定する if (manager.getBoundNetworkForProcess() != null) { manager.bindProcessToNetwork(null); } // NetworkCallbackを設定している時はunregisterする if (mCallback != null) { try { manager.unregisterNetworkCallback(mCallback); mCallback = null; } catch (IllegalArgumentException e) { Log.e(TAG, e.getMessage()); } } } /** * 通信リクエスト後のコールバッククラス */ private class NetworkChangeCallback extends ConnectivityManager.NetworkCallback { ConnectivityManager mManager = null; public NetworkChangeCallback(ConnectivityManager mConnectivityManager) { mManager = mConnectivityManager; } @Override public void onAvailable(Network network) { super.onAvailable(network); boolean result = mManager.bindProcessToNetwork(network); if (!result) { Log.e(TAG, "バインド失敗"); } else { checkNetwork(); } } ・・・ private void checkNetwork() { // 設定したいNetworkが使えるかは確認しておいていいと思います。 Network[] allNetwork = mManager.getAllNetworks(); Button button = findViewById(R.id.button_con_result); for (Network network : allNetwork) { NetworkCapabilities networkCapabilities = mManager.getNetworkCapabilities(network); if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { // WiFi network button.setText("Wi-fi通信"); } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { // Mobile network button.setText("モバイル通信"); } else { // Other network button.setText("それ以外"); } } } };
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" />
あなたの回答
tips
プレビュー