summaryrefslogtreecommitdiffstats
path: root/samples/browseable/WearHighBandwidthNetworking/src/com.example.android.wearable.wear.wearhighbandwidthnetworking/MainActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'samples/browseable/WearHighBandwidthNetworking/src/com.example.android.wearable.wear.wearhighbandwidthnetworking/MainActivity.java')
-rw-r--r--samples/browseable/WearHighBandwidthNetworking/src/com.example.android.wearable.wear.wearhighbandwidthnetworking/MainActivity.java340
1 files changed, 340 insertions, 0 deletions
diff --git a/samples/browseable/WearHighBandwidthNetworking/src/com.example.android.wearable.wear.wearhighbandwidthnetworking/MainActivity.java b/samples/browseable/WearHighBandwidthNetworking/src/com.example.android.wearable.wear.wearhighbandwidthnetworking/MainActivity.java
new file mode 100644
index 000000000..b2161ed6e
--- /dev/null
+++ b/samples/browseable/WearHighBandwidthNetworking/src/com.example.android.wearable.wear.wearhighbandwidthnetworking/MainActivity.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.wearable.wear.wearhighbandwidthnetworking;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This sample demonstrates how to determine if a high-bandwidth network is available for use cases
+ * that require a minimum network bandwidth, such as streaming media or downloading large files.
+ * In addition, the sample demonstrates best practices for asking a user to add a new Wi-Fi network
+ * for high-bandwidth network operations, if currently available networks are inadequate.
+ */
+public class MainActivity extends Activity {
+ private static final String LOG_TAG = MainActivity.class.getSimpleName();
+
+ // Intent action for sending the user directly to the add Wi-Fi network activity.
+ private static final String ACTION_ADD_NETWORK_SETTINGS =
+ "com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS";
+
+ // Message to notify the network request timout handler that too much time has passed.
+ private static final int MESSAGE_CONNECTIVITY_TIMEOUT = 1;
+
+ // How long the app should wait trying to connect to a sufficient high-bandwidth network before
+ // asking the user to add a new Wi-Fi network.
+ private static final long NETWORK_CONNECTIVITY_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10);
+
+ // The minimum network bandwidth required by the app for high-bandwidth operations.
+ private static final int MIN_NETWORK_BANDWIDTH_KBPS = 10000;
+
+ private ConnectivityManager mConnectivityManager;
+ private ConnectivityManager.NetworkCallback mNetworkCallback;
+
+ // Handler for dealing with network connection timeouts.
+ private Handler mHandler;
+
+ private ImageView mConnectivityIcon;
+ private TextView mConnectivityText;
+
+ private View mButton;
+ private ImageView mButtonIcon;
+ private TextView mButtonText;
+ private TextView mInfoText;
+ private View mProgressBar;
+
+ // Tags added to the button in the UI to detect what operation the user has requested.
+ // These are required since the app reuses the button for different states of the app/UI.
+ // See onButtonClick() for how these tags are used.
+ static final String TAG_REQUEST_NETWORK = "REQUEST_NETWORK";
+ static final String TAG_RELEASE_NETWORK = "RELEASE_NETWORK";
+ static final String TAG_ADD_WIFI = "ADD_WIFI";
+
+ // These constants are used by setUiState() to determine what information to display in the UI,
+ // as this app reuses UI components for the various states of the app, which is dependent on
+ // the state of the network.
+ static final int UI_STATE_REQUEST_NETWORK = 1;
+ static final int UI_STATE_REQUESTING_NETWORK = 2;
+ static final int UI_STATE_NETWORK_CONNECTED = 3;
+ static final int UI_STATE_CONNECTION_TIMEOUT = 4;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+ mConnectivityIcon = (ImageView) findViewById(R.id.connectivity_icon);
+ mConnectivityText = (TextView) findViewById(R.id.connectivity_text);
+
+ mProgressBar = findViewById(R.id.progress_bar);
+
+ mButton = findViewById(R.id.button);
+ mButton.setTag(TAG_REQUEST_NETWORK);
+ mButtonIcon = (ImageView) findViewById(R.id.button_icon);
+ mButtonText = (TextView) findViewById(R.id.button_label);
+
+ mInfoText = (TextView) findViewById(R.id.info_text);
+
+ mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MESSAGE_CONNECTIVITY_TIMEOUT:
+ Log.d(LOG_TAG, "Network connection timeout");
+ setUiState(UI_STATE_CONNECTION_TIMEOUT);
+ unregisterNetworkCallback();
+ break;
+ }
+ }
+ };
+ }
+
+ @Override
+ public void onStop() {
+ releaseHighBandwidthNetwork();
+ super.onStop();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ if (isNetworkHighBandwidth()) {
+ setUiState(UI_STATE_NETWORK_CONNECTED);
+ } else {
+ setUiState(UI_STATE_REQUEST_NETWORK);
+ }
+ }
+
+ private void unregisterNetworkCallback() {
+ if (mNetworkCallback != null) {
+ Log.d(LOG_TAG, "Unregistering network callback");
+ mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+ mNetworkCallback = null;
+ }
+ }
+
+ // Determine if there is a high-bandwidth network exists. Checks both the active
+ // and bound networks. Returns false if no network is available (low or high-bandwidth).
+ private boolean isNetworkHighBandwidth() {
+ Network network = mConnectivityManager.getBoundNetworkForProcess();
+ network = network == null ? mConnectivityManager.getActiveNetwork() : network;
+ if (network == null) {
+ return false;
+ }
+
+ // requires android.permission.ACCESS_NETWORK_STATE
+ int bandwidth = mConnectivityManager
+ .getNetworkCapabilities(network).getLinkDownstreamBandwidthKbps();
+
+ if (bandwidth >= MIN_NETWORK_BANDWIDTH_KBPS) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private void requestHighBandwidthNetwork() {
+ // Before requesting a high-bandwidth network, ensure prior requests are invalidated.
+ unregisterNetworkCallback();
+
+ Log.d(LOG_TAG, "Requesting high-bandwidth network");
+
+ // Requesting an unmetered network may prevent you from connecting to the cellular
+ // network on the user's watch or phone; however, unless you explicitly ask for permission
+ // to a access the user's cellular network, you should request an unmetered network.
+ NetworkRequest request = new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+ .build();
+
+ mNetworkCallback = new ConnectivityManager.NetworkCallback() {
+ @Override
+ public void onAvailable(final Network network) {
+ mHandler.removeMessages(MESSAGE_CONNECTIVITY_TIMEOUT);
+
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // requires android.permission.INTERNET
+ if (!mConnectivityManager.bindProcessToNetwork(network)) {
+ Log.e(LOG_TAG, "ConnectivityManager.bindProcessToNetwork()"
+ + " requires android.permission.INTERNET");
+ setUiState(UI_STATE_REQUEST_NETWORK);
+ } else {
+ Log.d(LOG_TAG, "Network available");
+ setUiState(UI_STATE_NETWORK_CONNECTED);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onCapabilitiesChanged(Network network,
+ NetworkCapabilities networkCapabilities) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Log.d(LOG_TAG, "Network capabilities changed");
+ }
+ });
+ }
+
+ @Override
+ public void onLost(Network network) {
+ Log.d(LOG_TAG, "Network lost");
+
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ setUiState(UI_STATE_REQUEST_NETWORK);
+ }
+ });
+ }
+ };
+
+ // requires android.permission.CHANGE_NETWORK_STATE
+ mConnectivityManager.requestNetwork(request, mNetworkCallback);
+
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(MESSAGE_CONNECTIVITY_TIMEOUT),
+ NETWORK_CONNECTIVITY_TIMEOUT_MS);
+ }
+
+ private void releaseHighBandwidthNetwork() {
+ mConnectivityManager.bindProcessToNetwork(null);
+ unregisterNetworkCallback();
+ }
+
+ private void addWifiNetwork() {
+ // requires android.permission.CHANGE_WIFI_STATE
+ startActivity(new Intent(ACTION_ADD_NETWORK_SETTINGS));
+ }
+
+ /**
+ * Click handler for the button in the UI. The view tag is used to determine the specific
+ * function of the button.
+ *
+ * @param view The view that was clicked
+ */
+ public void onButtonClick(View view) {
+ switch (view.getTag().toString()) {
+ case TAG_REQUEST_NETWORK:
+ requestHighBandwidthNetwork();
+ setUiState(UI_STATE_REQUESTING_NETWORK);
+ break;
+
+ case TAG_RELEASE_NETWORK:
+ releaseHighBandwidthNetwork();
+ setUiState(UI_STATE_REQUEST_NETWORK);
+ break;
+
+ case TAG_ADD_WIFI:
+ addWifiNetwork();
+ break;
+ }
+ }
+
+ // Sets the text and icons the connectivity indicator, button, and info text in the app UI,
+ // which are all reused for the various states of the app and network connectivity. Also,
+ // will show/hide a progress bar, which is dependent on the state of the network connectivity
+ // request.
+ private void setUiState(int uiState) {
+ switch (uiState) {
+ case UI_STATE_REQUEST_NETWORK:
+ if (isNetworkHighBandwidth()) {
+ mConnectivityIcon.setImageResource(R.drawable.ic_cloud_happy);
+ mConnectivityText.setText(R.string.network_fast);
+ } else {
+ mConnectivityIcon.setImageResource(R.drawable.ic_cloud_sad);
+ mConnectivityText.setText(R.string.network_slow);
+ }
+
+ mButton.setTag(TAG_REQUEST_NETWORK);
+ mButtonIcon.setImageResource(R.drawable.ic_fast_network);
+ mButtonText.setText(R.string.button_request_network);
+ mInfoText.setText(R.string.info_request_network);
+
+ break;
+
+ case UI_STATE_REQUESTING_NETWORK:
+ mConnectivityIcon.setImageResource(R.drawable.ic_cloud_disconnected);
+ mConnectivityText.setText(R.string.network_connecting);
+
+ mProgressBar.setVisibility(View.VISIBLE);
+ mInfoText.setVisibility(View.GONE);
+ mButton.setVisibility(View.GONE);
+
+ break;
+
+ case UI_STATE_NETWORK_CONNECTED:
+ if (isNetworkHighBandwidth()) {
+ mConnectivityIcon.setImageResource(R.drawable.ic_cloud_happy);
+ mConnectivityText.setText(R.string.network_fast);
+ } else {
+ mConnectivityIcon.setImageResource(R.drawable.ic_cloud_sad);
+ mConnectivityText.setText(R.string.network_slow);
+ }
+
+ mProgressBar.setVisibility(View.GONE);
+ mInfoText.setVisibility(View.VISIBLE);
+ mButton.setVisibility(View.VISIBLE);
+
+ mButton.setTag(TAG_RELEASE_NETWORK);
+ mButtonIcon.setImageResource(R.drawable.ic_no_network);
+ mButtonText.setText(R.string.button_release_network);
+ mInfoText.setText(R.string.info_release_network);
+
+ break;
+
+ case UI_STATE_CONNECTION_TIMEOUT:
+ mConnectivityIcon.setImageResource(R.drawable.ic_cloud_disconnected);
+ mConnectivityText.setText(R.string.network_disconnected);
+
+ mProgressBar.setVisibility(View.GONE);
+ mInfoText.setVisibility(View.VISIBLE);
+ mButton.setVisibility(View.VISIBLE);
+
+ mButton.setTag(TAG_ADD_WIFI);
+ mButtonIcon.setImageResource(R.drawable.ic_wifi_network);
+ mButtonText.setText(R.string.button_add_wifi);
+ mInfoText.setText(R.string.info_add_wifi);
+
+ break;
+ }
+ }
+} \ No newline at end of file