original source : https://developer.android.com/training/wearables/data-layer/network-access.html

Network Access and Syncing

With Android Wear 2.0, a watch can communicate with a network directly.

This direct network access replaces the use (in Wear 1.x) of the Data Layer API for connecting to a network .

Network Access

watch’s network traffic generally is proxied through the phone. But when a phone is unavailable, Wi-Fi and cellular networks are used, depending on the hardware. The Wear platform handles transitions between networks.

You can use protocols such as HTTP, TCP, and UDP. However, the android.webkit APIs (including the CookieManager class) are not available. You can use cookies by reading and writing headers on requests and responses.

참고사항

  • The JobScheduler API for asynchronous jobs, including polling at regular intervals (described below)
  • Multi-networking APIs if you need to connect to specific network types; see Multiple Network Connections

High-bandwidth Network Access

The Android Wear platform manages network connectivity.

The platform chooses the default, active network by balancing two factors:

  • The need for long battery life
  • The need for network bandwidth

            Acquiring a High-Bandwidth Network

high-bandwidth network가 항상 사용가능한게 아니므로

high-bandwidth network 가 필요한 경우아래의 과정을 거쳐야 한다. 

  1. Check for an active network, and if there is one, check its bandwidth.
  2. If there isn’t an active network, or its bandwidth is insufficient, request access to an unmetered Wi-Fi or cellular network.

ConnectivityManager class 를 사용하여 네트워크가 있는지 밴드크기 어떤지 확인가능하다. 

int MIN_BANDWIDTH_KBPS = 320;
mConnectivityManager =
 (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Network activeNetwork = mConnectivityManager.getActiveNetwork();

if (activeNetwork != null) {
 int bandwidth =
   mConnectivityManager.getNetworkCapabilities(activeNetwork).getLinkDownstreamBandwidthKbps();

 if (bandwidth < MIN_BANDWIDTH_KBPS) {
   // Request a high-bandwidth network
 }
} else {
 // You already are on a high-bandwidth network, so start your network request
}

You can request an unmetered, high-bandwidth network using the ConnectivityManager.

When the network is ready (e.g., the device’s Wi-Fi radio connects to a saved network), the onAvailable() method of your NetworkCallback instance is called. If a suitable network is not found, the onAvailable() method is not called. Therefore, you should time-out your request manually; see Waiting for Network Availability.

mNetworkCallback = new ConnectivityManager.NetworkCallback() {
 @Override
 public void onAvailable(Network network) {
   if (bindProcessToNetwork(network)) {
     // socket connections will now use this network
   } else {
     // app doesn't have android.permission.INTERNET permission
   }
 }
};

NetworkRequest request = new NetworkRequest.Builder()
 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
 .build();

mConnectivityManager.requestNetwork(request, mNetworkCallback);

       Releasing the Network

사용이 끝난 network는 release해야 한다. 

mConnectivityManager.bindProcessToNetwork(null);
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);

또 이작업은 

activity’s onStop() method 안에서도 실행되어야 한다.

       Waiting for Network Availability

if a watch cannot connect to a network, the onAvailable() method of your NetworkCallback instance is not called. Therefore, you should time-out the request after a predetermined length of time and release any associated resources.

int MESSAGE_CONNECTIVITY_TIMEOUT = 1;
long NETWORK_CONNECTIVITY_TIMEOUT_MS = 10000

mHandler = new Handler() {
 @Override
 public void handleMessage(Message msg) {
   switch (msg.what) {
     case MESSAGE_CONNECTIVITY_TIMEOUT:
       // unregister the network
       break;
   }
 }
};

mNetworkCallback = new ConnectivityManager.NetworkCallback() {
 @Override
 public void onAvailable(Network network) {
   mHandler.removeMessages(MESSAGE_CONNECTIVITY_TIMEOUT);
   ...
 }
};

mConnectivityManager.requestNetwork(request, mNetworkCallback);

mHandler.sendMessageDelayed(
 mHandler.obtainMessage(MESSAGE_CONNECTIVITY_TIMEOUT),
 NETWORK_CONNECTIVITY_TIMEOUT_MS);

       

Monitoring the Network State

mNetworkCallback = ConnectivityManager.NetworkCallback {
 @Override
 public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
   int bandwidth =
     mConnectivityManager.getNetworkCapabilities(network).getLinkDownstreamBandwidthKbps();

     if (bandwidth < MIN_BANDWIDTH.KBPS) {
       // handle insufficient network bandwidth
     }
 }

 @Override
 public void onLost(Network network) {
   // handle network loss
 }
}

       

Launching the Wi-Fi Settings Activity

사용자가 저장한 wi-fi가 없거나 접근 불가능한 경우 사용자를 wi-fi 설정 activity로 이동시킬수 있다.

context.startActivity(new Intent("com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS"));

Cloud Messaging

For sending notifications, apps can directly use Firebase Cloud Messaging (FCM)

By default, notifications are bridged (shared) from a phone app to a watch. If you have a standalone Wear app and a corresponding phone app, duplicate notifications can occur.

Using Background Services

You should schedule jobs with the JobScheduler API, which enables your app to register for Doze-safe code execution.

Jobs should use a JobInfo.Builder object to provide constraints and metadata.

  • To schedule a task that requires networking, use setRequiredNetworkType(int networkType), specifying NETWORK_TYPE_ANY or NETWORK_TYPE_UNMETERED; note that NETWORK_TYPE_UNMETERED is for large data transfers while NETWORK_TYPE_ANY is for small transfers
  • To schedule a task while charging, use setRequiresCharging(boolean requiresCharging)
  • To specify that a device is idle for a task, use setRequiresDeviceIdle(boolean requiresDeviceIdle); this method is useful for lower-priority background work or synchronization, especially when used with setRequiresCharging

Note that some low-bandwidth networks, such as Bluetooth LE, are considered meter

Scheduling with constraints

You can use the builder method setExtras to attach a bundle of app-specific metadata to the job request. When your job executes, this bundle is provided to your job service. Note the MY_JOB_ID value passed to the JobInfo.Builder constructor. This MY_JOB_ID value is an app-provided identifier. Subsequent calls to cancel, and subsequent jobs created with that same value, will update the existing job.

JobInfo jobInfo = new JobInfo.Builder(MY_JOB_ID,
       new ComponentName(this, MyJobService.class))
       .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
       .setRequiresCharging(true)
       .setExtras(extras)
       .build();
((JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE))
       .schedule(jobInfo);

아래는 위의 작업을 서비스하는 부분설명.

JobParameters object is passed into the onStartJobmethod. The JobParameters object enables you to get the job ID value along with any extras bundle provided when scheduling the job.

The onStartJobmethod is called on the main application thread, and therefore any expensive logic should be run from a separate thread .

When work is complete, you would call the jobFinished method to notify JobScheduler that the task is done.

public class MyJobService extends JobService {
   @Override public boolean onStartJob(JobParameters params) {
       new JobAsyncTask().execute(params);
       return true;
   }

   private class JobAsyncTask extends AsyncTask

Comments are closed.

Post Navigation