Home | History | Annotate | Download | only in com.example.android.wearable.datalayer
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.example.android.wearable.datalayer;
     18 
     19 import static com.example.android.wearable.datalayer.DataLayerListenerService.LOGD;
     20 
     21 import android.app.Activity;
     22 import android.content.Context;
     23 import android.graphics.Bitmap;
     24 import android.graphics.BitmapFactory;
     25 import android.graphics.drawable.BitmapDrawable;
     26 import android.os.Bundle;
     27 import android.os.Handler;
     28 import android.util.Log;
     29 import android.view.LayoutInflater;
     30 import android.view.View;
     31 import android.view.ViewGroup;
     32 import android.view.WindowManager;
     33 import android.widget.ArrayAdapter;
     34 import android.widget.ListView;
     35 import android.widget.TextView;
     36 
     37 import com.google.android.gms.common.ConnectionResult;
     38 import com.google.android.gms.common.api.GoogleApiClient;
     39 import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
     40 import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
     41 import com.google.android.gms.common.data.FreezableUtils;
     42 import com.google.android.gms.wearable.Asset;
     43 import com.google.android.gms.wearable.DataApi;
     44 import com.google.android.gms.wearable.DataEvent;
     45 import com.google.android.gms.wearable.DataEventBuffer;
     46 import com.google.android.gms.wearable.DataMapItem;
     47 import com.google.android.gms.wearable.MessageApi;
     48 import com.google.android.gms.wearable.MessageEvent;
     49 import com.google.android.gms.wearable.Node;
     50 import com.google.android.gms.wearable.NodeApi;
     51 import com.google.android.gms.wearable.Wearable;
     52 
     53 import java.io.InputStream;
     54 import java.util.List;
     55 
     56 /**
     57  * Shows events and photo from the Wearable APIs.
     58  */
     59 public class MainActivity extends Activity implements ConnectionCallbacks,
     60         OnConnectionFailedListener, DataApi.DataListener, MessageApi.MessageListener,
     61         NodeApi.NodeListener {
     62 
     63     private static final String TAG = "MainActivity";
     64 
     65     private GoogleApiClient mGoogleApiClient;
     66     private ListView mDataItemList;
     67     private TextView mIntroText;
     68     private DataItemAdapter mDataItemListAdapter;
     69     private View mLayout;
     70     private Handler mHandler;
     71 
     72     @Override
     73     public void onCreate(Bundle b) {
     74         super.onCreate(b);
     75         mHandler = new Handler();
     76         LOGD(TAG, "onCreate");
     77         setContentView(R.layout.main_activity);
     78         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
     79         mDataItemList = (ListView) findViewById(R.id.dataItem_list);
     80         mIntroText = (TextView) findViewById(R.id.intro);
     81         mLayout = findViewById(R.id.layout);
     82 
     83         // Stores data events received by the local broadcaster.
     84         mDataItemListAdapter = new DataItemAdapter(this, android.R.layout.simple_list_item_1);
     85         mDataItemList.setAdapter(mDataItemListAdapter);
     86 
     87         mGoogleApiClient = new GoogleApiClient.Builder(this)
     88                 .addApi(Wearable.API)
     89                 .addConnectionCallbacks(this)
     90                 .addOnConnectionFailedListener(this)
     91                 .build();
     92     }
     93 
     94     @Override
     95     protected void onResume() {
     96         super.onResume();
     97         mGoogleApiClient.connect();
     98     }
     99 
    100     @Override
    101     protected void onPause() {
    102         super.onPause();
    103         Wearable.DataApi.removeListener(mGoogleApiClient, this);
    104         Wearable.MessageApi.removeListener(mGoogleApiClient, this);
    105         Wearable.NodeApi.removeListener(mGoogleApiClient, this);
    106         mGoogleApiClient.disconnect();
    107     }
    108 
    109     @Override
    110     public void onConnected(Bundle connectionHint) {
    111         LOGD(TAG, "onConnected(): Successfully connected to Google API client");
    112         Wearable.DataApi.addListener(mGoogleApiClient, this);
    113         Wearable.MessageApi.addListener(mGoogleApiClient, this);
    114         Wearable.NodeApi.addListener(mGoogleApiClient, this);
    115     }
    116 
    117     @Override
    118     public void onConnectionSuspended(int cause) {
    119         LOGD(TAG, "onConnectionSuspended(): Connection to Google API client was suspended");
    120     }
    121 
    122     @Override
    123     public void onConnectionFailed(ConnectionResult result) {
    124         Log.e(TAG, "onConnectionFailed(): Failed to connect, with result: " + result);
    125     }
    126 
    127     private void generateEvent(final String title, final String text) {
    128         runOnUiThread(new Runnable() {
    129             @Override
    130             public void run() {
    131                 mIntroText.setVisibility(View.INVISIBLE);
    132                 mDataItemListAdapter.add(new Event(title, text));
    133             }
    134         });
    135     }
    136 
    137     @Override
    138     public void onDataChanged(DataEventBuffer dataEvents) {
    139         LOGD(TAG, "onDataChanged(): " + dataEvents);
    140 
    141         final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
    142         dataEvents.close();
    143         for (DataEvent event : events) {
    144             if (event.getType() == DataEvent.TYPE_CHANGED) {
    145                 String path = event.getDataItem().getUri().getPath();
    146                 if (DataLayerListenerService.IMAGE_PATH.equals(path)) {
    147                     DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
    148                     Asset photo = dataMapItem.getDataMap()
    149                             .getAsset(DataLayerListenerService.IMAGE_KEY);
    150                     final Bitmap bitmap = loadBitmapFromAsset(mGoogleApiClient, photo);
    151                     mHandler.post(new Runnable() {
    152                         @Override
    153                         public void run() {
    154                             Log.d(TAG, "Setting background image..");
    155                             mLayout.setBackground(new BitmapDrawable(getResources(), bitmap));
    156                         }
    157                     });
    158 
    159                 } else if (DataLayerListenerService.COUNT_PATH.equals(path)) {
    160                     LOGD(TAG, "Data Changed for COUNT_PATH");
    161                     generateEvent("DataItem Changed", event.getDataItem().toString());
    162                 } else {
    163                     LOGD(TAG, "Unrecognized path: " + path);
    164                 }
    165 
    166             } else if (event.getType() == DataEvent.TYPE_DELETED) {
    167                 generateEvent("DataItem Deleted", event.getDataItem().toString());
    168             } else {
    169                 generateEvent("Unknown data event type", "Type = " + event.getType());
    170             }
    171         }
    172     }
    173 
    174     /**
    175      * Extracts {@link android.graphics.Bitmap} data from the
    176      * {@link com.google.android.gms.wearable.Asset}
    177      */
    178     private Bitmap loadBitmapFromAsset(GoogleApiClient apiClient, Asset asset) {
    179         if (asset == null) {
    180             throw new IllegalArgumentException("Asset must be non-null");
    181         }
    182 
    183         InputStream assetInputStream = Wearable.DataApi.getFdForAsset(
    184                 apiClient, asset).await().getInputStream();
    185 
    186         if (assetInputStream == null) {
    187             Log.w(TAG, "Requested an unknown Asset.");
    188             return null;
    189         }
    190         return BitmapFactory.decodeStream(assetInputStream);
    191     }
    192 
    193     @Override
    194     public void onMessageReceived(MessageEvent event) {
    195         LOGD(TAG, "onMessageReceived: " + event);
    196         generateEvent("Message", event.toString());
    197     }
    198 
    199     @Override
    200     public void onPeerConnected(Node node) {
    201         generateEvent("Node Connected", node.getId());
    202     }
    203 
    204     @Override
    205     public void onPeerDisconnected(Node node) {
    206         generateEvent("Node Disconnected", node.getId());
    207     }
    208 
    209     private static class DataItemAdapter extends ArrayAdapter<Event> {
    210 
    211         private final Context mContext;
    212 
    213         public DataItemAdapter(Context context, int unusedResource) {
    214             super(context, unusedResource);
    215             mContext = context;
    216         }
    217 
    218         @Override
    219         public View getView(int position, View convertView, ViewGroup parent) {
    220             ViewHolder holder;
    221             if (convertView == null) {
    222                 holder = new ViewHolder();
    223                 LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
    224                         Context.LAYOUT_INFLATER_SERVICE);
    225                 convertView = inflater.inflate(android.R.layout.two_line_list_item, null);
    226                 convertView.setTag(holder);
    227                 holder.text1 = (TextView) convertView.findViewById(android.R.id.text1);
    228                 holder.text2 = (TextView) convertView.findViewById(android.R.id.text2);
    229             } else {
    230                 holder = (ViewHolder) convertView.getTag();
    231             }
    232             Event event = getItem(position);
    233             holder.text1.setText(event.title);
    234             holder.text2.setText(event.text);
    235             return convertView;
    236         }
    237 
    238         private class ViewHolder {
    239 
    240             TextView text1;
    241             TextView text2;
    242         }
    243     }
    244 
    245     private class Event {
    246 
    247         String title;
    248         String text;
    249 
    250         public Event(String title, String text) {
    251             this.title = title;
    252             this.text = text;
    253         }
    254     }
    255 }
    256