Wednesday, May 15, 2013

Android - An example application

Summary

This article describes the android application, "CyNotify".  The application was made for learning, enjoy.  The source and application are available to use in any way that you want.  Use it, take it, learn from it, make it your own... etc..

Before we begin

The source for the application is available at:
https://github.com/ergobot/CyNotify

The application is available in the google play store at:
https://play.google.com/store/apps/details?id=edu.simpson.obryan.projects

What can I learn from the source?

  • Read SMS
  • Read phone contacts
  • Make notifications
  • Create Alarms (instead of using timers)
  • Cancel Alarms
  • Use Intent Service

 

What does it do?

The application reminds you about missed calls or missed text messages (SMS) at specific intervals. 

Example scenario

For example, you miss a call while in a meeting.  You see that you missed a call and think, "I really need to return that call but I'm in the middle of this meeting.  I'll get back to the missed call in 15 minutes."  Before you know it, an hour has passed and you forgot to return that call. 

Android only notifies you once that you have a missed call or new text message.

With CyNotify enabled, you'll always be reminded regularly when you forget about those missed calls or new text messages.

How does it work?

In short, we are setting system alarms and running an IntentService when the system alarms go off.  In the IntentService, we check for missed calls/new text messages and finanlly make notifications (if needed) to the user.

More specifically...
  • The application interacts with the user through one Activity.
  • There are two broadcast receivers to listen for device boot completed and system alarms (AlarmManager).
  • There are two IntentServices (fire and forget services) to do the work of setting an alarm after the device boot as well as performing the message changes/creating notifications

How did you make the icons? 

I used Inkscape, its free and works great.  http://inkscape.org/

The tutorial where I learned to use Inkscape to make android icons is:
http://tekeye.biz/2012/android-launcher-icons-using-inkscape

(Gimp is another good choice, http://www.gimp.org/ .  It is free and there is plenty of documentation. )

Take the icon you made and go to http://android-ui-utils.googlecode.com/hg/asset-studio/dist/icons-launcher.html .  Upload the icon you made in Inkscape (or gimp) and you will get all of the different sizes of icons you need. 


That is it!  This was a fun application to make and I learned a lot.  I hope the experience can help you. 



Monday, May 13, 2013

Android IOIO - Listen for Digital Input

Summary
This tutorial shows how to slightly modify the ioio lib in order to add a listener for digital input.
Description
At the very least, you're reading this because you want to do something when the value of your digital input changes.  This might even mean that you've tried to listen for the digital input changes by creating a new thread and use the blocking call Digitalinput.waitForValue().  This is one way but we can also go into the IOIOLib and add a listener.  Adding this listener to the pin is what this article is all about. 

Before we begin
This tutorial assumes you are somewhat familiar with your ioio, java, and android.   How familiar do you have to be to use the tutorial without problems?  Work with the ioio examples first or be able to read your targeted digital input before attempting this tutorial.

Steps

As an overview, we are going to make the following changes/additions to the IOIOLib:
  1. Add the abstract class, "Listener.java", to the package "ioio.lib.impl"
  2. Modify the abstract class, "DigitalInput.java", in the package "ioio.lib.api".  Adding the the abstract methods for the Listener.
  3. Modify the class, "DigitalInputImpl.java", in the package "ioio.lib.impl".  Add the implementation for the Listener, and call  "firePropertyChanged" at the start of "setValue"
  4. Create your DigitalInput in the Looper class
  5. Add the listener in the setup method of your looper class 

Step One



Add the abstract class, "Listener.java" to the package "ioio.lib.impl".
Create a new class named "Listener.java" inside of the package "ioio.lib.impl". 
In this class delete everything and the following:

package ioio.lib.impl;

import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;


public abstract class Listener {

    private final Set<String> properties;

    public Listener(String... properties) {
        Collections.addAll(this.properties = new TreeSet<String>(), properties);
    }

    protected final Set<String> getProperties() {
        return this.properties;
    }

    public abstract <T> void propertyChanged(final String property,
            final T oldValue, final T newValue);
}

See it on github at:
https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/impl/Listener.java



Step Two
Modify the abstract class, "DigitalInput.java", in the package "ioio.lib.api".  Adding the the abstract methods for the Listener.

To do this, find the file "DigitalInput.java" in the package "ioio.lib.api" and add the following (inside the class):
     // Custom
    public boolean addListener(final Listener x);
    public boolean removeListener(final Listener x);

See it on github at (lines 129 and 130):
https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/api/DigitalInput.java



Step Three
Modify the class, "DigitalInputImpl.java", in the package "ioio.lib.impl".  Add the implementation for the Listener, and call  "firePropertyChanged" at the start of "setValue".

Find the class "DigitalInputImpl.java" in the package "ioio.lib.impl" and add the following (inside the class):

    private final List<Listener> listeners = new LinkedList<Listener>();

    protected final <T> void firePropertyChanged(final String property,
            final T oldValue, final T newValue) {
        assert(property != null);
        if((oldValue != null && oldValue.equals(newValue))
                || (oldValue == null && newValue == null))
            return;
        for(final Listener listener : this.listeners) {
            try {
                if(listener.getProperties().contains(property))
                    //System.out.println("property changed");
                    listener.propertyChanged(property, oldValue, newValue);
            } catch(Exception ex) {
             System.out.println(ex.getMessage());
                // log these, to help debugging
                ex.printStackTrace();
            }
        }
    }

    @Override
    synchronized public final boolean addListener(final Listener x) {
        if(x == null) return false;
        return this.listeners.add(x);
    }

    @Override
    synchronized public final boolean removeListener(final Listener x) {
        return this.listeners.remove(x);
    }

See it on github at: https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/impl/DigitalInputImpl.java  (lines 107 through 135)

In this same class add the following inside of the method "setValue":

firePropertyChanged("value",value_,value);
See it on github at: https://github.com/ergobot/IOIOLib/blob/master/src/ioio/lib/impl/DigitalInputImpl.java  (line 55)



Step Four
Create your DigitalInput in the Looper class

I'm using the HelloIOIO project as the example.  Find where your looper class starts, and declare a DigitalInput named "exampleInput".  For this example, it is directly under the line "private DigitalOuput led_;".  The line we are adding looks like this:

private DigitalInput exampleInput;

See it on github at:
https://github.com/ergobot/HelloIOIO/blob/master/src/ioio/examples/hello/MainActivity.java
(line 47)



Step Five
Add the listener in the setup method of the looper class 

Note:  For the example, we are using pin 47.

Find your setup method in the looper class, and add the following:

            // Our digital input (the pin being used for this example is pin #47)
            exampleInput = ioio_.openDigitalInput(47);
           
            exampleInput.addListener(new ioio.lib.impl.Listener("value") {
                public <T> void propertyChanged(final String p, final T oldValue,
                final T newValue) {
                                           
                        // This is where you do what you want with the old or new value
                   
                        // Write to the logcat
                        Log.v("exampleInput", "exampleInput - " + System.nanoTime() +"  oldValue = " + ((Boolean) oldValue ? 0:1) + " : newValue = " + newValue);
               
                        // or another way to write it... print it out
                        System.out.println(p + " changed: " + oldValue + " to "    + newValue);
               
                }
                });

See it on github at: https://github.com/ergobot/HelloIOIO/blob/master/src/ioio/examples/hello/MainActivity.java (lines 64 to 79)


...and there it is!  Hope you helps you.  When searching, there wasn't a way to do this.  It may not be the best but take it and make it your own.  If you know of a better way, put it in the comments. 



Resources:

Original idea:
https://groups.google.com/d/msg/ioio-users/aROyaAVOhAQ/UVQHx5Lmh6kJ

Listener based on stackoverflow.com answer:
http://stackoverflow.com/questions/2822901/watching-a-variable-for-changes-without-polling

Eclipse IDE (from the adt-bundle)
     link - http://developer.android.com/sdk/index.html

HelloIOIO
     original - https://github.com/ytai/ioio/tree/master/software/applications/HelloIOIO
     modified -  https://github.com/ergobot/HelloIOIO

IOIOLib
     original - https://github.com/ytai/ioio/tree/master/software/IOIOLib 
     modified - https://github.com/ergobot/IOIOLib

IOIO Mint
     adafruit - http://www.adafruit.com/products/885