diff options
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.java | 340 |
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 |