Android Wear Demo App

Introduction

I am going to reuse the sample code developed by “Martin Knudsen”. The entire credit for developing the application goes to Martin Knudsen.

This project is about Today’s menu, the author developed this one as a learning material for students.

The sample project utilizes some of the most commonly used Android Wear components. So it’s always good to have some understanding about android widgets such as BoxInsetLayout, WearableListView, FrameLayout, LinearLayout etc.

TodayMenu shows screen in four fragments, the main fragment shows the list of choices which is nothing but food items. The second one shows the statistics of the selected food items. The third one accepts or takes in a voice input nothing but a food item name and temporarily saves in SQLite database. The last fragment shows two buttons, one to reset the statistics and the other to rest food choices.

Please take a look into the following link to have some understanding about Android Wear

TodayMenu Application UI

Before we dig into the TodayMenu application functionality, let us take a quick look into the application UI screens.

TodayMenu Application UI

Database custom class

We have a class name Database which extends itself from SQLiteOpenHelper. There are two methods that we are overriding i.e onCreate and onUpdate. The following is the code snippet of onCreateoverride. We are executing SQL script to create tables for menu and choices.

  1. @Override  
  2. public void onCreate(SQLiteDatabase db) {  
  3.    db.execSQL("CREATE TABLE menu ( id INTEGER PRIMARY KEY AUTOINCREMENT," +  
  4.          "name TEXT, weekday INTEGER);");  
  5.    db.execSQL("CREATE TABLE choices ( id INTEGER PRIMARY KEY AUTOINCREMENT," +  
  6.          "name TEXT);");               
  7. }  
Here’s the code snippet for onUpgrade override. If the old version was 1 and the new version is 2, then we are executing a SQL script to create new table for user defined choices. The onUpgrade gets executed based on the app version. If you want to add functionality for your application which requires database changes, here’s the place where you can handle.
  1. @Override  
  2. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
  3.    if (oldVersion==1 && newVersion==2)  
  4.       db.execSQL("CREATE TABLE choices ( id INTEGER PRIMARY KEY AUTOINCREMENT," +  
  5.          "name TEXT);");  
  6. }  
This class ‘Database’ has few other methods that deal with reading choices, adding food, etc. We will soon take a look into those.

MainActivity XML and Code

Now let us take a look into the main activity xml and the associated code. Below is the code snippet of the activity.xml. You can notice a BoxInsetLayout is being used so the same UI can be displayed on rounded or square watches. It composes GridViewPager and DotsPageIndicator.
  1. <android.support.wearable.view.BoxInsetLayout  
  2.     xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_height="match_parent"  
  4.     android:layout_width="match_parent">  
  5.   
  6.     <!-- This is the gridviewpager, it makes sure we can swipe between different views -->  
  7.    <android.support.wearable.view.GridViewPager  
  8.     xmlns:android="http://schemas.android.com/apk/res/android"  
  9.     android:id="@+id/pager"  
  10.     android:layout_width="match_parent"  
  11.     android:layout_height="match_parent" />  
  12.   
  13.     <!-- This is the DotsPageIndicator, it makes sure we can use the small  
  14.     dots on the bottom of the screen to indicate the current page of the app is displayed -->  
  15.   
  16.     <android.support.wearable.view.DotsPageIndicator  
  17.         android:id="@+id/page_indicator"  
  18.         android:layout_width="wrap_content"  
  19.         android:layout_height="wrap_content"  
  20.         android:layout_gravity="center_horizontal|bottom">  
  21.     </android.support.wearable.view.DotsPageIndicator>  
  22.      
  23. </android.support.wearable.view.BoxInsetLayout>  
The following is the code snippet of main activity onCreate override. We will be digging in to understand how the GridViewPager is being set with the data. You can see below, how a SampleGridPagerAdapter instance is set to the activity GridViewPager. Also the DotsPageIndicator is set with the pager instance so it gives a visual feedback on the fragment the user is in. 
  1. @Override  
  2. protected void onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     setContentView(R.layout.activity);  
  5.   
  6.     final Resources res = getResources();  
  7.      final GridViewPager pager = (GridViewPager) findViewById(R.id.pager);  
  8.      pager.setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListener() {  
  9.             @Override  
  10.             public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {  
  11.                 final boolean round = insets.isRound();  
  12.                 int rowMargin = res.getDimensionPixelOffset(R.dimen.page_row_margin);  
  13.                 int colMargin = res.getDimensionPixelOffset(round ?  
  14.                         R.dimen.page_column_margin_round : R.dimen.page_column_margin);  
  15.                 pager.setPageMargins(rowMargin, colMargin);  
  16.                 pager.onApplyWindowInsets(insets);  
  17.                 return insets;  
  18.             }  
  19.         });  
  20.   
  21.      pager.setAdapter(new SampleGridPagerAdapter(this, getFragmentManager()));  
  22.      pagerGlobal = pager;  
  23.      DotsPageIndicator dotsPageIndicator = (DotsPageIndicator) findViewById(R.id.page_indicator);  
  24.      dotsPageIndicator.setPager(pager);  
  25.      Database db = new Database(this);  
  26.      db.readChoices(); //when the app starts we need to read the choices from the database file  
  27. }  
Something interesting happens when the Main activity gets loaded. i.e. we also read choices. Here’s the code snippet which deals with reading choices and it’s within the Database class. Firstly, we issue a SELECT query to fetch all choices order by id. If the count is 0 which means there are no user input choices, so we will be looping through the choices list and insert into our choices table. Else, we are iterating over the choices, gather all of them and set the same to a static string array Choices.ELEMENTS.
  1. public String[] readChoices() {  
  2.   
  3.    SQLiteDatabase database = getReadableDatabase();  
  4.    Cursor cursor = database.rawQuery("SELECT name FROM choices ORDER BY id",null);  
  5.    int count = cursor.getCount();  
  6.   
  7.    if (count==0//there is nothing, so first time we start the app.  
  8.    {  
  9.          for (String choice : Choices.ELEMENTS_RESET)  
  10.          database.execSQL("INSERT INTO choices (name) VALUES ('"+choice+"')");  
  11.          Choices.ELEMENTS = new String[Choices.ELEMENTS_RESET.length];  
  12.          System.arraycopy(Choices.ELEMENTS_RESET, 0, Choices.ELEMENTS, 0,   
  13.              Choices.ELEMENTS_RESET.length);  
  14.          cursor.close();  
  15.          return Choices.ELEMENTS_RESET; //we just have default values.  
  16.    }  
  17.    else  
  18.    {  
  19.       String[] elements = new String[count];  
  20.       int index = 0;  
  21.   
  22.       while (cursor.moveToNext())  
  23.       {                
  24.          elements[index] = cursor.getString(0);  
  25.          index++;  
  26.       }  
  27.   
  28.       Choices.ELEMENTS = elements;   //overwrite the elements array  
  29.       cursor.close();  
  30.       return elements;  
  31.    }  
  32. }  
Here’s the code snippet of Choices class. We have the initial list of choices and also the user defined or input choices.
  1. public class Choices {  
  2.    public static String[] ELEMENTS_RESET = { "Chicken""Beef""Pork""Lamb","Duck","Turkey" };  
  3.    public static String[] ELEMENTS;  
  4. }  
It’s time to have a look into SampleGridPagerAdapter logic. It’s a custom class extends itself from FragmentGridPagerAdapter. The following is the code snippet for the same. As of now, we are dealing with four fragments. Within the constructor, we create a new instance of each of the fragments that we are going to display on a GridViewPager. There’s an override method getFragment that you can see below returns the fragment instance based on the column. As and when the user swipes from left to right, these fragments get displayed on the wearable device.

GridViewPager Adaper

The following is the code snippet of GridViewPager Adapter.
  1. public class SampleGridPagerAdapter extends FragmentGridPagerAdapter {  
  2.   
  3.     MenuFragment menuFragment;  
  4.     ClearFragment clearFragment;  
  5.     StatsFragment statsFragment;  
  6.     SpeechFragment speechFragment;  
  7.   
  8.     public SpeechFragment getSpeechFragment()  
  9.     {  
  10.        return speechFragment;  
  11.     }  
  12.       
  13.     public ClearFragment getClearFragment()  
  14.     {  
  15.        return clearFragment;  
  16.     }  
  17.       
  18.     public StatsFragment getStatsFragment()  
  19.     {  
  20.        return statsFragment;  
  21.     }  
  22.       
  23.     public MenuFragment getMenuFragment()  
  24.     {  
  25.        return menuFragment;  
  26.     }  
  27.   
  28.     public SampleGridPagerAdapter(Context ctx, FragmentManager fm) {  
  29.         super(fm);  
  30.         menuFragment = new MenuFragment();  
  31.         clearFragment = new ClearFragment();  
  32.         statsFragment = new StatsFragment();  
  33.         statsFragment.setContext(ctx); //we need the context in this class  
  34.         speechFragment = new SpeechFragment();  
  35.     }  
  36.   
  37.     public void notifyStatsSetChanged() {  
  38.         statsFragment.updateUI();  
  39.     }  
  40.   
  41.     public void listViewDataSetChanged()  {  
  42.        menuFragment.resetList();  
  43.     }  
  44.       
  45.   
  46.     @Override  
  47.     public Fragment getFragment(int row, int col) {  
  48.         if (col==0)  
  49.            return menuFragment;    
  50.         else if (col==1)  
  51.            return statsFragment;   
  52.         else if (col==2)  
  53.            return speechFragment;  
  54.         else   
  55.            return clearFragment;  
  56.     }  
  57.   
  58.     @Override  
  59.     public int getRowCount() {  
  60.        return 1;  //we just have 1 row of pages, meaning scrolling horizontally  
  61.     }  
  62.   
  63.     @Override  
  64.     public int getColumnCount(int rowNum) {  
  65.        return 4//we just have 4 columns - fixed in this app.  
  66.     }  
  67. }  
Let us now dig into each of the above fragments to understand more about the inner working. The following is the code snippet of MenuFragment which extends itself from Fragment and implements WearableListView.ClickListener. The onCreateView override has a code to inflate the layout so we can fine the WearableListView and set its adapter with the list of choices.

Menu Fragment

Here's the code snippet of Menu fragment.
  1. public class MenuFragment extends Fragment implements WearableListView.ClickListener {  
  2.      
  3.    WearableListView listView;  
  4.      
  5.     @Override  
  6.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  7.             Bundle savedInstanceState) {  
  8.        View view = inflater.inflate(R.layout.select, container, false);  
  9.          
  10.       listView =(WearableListView) view.findViewById(R.id.wearable_list);  
  11.               
  12.       if (listView!=null)  
  13.       {  
  14.          listView.setAdapter(new Adapter(getActivity().getApplicationContext(), Choices.ELEMENTS));  
  15.          // Set a click listener - using this activity  
  16.          listView.setClickListener(this);  
  17.          listView.setGreedyTouchMode(true);  
  18.       }  
  19.        return view;  
  20.     }  
  21.        ….  
  22. }       
The following is the snapshot of the “TodayMenu” app main screen. You can see below its showing up the Menu fragment containing a ListView.

Menu Fragment

Here’s the code snippet where we are handing the wearable listview onClick event. 
  1. Firstly, we need to get the index of the selected listview item, we are obtaining the same from a “Tag” object coming next, you will see details on how we set the tag.

  2. Get the food choice based on the tag value.

  3. Create an instance of Database class and make a call to addFood so we can save our choice.

  4. An Intent instance is created to show a success confirmation to the user.

  5. In the end, we are going to update the stats fragment UI so when the user navigates, she/he can see the updated statistics of the choices the user has selected. 
  1. @Override  
  2. public void onClick(WearableListView.ViewHolder v) {  
  3.    Integer tag = (Integer) v.itemView.getTag();  
  4.    int index = tag.intValue();  
  5.      
  6.    String chosen = Choices.ELEMENTS[index];  
  7.    Database db = new Database(getActivity());  
  8.    db.addFood(chosen);  
  9.   
  10.    Intent intent = new Intent(getActivity().getApplicationContext(), ConfirmationActivity.class);  
  11.    intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE,  
  12.                    ConfirmationActivity.SUCCESS_ANIMATION);  
  13.    intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE,getResources()  
  14.          .getString(R.string.saved)+" "+chosen);  
  15.    startActivity(intent);  
  16.    ((SampleGridPagerAdapter) MainActivity.getPager().getAdapter()).notifyStatsSetChanged();  
  17. }  
Menu Fragment ListView binding

The following is the code snippet of Menu fragment list view adapter. The adapter takes two parameters, one is the context and the other is a dataset instance. The dataset has all the list of choices to be displayed. There are two main overrides that we need to take care of i.e onCreateViewHolder and onBindViewHolder.

Within the onCreateViewHolder method, all we have to do is return an instance of WearableListView.ViewHolder.

Create a new instance of ItemViewHolder with the view. A LayoutInflator instance is used to inflate the layout R.layout.list_item. The onBindViewHolder method internally gets called where we get the ViewHolder instance and then get the TextView so that we can set appropriate text from the dataset by position. Also you can notice we are making a call to set the tag object with the position value so we can use the same in onClick event. This is done so we can get the right choice and save in database.
  1. private static final class Adapter extends WearableListView.Adapter {  
  2.     private String[] mDataset;  
  3.     private final Context mContext;  
  4.     private final LayoutInflater mInflater;  
  5.   
  6.     public Adapter(Context context, String[] dataset) {  
  7.         mContext = context;  
  8.         mInflater = LayoutInflater.from(context);  
  9.         mDataset = dataset;  
  10.     }  
  11.   
  12.     public static class ItemViewHolder extends WearableListView.ViewHolder {  
  13.         private TextView textView;  
  14.         public ItemViewHolder(View itemView) {  
  15.             super(itemView);  
  16.             textView = (TextView) itemView.findViewById(R.id.name);  
  17.         }  
  18.     }  
  19.   
  20.     @Override  
  21.     public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent,  
  22.                                                           int viewType) {  
  23.         return new ItemViewHolder(mInflater.inflate(R.layout.list_item, null));  
  24.     }  
  25.   
  26.     @Override  
  27.     public void onBindViewHolder(WearableListView.ViewHolder holder,  
  28.                                  int position) {  
  29.         ItemViewHolder itemHolder = (ItemViewHolder) holder;  
  30.         TextView view = itemHolder.textView;  
  31.         view.setText(mDataset[position]);  
  32.         holder.itemView.setTag(position);  
  33.     }  
  34.   
  35.     @Override  
  36.     public int getItemCount() {  
  37.         return mDataset.length;  
  38.     }  
  39. }  
Main Fragment Resetting choice list

Now let us see how to reset the list of choices. The following is the code snippet for the same. First we need to get the choice length and copy all the choices temporarily into a string array so we can reset the Choices.ELEMENTS and the ListView component by setting the adapter and refreshing the same by making a call to invalidate method.
  1. public void resetList() {  
  2.    int len = Choices.ELEMENTS_RESET.length;  
  3.    String[] newElements = new String[len];  
  4.    System.arraycopy(Choices.ELEMENTS_RESET, 0, newElements, 0, len);  
  5.    Choices.ELEMENTS = newElements;  
  6.    listView.setAdapter(new Adapter(getActivity().getApplicationContext(), Choices.ELEMENTS));  
  7.    listView.invalidate();  
  8. }  
Statistics Fragment

Now let us take a look into the StatsFragment, where it shows the detailed statistics about the food choices the user chooses. The following is the partial code snippet of StatsFragment. We are making use of a LinearLayout where we have one TextView with a text set to “Statistics”. Coming next you will see how we are adding one more TextView component to LinearLayout so that we can show the real statistics to user.
  1. <LinearLayout   
  2.     android:layout_height="wrap_content"  
  3.     android:layout_width="wrap_content"  
  4.     android:layout_gravity="center"  
  5.     android:orientation="vertical"  
  6.     android:id="@+id/statslayout">  
  7.   
  8. <TextView   
  9. android:layout_height="wrap_content"  
  10.     android:layout_width="wrap_content"   
  11.     android:gravity="center_horizontal"  
  12.     android:textSize="24sp"  
  13.     android:layout_gravity="center_horizontal"  
  14.     android:textColor="@color/blue"  
  15.     android:text="@string/statistics"/>  
  16. </LinearLayout>  
Here’s the snapshot of the statistics fragment.

Statistics Fragment

Updating Statistics UI

It’s time to see how the statistics information is being shown to the user. Within the StatsFragment onCreate override, we are making a call to update the UI. The following is the code snippet for the same. Here’s what we do. 
  1. Create an instance of Database and get the latest statistics from SQLite DB. Hold the same in ArrayList of Item type.

  2. Get the child count for the LinearLayout instance so that we can remove and add a view so the user can see the up to date refreshed view.

  3. The next few set of lines, we are looping through all the statistics; create a TextView instance and then set text, color, font, etc. and add the same to LinearLayout instance. 
  1. public void updateUI() {  
  2.    Database db = new Database(context);  
  3.    ArrayList<Item> items = db.getStats();  
  4.    Collections.sort(items); //items are now sorted according to the frequency  
  5.    
  6.    int children = parent.getChildCount();  
  7.    if (children>1//do we have more than the "statistics" label, then remove them  
  8.    {  
  9.       parent.removeViews(1, children-1);  
  10.    }  
  11.   
  12.    for (Item item : items) {  
  13.       TextView text = new TextView(getActivity());  
  14.         
  15.       String p = String.format("%.1f", item.getPercent());  
  16.       text.setText(item.getName() + " : "+item.getFreq()+ " ("+p+" %)");  
  17.       text.setTextColor(Color.WHITE);  
  18.       text.setTextSize(22);  
  19.       text.setLayoutParams(new LayoutParams(  
  20.               LayoutParams.WRAP_CONTENT,  
  21.               LayoutParams.WRAP_CONTENT));  
  22.       parent.addView(text); //add the textview to the layout.  
  23.    }  
  24. }  
Speech Fragment

Let us take a look into the speech fragment and see the inner workings. The speech being highly important part of Android wear, the main functionality of this fragment being, accept new speech input from user and save the same as choices. The Speech fragment implements onClickListener, so it can handle user click. Here’s the code snippet for onCreateView override.

Within the onCreateView, first we get the view instance by inflating the speech layout. So we can find speech and add item buttons and attach onClick events for the same. Also do not forget to reset the textinput.
  1. @Override  
  2. public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  3.           Bundle savedInstanceState) {  
  4.    View view = inflater.inflate(R.layout.speech, container, false);  
  5.    Button button = (Button) view.findViewById(R.id.speechButton);  
  6.    button.setOnClickListener(this);  
  7.    button = (Button) view.findViewById(R.id.addItemButton);  
  8.    button.setOnClickListener(this);  
  9.    textView = (TextView) view.findViewById(R.id.speechText);  
  10.    textInput = "";  
  11.    return view;  
  12. }  
Here’s the snapshot of the speech fragment.

Input new item

Handling the Speech Fragment onClick event

Let’s see how to handle the onClick event for speech and add item buttons. Here’s the code snippet where a call to displaySpeechRecognizer method is made to start the speech recognizer to accept the voice input.
  1. @Override  
  2. public void onClick(View v) {  
  3.    if (v.getId()==R.id.speechButton) {  
  4.       displaySpeechRecognizer();  
  5.    }  
  6.    else if (v.getId()==R.id.addItemButton) {  
  7.       if (textInput.length()>0)  
  8.          addData();  
  9.       else {  
  10.          Toast toast = Toast.makeText(getActivity().getApplicationContext(),  
  11.                        "No input to add",Toast.LENGTH_LONG);  
  12.          toast.show();;  
  13.       }  
  14.    }  
  15. }  
Here’s the code snippet for displaying the speech recognizer. We have to create an Intent instance with the appropriate Intent action so the activity can be started with the intent and speech code.
  1. private void displaySpeechRecognizer() {  
  2.     Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);  
  3.     intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,  
  4.             RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);  
  5.     startActivityForResult(intent, SPEECH_CODE);  
  6. }  
The next important thing after receiving the voice input is to add the input text. Here’s the code snippet for the same. First we show a confirmation screen by making use of an Intent but we add the textinput through MenuFragment.

Please note - Adding a new choice can be done within the speech fragment itself. But we should not forget to refresh the MenuFragment ListView UI.
  1. public void addData() {  
  2.    Intent intent = new Intent(getActivity(), ConfirmationActivity.class);  
  3.    intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE,  
  4.                       ConfirmationActivity.SUCCESS_ANIMATION);  
  5.    intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE,getResources()  
  6.                      .getString(R.string.choiceAdded));  
  7.    startActivity(intent);  
  8.    MenuFragment frag = ((SampleGridPagerAdapter) MainActivity.getPager()  
  9.                        .getAdapter()).getMenuFragment();  
  10.    frag.addData(textInput);  
  11. }  
Clear Fragment

The Clear Fragment is the final or last fragment that gets displayed on the GridViewPager. It extends from a Fragment class and implements OnClickListener. The following is the code snippet ofonCreateView method override, where you can see we are setting the onClickListerner to handle the user click.
  1. @Override  
  2. public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  3.         Bundle savedInstanceState) {  
  4.    View view = inflater.inflate(R.layout.clear, container, false);  
  5.   
  6.    Button button = (Button) view.findViewById(R.id.clearDataButton);  
  7.    button.setOnClickListener(this);  
  8.    button = (Button) view.findViewById(R.id.clearChoicesButton);  
  9.    button.setOnClickListener(this);  
  10.      
  11.    return view;  
  12. }  
Here’s the snapshot of the clear fragment.

Clear Fragment

It’s time to take a look into the onClick override and try to understand how we are actually handling the Clear Data and Clear Choices button click. On each of the button clicks, we are showing a custom dialog so the user can take suitable action.

MyDialogFragment is a custom class extends itself from DiaglogFragment and overrides onCreateDialog. It has two methods named positiveClick and negativeClick with no implementation and allows one to override. Below you can see how we handle the positiveClick method to clear data by making a call to clearData method.
  1. @Override  
  2. public void onClick(View v) {  
  3.    if (v.getId()==R.id.clearDataButton) {  
  4.       MyDialogFragment dialog = new MyDialogFragment() {  
  5.          @Override  
  6.          protected void positiveClick() {  
  7.             super.positiveClick();  
  8.             clearData();  
  9.          }  
  10.   
  11.          @Override  
  12.          protected void negativeClick() {  
  13.             super.negativeClick();  
  14.          }  
  15.       };  
  16.       Bundle bundle = new Bundle();  
  17.       bundle.putString("title",getResources().getString(R.string.deleteStatsTitle));  
  18.       bundle.putString("message",getResources().getString(R.string.deleteStatsMessage));  
  19.       dialog.setArguments(bundle);  
  20.       dialog.show(this.getFragmentManager(),"test"); //test is just a tag - not shown to the user  
  21.    }  
  22.    else if (v.getId()==R.id.clearChoicesButton) {  
  23.       DialogFragment newFragment = MyWearDialog.newInstance();  
  24.       newFragment.show(getFragmentManager(), "dialog");  
  25.    }  
  26. }  
It’s time to see the clearData code and understand the code behind. In Database class, we have an implementation to clear the menu items and then we show a confirmation activity with the success animation.

Finally there is one important thing we need to do, that is – Notify the SampleGridPagerAdapter by making a call to notifyStatsSetChanged method on its adapter.
  1. public void clearData() {  
  2.     Database db = new Database(getActivity());  
  3.     db.clearData();  
  4.     db.close();  
  5.   
  6.     Intent intent = new Intent(getActivity(), ConfirmationActivity.class);  
  7.     intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE,  
  8.                    ConfirmationActivity.SUCCESS_ANIMATION);  
  9.     intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE,  
  10.           getResources().getString(R.string.statsDeleted));  
  11.     startActivity(intent);  
  12.     ((SampleGridPagerAdapter) MainActivity.getPager().getAdapter()).notifyStatsSetChanged();  
  13. }  
Now let us see how we handle the clear choices button click event. On clear choices button click, you can see there is a code to show a DialogFragment. We are making use of MyWearDialog, which is nothing but a custom dialog fragment as it extends itself from a DiaglogFragment. Here’s the code snippet of MyWearDialog which handles the “OK” and “Cancel” button click events. You can see below the cancel just dismisses the dialog. On click of ‘OK’ button make a call to clearChoices which makes use of Database instance to clear all choices.

Please note – After clearing choices, one should never forget to refresh the GridViewPager by notifying the same.
  1. @Override  
  2. public void onClick(View v) {  
  3.     if (v.getId()==R.id.cancel_btn) {  
  4.         dismiss(); //just do nothing  
  5.     }  
  6.     else if (v.getId()==R.id.ok_btn) {  
  7.         clearChoices();//do something  
  8.         dismiss(); //then dismiss  
  9.     }  
  10. }  
  11.   
  12. public void clearChoices() {  
  13.     Database db = new Database(getActivity());  
  14.     db.clearChoices();  
  15.     db.close();  
  16.    
  17.     ((SampleGridPagerAdapter)MainActivity.getPager().getAdapter()).listViewDataSetChanged();  
  18.   
  19.     Intent intent = new Intent(getActivity(), ConfirmationActivity.class);  
  20.     intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE,  
  21.             ConfirmationActivity.SUCCESS_ANIMATION);  
  22.     intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE,getResources()  
  23.           .getString(R.string.choicesDeleted));  
  24.     startActivity(intent);  
  25. }  
Debugging on Smartwatch

Please take a look into the following article to know more about how to debug apps on wearables. 

References

This article uses code sample developed by "Maritn Knudsen". Feel free to take a look into the following Github link. All attribution to the author is made starting from the beginning of the article.


Similar Articles