1 package jp.sfjp.gokigen.a01c.olycamerawrapper;
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;
19 import androidx.annotation.NonNull;
21 import java.util.concurrent.Executor;
22 import java.util.concurrent.Executors;
23 import java.util.concurrent.TimeUnit;
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;
35 * https://github.com/googlesamples/android-WearHighBandwidthNetworking/blob/master/Wearable/src/main/java/com/example/android/wearable/wear/wearhighbandwidthnetworking/MainActivity.java
37 * Created by MRSa on 2017/02/28.
39 class OlyCameraConnection implements ICameraConnection, OLYCameraConnectionListener
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;
48 private boolean isWatchingWifiStatus = false;
50 private final ConnectivityManager connectivityManager;
51 private ConnectivityManager.NetworkCallback networkCallback = null;
53 // Handler for dealing with network connection timeouts.
54 private final Handler networkConnectionTimeoutHandler;
56 // Message to notify the network request timout handler that too much time has passed.
57 private static final int MESSAGE_CONNECTIVITY_TIMEOUT = 1;
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;
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);
72 // The minimum network bandwidth required by the app for high-bandwidth operations.
73 private static final int MIN_NETWORK_BANDWIDTH_KBPS = 10000;
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";
83 OlyCameraConnection(Activity context, OLYCamera camera, ICameraStatusReceiver statusReceiver)
85 Log.v(TAG, "OlyCameraConnection()");
86 this.context = context;
88 this.connectivityManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
89 this.networkConnectionTimeoutHandler = new Handler(Looper.getMainLooper())
92 public void handleMessage(Message msg)
96 case MESSAGE_CONNECTIVITY_TIMEOUT:
97 Log.d(TAG, "Network connection timeout");
98 //setUiState(UI_STATE_CONNECTION_TIMEOUT);
99 unregisterNetworkCallback();
104 requestHighBandwidthNetwork();
106 Network activeNetwork = connectivityManager.getActiveNetwork();
107 if (activeNetwork != null)
109 int bandwidth = connectivityManager.getNetworkCapabilities(activeNetwork).getLinkDownstreamBandwidthKbps();
110 if (bandwidth < MIN_BANDWIDTH_KBPS)
112 // Request a high-bandwidth network
117 // You already are on a high-bandwidth network, so start your network request
121 this.statusReceiver = statusReceiver;
122 connectionReceiver = new BroadcastReceiver()
125 public void onReceive(Context context, Intent intent)
127 onReceiveBroadcastOfConnection(context, intent);
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()
137 Network network = connectivityManager.getBoundNetworkForProcess();
138 network = network == null ? connectivityManager.getActiveNetwork() : network;
144 // requires android.permission.ACCESS_NETWORK_STATE
145 int bandwidth = connectivityManager.getNetworkCapabilities(network).getLinkDownstreamBandwidthKbps();
146 return (bandwidth >= MIN_NETWORK_BANDWIDTH_KBPS);
151 private void unregisterNetworkCallback()
153 if (networkCallback != null)
155 Log.d(TAG, "Unregistering network callback");
156 connectivityManager.unregisterNetworkCallback(networkCallback);
157 networkCallback = null;
161 private void releaseHighBandwidthNetwork()
163 connectivityManager.bindProcessToNetwork(null);
164 unregisterNetworkCallback();
167 private void addWifiNetwork()
169 // requires android.permission.CHANGE_WIFI_STATE
170 context.getApplicationContext().startActivity(new Intent(ACTION_ADD_NETWORK_SETTINGS));
175 * Wifiが使える状態だったら、カメラと接続して動作するよ
178 private void onReceiveBroadcastOfConnection(Context context, Intent intent)
180 statusReceiver.onStatusNotify(context.getString(R.string.connect_check_wifi));
181 Log.v(TAG,context.getString(R.string.connect_check_wifi));
183 String action = intent.getAction();
184 if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION))
186 WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
187 WifiInfo info = wifiManager.getConnectionInfo();
188 if (wifiManager.isWifiEnabled() && info != null && info.getNetworkId() != -1)
199 * (接続の実処理は onReceiveBroadcastOfConnection() で実施)
202 public void startWatchWifiStatus(@NonNull Context context)
204 Log.v(TAG, "startWatchWifiStatus()");
205 statusReceiver.onStatusNotify("prepare");
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;
218 public void stopWatchWifiStatus(@NonNull Context context)
220 Log.v(TAG, "stopWatchWifiStatus()");
221 context.unregisterReceiver(connectionReceiver);
222 isWatchingWifiStatus = false;
227 * Wifi接続状態の監視処理を行っているかどうか
229 * @return true : 監視中 / false : 停止中
232 public boolean isWatchWifiStatus() {
233 return (isWatchingWifiStatus);
239 * @param powerOff 真ならカメラの電源オフを伴う
242 public void disconnect(final boolean powerOff)
244 Log.v(TAG, "disconnect()");
245 disconnectFromCamera(powerOff);
246 statusReceiver.onCameraDisconnected();
253 public void connect() {
258 * カメラの通信状態変化を監視するためのインターフェース
260 * @param camera 例外が発生した OLYCamera
264 public void onDisconnectedByError(OLYCamera camera, OLYCameraKitException e)
267 statusReceiver.onCameraDisconnected();
273 private void disconnectFromCamera(final boolean powerOff)
275 Log.v(TAG, "disconnectFromCamera()");
278 cameraExecutor.execute(new CameraDisconnectSequence(camera, powerOff));
289 private void connectToCamera()
291 Log.v(TAG, "connectToCamera()");
294 cameraExecutor.execute(new CameraConnectSequence(context, camera, statusReceiver));
302 private void requestHighBandwidthNetwork()
304 // Before requesting a high-bandwidth network, ensure prior requests are invalidated.
305 unregisterNetworkCallback();
307 Log.d(TAG, "requestHighBandwidthNetwork(): Requesting high-bandwidth network");
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)
319 networkCallback = new ConnectivityManager.NetworkCallback()
322 public void onAvailable(final Network network)
324 networkConnectionTimeoutHandler.removeMessages(MESSAGE_CONNECTIVITY_TIMEOUT);
325 context.runOnUiThread(new Runnable()
329 // requires android.permission.INTERNET
330 if (!connectivityManager.bindProcessToNetwork(network))
332 Log.e(TAG, "ConnectivityManager.bindProcessToNetwork() requires android.permission.INTERNET");
336 Log.d(TAG, "Network available");
343 public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities)
345 context.runOnUiThread(new Runnable()
350 Log.d(TAG, "Network capabilities changed");
356 public void onLost(Network network)
358 Log.d(TAG, "Network lost");
362 // requires android.permission.CHANGE_NETWORK_STATE
363 connectivityManager.requestNetwork(request, networkCallback);
365 networkConnectionTimeoutHandler.sendMessageDelayed(networkConnectionTimeoutHandler.obtainMessage(MESSAGE_CONNECTIVITY_TIMEOUT), NETWORK_CONNECTIVITY_TIMEOUT_MS);