Tag Archives: Mobile Development

IoT Course Week 8: Intro to Mobile Development

Internet of Things Course

For a change of pace, we are taking a step back from the cloud -> server model we have been working so diligently on, and instead turn our eyes towards mobile. As more and more people around the world enter the global smartphone market, the Internet of Things space is becoming increasingly reliant on smartphone interfaces to control connected devices. This is because the components native to the smartphones that many of us carry, are simple and effective media of interaction with the connected world around us.

The Mission

The goals of week 8 are to provide an introductory course on modern mobile development, in both native iOS with Objective-C and native Android in Java. This week will set up a user interface to control the LAMPi, which next week, will be extended to operate over Bluetooth.

iOS

While the students were almost equally divided on Android/iOS, most of the students utilized Mac laptops, so we made the pairs heterogeneous as each pair had to build the app for both platforms.  This is necessary due to restrictions that Apple places on its developers, where software meant to run on the iOS platform must be developed on a machine running some recent version of OSX. Students were led through the creation of a project in Xcode, and some initial configuration that Apple requires developers to follow in order to sign and run their code. Students used Xcode to create a single view project, and they got to work.

Working in Interface Builder and a UIViewController, students were guided through adding and connecting a UISlider and UILabel to an IBOutlet.

“`

#import <UIKit/UIKit.h>

@interface LampiViewController : UIViewController

@property (nonatomic, strong) IBOutlet UISlider *slider;

@property (nonatomic, strong) IBOutlet UILabel *label;

-(void)onSliderChanged:(UISlider*)sender;

@end

“`

“`

#import “LampiViewController.h”

@interface LampiViewController ()

@end

@implementation LampiViewController

– (void)viewDidLoad {

   [super viewDidLoad];

   NSLog(@”slider: %@ \n label: %@”, self.slider, self.label);

}

-(void)onSliderChanged:(UISlider*)sender {

   NSLog(@”slider changed”);

}

@end

“`

A this point, a slider appeared on the screen that could be interacted with to update the label.  However a problem existed when the screen was rotated on its side.

Screen Shot 2016-04-05 at 9.36.44 AM

As can be seen, the slider and logo fail to expand out when the screen changes. This can quickly be remedied by utilizing one of the much loved nuances of Xcode’s Interface Builder, which is defining constraints on the views.pin_image

And once applied, everything came together. As can be seen here, the iOS Simulator is capable of fluid rotation from portrait to landscape, without any upsetting of the slider position.

with_constraints

Android

Android development, unlike iOS development, is capable of running on a much larger swath of machines. Since its introduction, Google’s Android has been open sourced and designed to run on the Java Virtual Machine (JVM).

Students began by downloading Android Studio and the latest Android SDK Tools. Using the Android Studio Interface, students created a new Android Studio project, allowing the template to be generated for a blank activity. Android Studio wants to get developers started quickly. They offer some shims that help this process. Because our project will be full of custom layouts and widgets, choosing a blank activity is the ideal scenario. After all was said and done, students were left with an application containing one activity.shim_project

Students were given a custom UI Widget in order to define a consistent slider for the class to use. The slider was added to the created activity layout in the XML here:

“`

<?xml version=”1.0″ encoding=”utf-8″?>

<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”

   xmlns:tools=”http://schemas.android.com/tools”

   android:layout_width=”match_parent”

   android:layout_height=”match_parent”

   android:paddingTop=”@dimen/activity_vertical_margin”

   tools:context=”.Lampi”>

 

   <View

       android:id=”@+id/bar”

       android:layout_width=”match_parent”

       android:layout_height=”10dp”

       android:layout_alignParentLeft=”true”

       android:layout_alignParentTop=”true” />

 

   <com.leandog.widgets.hsv.sliders.HueSliderView

       android:id=”@+id/hue_slider”

       android:layout_width=”match_parent”

       android:layout_height=”wrap_content”

       android:layout_alignParentLeft=”true”

       android:layout_alignParentTop=”true” />

</RelativeLayout>

“`

and when rendered by the running application it looked like this:

hue_slider_example

An event listener is added to the HueSlider, which tells a changeColor to run whenever the slider is interacted with.  It also allows the slider to initialize to a certain position or color, which will be useful when starting and restarting the LAMPi appication.

“`

package com.leandog.lampi;

 

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

 

import com.leandog.widgets.hsv.sliders.HueSliderView;

import com.leandog.widgets.hsv.sliders.OnSliderEventListener;

 

public class Lampi extends AppCompatActivity {

 

   HueSliderView hueSliderView;

   View bar;

 

   @Override

   protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_lampi);

       bar = findViewById(R.id.bar);

       setupHueSlider();

   }

 

   private void changeColor(int color) {

       bar.setBackgroundColor(color);

   }

 

   private void setupHueSlider() {

       hueSliderView = (HueSliderView) findViewById(R.id.hue_slider);

 

       hueSliderView.setOnSliderEventListener(new OnSliderEventListener() {

           @Override

           public void onChange(int color) {

               changeColor(color);

           }

 

           @Override

           public void onSliderInitialized() {

               changeColor(hueSliderView.getHue());

           }

       });

   }

}

“`

Where we end up

The homework for this week was to follow the patterns of user interface and code interaction just demonstrated, and build a fully operational user interface for both iOS and Android. These user interfaces will essentially mirror that which we have already built on both the LAMPi screen, and the web interface.

iOS Simulator screen capture:

ios_assignment

Android Emulator screen capture:

android_assignment

What is next!

Next week we will add the bluetooth functionality that connects our devices directly to the bluetooth hardware running on the Raspberry Pi controlled LAMPi.  For the sake of brevity and focus, from this point onward, mobile development will be done primarily on the iOS platform.