OSDN Git Service

9103772b83df0684de2524a1392d6da800b55bf4
[gokigen/A01c.git] / wear / src / main / java / jp / sfjp / gokigen / a01c / WifiConnection.kt
1 package jp.sfjp.gokigen.a01c
2
3 import android.content.BroadcastReceiver
4 import android.content.Context
5 import android.content.Intent
6 import android.content.IntentFilter
7 import android.net.ConnectivityManager
8 import android.net.ConnectivityManager.NetworkCallback
9 import android.net.Network
10 import android.net.NetworkCapabilities
11 import android.net.NetworkRequest
12 import android.net.wifi.WifiManager
13 import android.os.Handler
14 import android.os.Looper
15 import android.os.Message
16 import android.util.Log
17 import androidx.appcompat.app.AppCompatActivity
18 import java.util.concurrent.TimeUnit
19
20 class WifiConnection(private val context: AppCompatActivity, private val callback : IWifiConnection)
21 {
22     private var isWatchingWifiStatus = false
23
24     private val connectivityManager: ConnectivityManager = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
25     private val connectionReceiver: BroadcastReceiver = object : BroadcastReceiver()
26     {
27         override fun onReceive(context: Context, intent: Intent)
28         {
29             onReceiveBroadcastOfConnection(context, intent)
30         }
31     }
32
33     private val networkConnectionTimeoutHandler = object : Handler(Looper.getMainLooper())
34     {
35         override fun handleMessage(msg: Message)
36         {
37             when (msg.what) {
38                 MESSAGE_CONNECTIVITY_TIMEOUT -> {
39                     Log.d(TAG, "Network connection timeout")
40                     unregisterNetworkCallback()
41                 }
42             }
43         }
44     }
45
46     private val networkCallback = object : NetworkCallback()
47     {
48         override fun onAvailable(network: Network) {
49             networkConnectionTimeoutHandler.removeMessages(MESSAGE_CONNECTIVITY_TIMEOUT)
50             context.runOnUiThread {
51                 if (!connectivityManager.bindProcessToNetwork(network))
52                 {
53                     Log.e(TAG, "ConnectivityManager.bindProcessToNetwork()  requires android.permission.INTERNET")
54                 }
55                 else
56                 {
57                     Log.d(TAG, "Network available")
58                 }
59             }
60         }
61
62         override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities)
63         {
64             context.runOnUiThread { Log.d(TAG, "Network capabilities changed") }
65         }
66
67         override fun onLost(network: Network)
68         {
69             Log.d(TAG, "Network lost")
70         }
71     }
72
73
74     init
75     {
76         Log.v(TAG, "WifiConnection()")
77         requestHighBandwidthNetwork()
78 /*
79         Network activeNetwork = connectivityManager.getActiveNetwork();
80         if (activeNetwork != null)
81         {
82             int bandwidth = connectivityManager.getNetworkCapabilities(activeNetwork).getLinkDownstreamBandwidthKbps();
83             if (bandwidth < MIN_BANDWIDTH_KBPS)
84             {
85                 // Request a high-bandwidth network
86             }
87         }
88         else
89         {
90             // You already are on a high-bandwidth network, so start your network request
91         }
92 */
93
94 /*
95         Network activeNetwork = connectivityManager.getActiveNetwork();
96         if (activeNetwork != null)
97         {
98             int bandwidth = connectivityManager.getNetworkCapabilities(activeNetwork).getLinkDownstreamBandwidthKbps();
99             if (bandwidth < MIN_BANDWIDTH_KBPS)
100             {
101                 // Request a high-bandwidth network
102             }
103         }
104         else
105         {
106             // You already are on a high-bandwidth network, so start your network request
107         }
108 */
109      }
110
111     // Determine if there is a high-bandwidth network exists. Checks both the active
112     // and bound networks. Returns false if no network is available (low or high-bandwidth).
113     private fun isNetworkHighBandwidth(): Boolean
114     {
115         var network: Network? = connectivityManager.boundNetworkForProcess
116         network = network ?: connectivityManager.activeNetwork
117         if (network == null)
118         {
119             return (false)
120         }
121         val networkCapabilities = connectivityManager.getNetworkCapabilities(network) ?: return (false)
122         return (networkCapabilities.linkDownstreamBandwidthKbps >= MIN_NETWORK_BANDWIDTH_KBPS)
123     }
124
125
126     private fun unregisterNetworkCallback()
127     {
128         Log.d(TAG, "Unregistering network callback")
129         connectivityManager.unregisterNetworkCallback(networkCallback)
130     }
131
132     private fun releaseHighBandwidthNetwork()
133     {
134         connectivityManager.bindProcessToNetwork(null)
135         unregisterNetworkCallback()
136     }
137
138     private fun addWifiNetwork()
139     {
140         // requires android.permission.CHANGE_WIFI_STATE
141         context.applicationContext.startActivity(Intent(ACTION_ADD_NETWORK_SETTINGS))
142     }
143
144     /**
145      * Wifiが使える状態だったら、カメラと接続して動作するよ
146      *
147      */
148     @Suppress("DEPRECATION")
149     private fun onReceiveBroadcastOfConnection(context: Context, intent: Intent)
150     {
151         Log.v(TAG, context.getString(R.string.connect_check_wifi))
152         try
153         {
154             val action = intent.action
155             if (action == ConnectivityManager.CONNECTIVITY_ACTION)
156             {
157                 val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
158                 val info = wifiManager.connectionInfo
159                 if (wifiManager.isWifiEnabled)
160                 {
161                     if ((info != null)&&(info.networkId != -1))
162                     {
163                         Log.v(TAG, " READY TO CONNECT CAMERA. " + info.networkId)
164                     }
165                     callback.onConnectedToWifi()
166                 }
167             }
168         }
169         catch (e : Exception)
170         {
171             e.printStackTrace()
172         }
173     }
174
175     fun requestNetwork()
176     {
177         Log.v(TAG, " requestNetwork()")
178         requestHighBandwidthNetwork()
179     }
180
181     /**
182      * Wifi接続状態の監視
183      * (接続の実処理は onReceiveBroadcastOfConnection() で実施)
184      */
185     @Suppress("DEPRECATION")
186     fun startWatchWifiStatus()
187     {
188         Log.v(TAG, "startWatchWifiStatus()")
189         val filter = IntentFilter()
190         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
191         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
192         context.registerReceiver(connectionReceiver, filter)
193         isWatchingWifiStatus = true
194     }
195
196     /**
197      * Wifi接続状態の監視終了
198      */
199     fun stopWatchWifiStatus()
200     {
201         Log.v(TAG, "stopWatchWifiStatus()")
202         context.unregisterReceiver(connectionReceiver)
203         isWatchingWifiStatus = false
204     }
205
206     /**
207      * Wifi接続状態の監視処理を行っているかどうか
208      *
209      * @return true : 監視中 / false : 停止中
210      */
211     fun isWatchWifiStatus(): Boolean
212     {
213         return isWatchingWifiStatus
214     }
215
216     private fun requestHighBandwidthNetwork()
217     {
218         // Before requesting a high-bandwidth network, ensure prior requests are invalidated.
219         unregisterNetworkCallback()
220         Log.d(TAG, "requestHighBandwidthNetwork(): Requesting high-bandwidth network")
221
222         // Requesting an unmetered network may prevent you from connecting to the cellular
223         // network on the user's watch or phone; however, unless you explicitly ask for permission
224         // to a access the user's cellular network, you should request an unmetered network.
225         val request = NetworkRequest.Builder()
226             .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
227             .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
228             .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
229             .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
230             .build()
231
232         // requires android.permission.CHANGE_NETWORK_STATE
233         connectivityManager.requestNetwork(request, networkCallback)
234         networkConnectionTimeoutHandler.sendMessageDelayed(networkConnectionTimeoutHandler.obtainMessage(MESSAGE_CONNECTIVITY_TIMEOUT), NETWORK_CONNECTIVITY_TIMEOUT_MS)
235     }
236
237     companion object
238     {
239         private val TAG = WifiConnection::class.java.simpleName
240         private const val MESSAGE_CONNECTIVITY_TIMEOUT = 1
241         private const val MIN_NETWORK_BANDWIDTH_KBPS = 10000
242         private const val ACTION_ADD_NETWORK_SETTINGS = "com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS"
243         private val NETWORK_CONNECTIVITY_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(2000)
244     }
245 }