OSDN Git Service

WIFIの接続が切れていたのを少し変更する。
[gokigen/A01c.git] / wear / src / main / java / jp / sfjp / gokigen / a01c / olycamerawrapper / OlyCameraConnection.java
1 package jp.sfjp.gokigen.a01c.olycamerawrapper;
2
3 import android.app.Activity;
4 import android.content.BroadcastReceiver;
5 import android.content.Context;
6 import android.content.Intent;
7 import android.content.IntentFilter;
8 import android.net.ConnectivityManager;
9 import android.net.Network;
10 import android.net.NetworkCapabilities;
11 import android.net.NetworkRequest;
12 import android.net.wifi.WifiInfo;
13 import android.net.wifi.WifiManager;
14 import android.os.Handler;
15 import android.os.Looper;
16 import android.os.Message;
17 import android.util.Log;
18
19 import androidx.annotation.NonNull;
20
21 import java.util.concurrent.Executor;
22 import java.util.concurrent.Executors;
23 import java.util.concurrent.TimeUnit;
24
25 import jp.co.olympus.camerakit.OLYCamera;
26 import jp.co.olympus.camerakit.OLYCameraConnectionListener;
27 import jp.co.olympus.camerakit.OLYCameraKitException;
28 import jp.sfjp.gokigen.a01c.ICameraConnection;
29 import jp.sfjp.gokigen.a01c.R;
30 import jp.sfjp.gokigen.a01c.liveview.ICameraStatusReceiver;
31
32 /**
33  *   カメラの接続・切断処理クラス
34  *
35  *     https://github.com/googlesamples/android-WearHighBandwidthNetworking/blob/master/Wearable/src/main/java/com/example/android/wearable/wear/wearhighbandwidthnetworking/MainActivity.java
36  *
37  * Created by MRSa on 2017/02/28.
38  */
39 class OlyCameraConnection implements ICameraConnection, OLYCameraConnectionListener
40 {
41     private final String TAG = toString();
42     private final Activity context;
43     private final OLYCamera camera;
44     private final Executor cameraExecutor = Executors.newFixedThreadPool(1);
45     private final BroadcastReceiver connectionReceiver;
46     private final ICameraStatusReceiver statusReceiver;
47
48     private boolean isWatchingWifiStatus = false;
49
50     private final ConnectivityManager connectivityManager;
51     private ConnectivityManager.NetworkCallback networkCallback = null;
52
53     // Handler for dealing with network connection timeouts.
54     private final Handler networkConnectionTimeoutHandler;
55
56     // Message to notify the network request timout handler that too much time has passed.
57     private static final int MESSAGE_CONNECTIVITY_TIMEOUT = 1;
58
59     // These constants are used by setUiState() to determine what information to display in the UI,
60     // as this app reuses UI components for the various states of the app, which is dependent on
61     // the state of the network.
62     static final int UI_STATE_REQUEST_NETWORK = 1;
63     static final int UI_STATE_REQUESTING_NETWORK = 2;
64     static final int UI_STATE_NETWORK_CONNECTED = 3;
65     static final int UI_STATE_CONNECTION_TIMEOUT = 4;
66     static final int MIN_BANDWIDTH_KBPS = 160;
67
68     // How long the app should wait trying to connect to a sufficient high-bandwidth network before
69     // asking the user to add a new Wi-Fi network.
70     private static final long NETWORK_CONNECTIVITY_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(2000);
71
72     // The minimum network bandwidth required by the app for high-bandwidth operations.
73     private static final int MIN_NETWORK_BANDWIDTH_KBPS = 10000;
74
75     // Intent action for sending the user directly to the add Wi-Fi network activity.
76     private static final String ACTION_ADD_NETWORK_SETTINGS = "com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS";
77
78
79     /**
80      *    コンストラクタ
81      *
82      */
83     OlyCameraConnection(Activity context, OLYCamera camera, ICameraStatusReceiver statusReceiver)
84     {
85         Log.v(TAG, "OlyCameraConnection()");
86         this.context = context;
87         this.camera = camera;
88         this.connectivityManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
89         this.networkConnectionTimeoutHandler = new Handler(Looper.getMainLooper())
90         {
91             @Override
92             public void handleMessage(Message msg)
93             {
94                 switch (msg.what)
95                 {
96                     case MESSAGE_CONNECTIVITY_TIMEOUT:
97                         Log.d(TAG, "Network connection timeout");
98                         //setUiState(UI_STATE_CONNECTION_TIMEOUT);
99                         unregisterNetworkCallback();
100                         break;
101                 }
102             }
103         };
104         requestHighBandwidthNetwork();
105 /*
106         Network activeNetwork = connectivityManager.getActiveNetwork();
107         if (activeNetwork != null)
108         {
109             int bandwidth = connectivityManager.getNetworkCapabilities(activeNetwork).getLinkDownstreamBandwidthKbps();
110             if (bandwidth < MIN_BANDWIDTH_KBPS)
111             {
112                 // Request a high-bandwidth network
113             }
114         }
115         else
116         {
117             // You already are on a high-bandwidth network, so start your network request
118         }
119 */
120
121         this.statusReceiver = statusReceiver;
122         connectionReceiver = new BroadcastReceiver()
123         {
124             @Override
125             public void onReceive(Context context, Intent intent)
126             {
127                 onReceiveBroadcastOfConnection(context, intent);
128             }
129         };
130
131     }
132
133     // Determine if there is a high-bandwidth network exists. Checks both the active
134     // and bound networks. Returns false if no network is available (low or high-bandwidth).
135     private boolean isNetworkHighBandwidth()
136     {
137         Network network = connectivityManager.getBoundNetworkForProcess();
138         network = network == null ? connectivityManager.getActiveNetwork() : network;
139         if (network == null)
140         {
141             return (false);
142         }
143
144         // requires android.permission.ACCESS_NETWORK_STATE
145         int bandwidth = connectivityManager.getNetworkCapabilities(network).getLinkDownstreamBandwidthKbps();
146         return (bandwidth >= MIN_NETWORK_BANDWIDTH_KBPS);
147     }
148
149
150
151     private void unregisterNetworkCallback()
152     {
153         if (networkCallback != null)
154         {
155             Log.d(TAG, "Unregistering network callback");
156             connectivityManager.unregisterNetworkCallback(networkCallback);
157             networkCallback = null;
158         }
159     }
160
161     private void releaseHighBandwidthNetwork()
162     {
163         connectivityManager.bindProcessToNetwork(null);
164         unregisterNetworkCallback();
165     }
166
167     private void addWifiNetwork()
168     {
169         // requires android.permission.CHANGE_WIFI_STATE
170         context.getApplicationContext().startActivity(new Intent(ACTION_ADD_NETWORK_SETTINGS));
171     }
172
173
174     /**
175      *   Wifiが使える状態だったら、カメラと接続して動作するよ
176      *
177      */
178     private void onReceiveBroadcastOfConnection(Context context, Intent intent)
179     {
180         statusReceiver.onStatusNotify(context.getString(R.string.connect_check_wifi));
181         Log.v(TAG,context.getString(R.string.connect_check_wifi));
182
183         String action = intent.getAction();
184         if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION))
185         {
186             WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
187             WifiInfo info = wifiManager.getConnectionInfo();
188             if (wifiManager.isWifiEnabled() && info != null && info.getNetworkId() != -1)
189             {
190                 // カメラとの接続処理を行う
191                 connectToCamera();
192             }
193         }
194     }
195
196
197     /**
198      * Wifi接続状態の監視
199      * (接続の実処理は onReceiveBroadcastOfConnection() で実施)
200      */
201     @Override
202     public void startWatchWifiStatus(@NonNull Context context)
203     {
204         Log.v(TAG, "startWatchWifiStatus()");
205         statusReceiver.onStatusNotify("prepare");
206
207         IntentFilter filter = new IntentFilter();
208         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
209         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
210         context.registerReceiver(connectionReceiver, filter);
211         isWatchingWifiStatus = true;
212     }
213
214     /**
215      * Wifi接続状態の監視終了
216      */
217     @Override
218     public void stopWatchWifiStatus(@NonNull Context context)
219     {
220         Log.v(TAG, "stopWatchWifiStatus()");
221         context.unregisterReceiver(connectionReceiver);
222         isWatchingWifiStatus = false;
223         disconnect(false);
224     }
225
226     /**
227      * Wifi接続状態の監視処理を行っているかどうか
228      *
229      * @return true : 監視中 / false : 停止中
230      */
231     @Override
232     public boolean isWatchWifiStatus() {
233         return (isWatchingWifiStatus);
234     }
235
236     /**
237      *   カメラとの接続を解除する
238      *
239      * @param powerOff 真ならカメラの電源オフを伴う
240      */
241     @Override
242     public void disconnect(final boolean powerOff)
243     {
244         Log.v(TAG, "disconnect()");
245         disconnectFromCamera(powerOff);
246         statusReceiver.onCameraDisconnected();
247     }
248
249     /**
250      * カメラとの再接続を指示する
251      */
252     @Override
253     public void connect() {
254         connectToCamera();
255     }
256
257     /**
258      * カメラの通信状態変化を監視するためのインターフェース
259      *
260      * @param camera 例外が発生した OLYCamera
261      * @param e      カメラクラスの例外
262      */
263     @Override
264     public void onDisconnectedByError(OLYCamera camera, OLYCameraKitException e)
265     {
266         // カメラが切れた時に通知する
267         statusReceiver.onCameraDisconnected();
268     }
269
270     /**
271      * カメラとの切断処理
272      */
273     private void disconnectFromCamera(final boolean powerOff)
274     {
275         Log.v(TAG, "disconnectFromCamera()");
276         try
277         {
278             cameraExecutor.execute(new CameraDisconnectSequence(camera, powerOff));
279         }
280         catch (Exception e)
281         {
282             e.printStackTrace();
283         }
284     }
285
286     /**
287      * カメラとの接続処理
288      */
289     private void connectToCamera()
290     {
291         Log.v(TAG, "connectToCamera()");
292         try
293         {
294             cameraExecutor.execute(new CameraConnectSequence(context, camera, statusReceiver));
295         }
296         catch (Exception e)
297         {
298             e.printStackTrace();
299         }
300     }
301
302     private void requestHighBandwidthNetwork()
303     {
304         // Before requesting a high-bandwidth network, ensure prior requests are invalidated.
305         unregisterNetworkCallback();
306
307         Log.d(TAG, "requestHighBandwidthNetwork(): Requesting high-bandwidth network");
308
309         // Requesting an unmetered network may prevent you from connecting to the cellular
310         // network on the user's watch or phone; however, unless you explicitly ask for permission
311         // to a access the user's cellular network, you should request an unmetered network.
312         NetworkRequest request = new NetworkRequest.Builder()
313                 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
314                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
315                 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
316                 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
317                 .build();
318
319         networkCallback = new ConnectivityManager.NetworkCallback()
320         {
321             @Override
322             public void onAvailable(final Network network)
323             {
324                 networkConnectionTimeoutHandler.removeMessages(MESSAGE_CONNECTIVITY_TIMEOUT);
325                 context.runOnUiThread(new Runnable()
326                 {
327                     @Override
328                     public void run() {
329                         // requires android.permission.INTERNET
330                         if (!connectivityManager.bindProcessToNetwork(network))
331                         {
332                             Log.e(TAG, "ConnectivityManager.bindProcessToNetwork()  requires android.permission.INTERNET");
333                         }
334                         else
335                         {
336                             Log.d(TAG, "Network available");
337                         }
338                     }
339                 });
340             }
341
342             @Override
343             public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities)
344             {
345                 context.runOnUiThread(new Runnable()
346                 {
347                     @Override
348                     public void run()
349                     {
350                         Log.d(TAG, "Network capabilities changed");
351                     }
352                 });
353             }
354
355             @Override
356             public void onLost(Network network)
357             {
358                 Log.d(TAG, "Network lost");
359             }
360         };
361
362         // requires android.permission.CHANGE_NETWORK_STATE
363         connectivityManager.requestNetwork(request, networkCallback);
364
365         networkConnectionTimeoutHandler.sendMessageDelayed(networkConnectionTimeoutHandler.obtainMessage(MESSAGE_CONNECTIVITY_TIMEOUT), NETWORK_CONNECTIVITY_TIMEOUT_MS);
366     }
367 }