Tuesday, August 28, 2012

Spotify search with JQuery Mobile

I want to broaden my skills set of mobile development. Since 2 years I have been involved in Android development, now I want to get involved in a cross-platform solution using Javascript, Html and CSS. 

JQuery Mobile

During my time at KHLeuven I have written a lot of Javascript code but since my graduation i have written none. So I believed it was time to refresh my javascript by experimenting with JQuery mobile. I wanted to create a simple search application that uses an online datasource to fill in a ListView.

Spotify

I chose Spotify as an online datasource since it uses JSON as a data-interchange format and I have used it before in other projects. Another reason why I use Spotify is that the application can be used to invoke playing a new song on a spotify client.

PhoneGap

I have packaged the application using PhoneGap. By using PhoneGap the process of building a native app embedded with javascript is simplified.

Screenshots



Source Code

The code used in this demonstration isn't a good example of functional programming. I solely wanted to test out JQuery and not write a full application that is extensible. Only reuse the code by re-factoring it into functions and objects.
Link to source

Thursday, August 23, 2012

Configuration VLC web interface


In this tutorial we are going to cover the basics steps needed to config a VLC mediaplayer instance to accept connections over the local area network. This tutorial is created to help configure the VLCRemote application for Android.

Windows

This tutorial is created using Windows 7 and VLC 2.0.3

Step 1 of 5: show hidden files

We need to edit a configuration file of VLC, the .hosts file. This file is hidden so we first need to enable our Windows system to show hidden files and folders. This can be configured in the Control Panel:
Start > Control Panel > Search for Folder Options  > Enable "show hidden files,..  > Apply


Step 2 of 5: edit the .hosts file

Now we should be able to see the hidden files. We will be editing the .hosts file to helps configure VLC to allow or deny certain  IP-addresses. We need to edit this file with a text editor enhanced with administrator rights.
Texteditor > Right click > Run as Administrator


When the texteditor is open:
Menu > Open file > C:\Program Files\VideoLAN\VLC\lua\http\.hosts

Edit and save the file so the file looks like the following screenshot:
-> uncomment private addresses 


Step 3 of 5: enable the web interface

If you already have VLC mediaplayer opened on your computer, you should restart it so the new configuration can be loaded. When VLC is reopened you can continue to activate the web interface of the VLC mediaplayer. This is achieved by clicking on a menu item in the view tab.
Menu > View > Add interface > Web

Step 4 of 5: determine the IP-address of VLC-host

Our VLC mediaplayer is ready to accept connections. Before we can test the web interface we should determine the IP-address of the computer hosting the VLC instance. This can be achieved by using the ipconfig command in the commandprompt.
Start > search for "cmd" > open de cmd.exe
When cmd is opened > Type "ipconfig" > press enter


Step 5 of 5: test if the web interface is accessible 

Now that we have our IP-address. It's time to test the web interface. Open a browser and browse to a webpage constructed out the following format:
http://<ipaddres>:8080
If a page gets loaded you are set to start using the VLCRemote application. You only need to fill in the IP-address in the application and add some songs to the playlist.

I hope the how-to guide was helpfull. If not please leave a comment below.

Enjoy VLCRemote!

Wednesday, July 18, 2012

VLCRemote

version 0.2.7

The Ubuntu App Showdown deadline has passed. So the time has come to start a new project!
I teamed up with the same developer as the showdown competition, Lemaire NickLet's introduce the project by demonstrating some screenshots of the application in development.
Screenshot phone

VLC remote
Screenshot tablet




















During my internship at Philips iLab in Leuven, I had the chance to discover the development possibilities of the VLC-platform created by VideoLan. One of the possibilities is the usage of the web interface via Http protocol. By using the web interface of VLC, a developer can control a VLC-instance on the local area network by invoking simple http requests.

Current features:
  • Manuel connection wizard
  • Playback control (play, pause, loop, shuffle etc.)
  • Volume control
  • Dynamic playlist
  • Metadata processing
  • Dynamic preferences
Future features
  • Automatic connection wizard
  • Gestures control
Design:


Coming soon to the Google Playstore, just need to get my hands on a developers key!

Tuesday, July 10, 2012

Dynamic table in Quickly




When participating with a friend on the Ubuntu App Showdown, I realized that there aren't many tutorials and examples around regarding Ubuntu development with Quickly. So I got the idea to share some code I struggled with. I have extracted the necessarily code from my Quickly project to illustrate how clickable dynamic tables are constructed.

Glade

We need to create container to hold our table. For this I have chosen to use a  viewport inside a  scrolledwindow. In this example I'm using glade as an interface designer.
Open glade:

  • Terminal : path_to_project/project_folder/ quickly design

Add a viewport inside a scrolledwindow :

  • Drag & drop: scrolledwindow from the Containers-tab inside the vbox1 
  • Drag & drop: viewport from the Containers-tab inside the the scrolledwindow

  Dynamic table

A dynamic table construction of 2 elements:
A Tree view is constructed out of columns. Those columns hold CellRenderers. In this example we use 2 children classes of the CellRenderer class. The first one is the CellRenderText class which is used to display text. The second one is a custom implementation of a  CellRendererPixBuff . A CellRendererPixbuff is used to display an image. We needed to extend from CellRendererPixBuff so we could make the cell that holds an icon clickable (implement the clicked signal). 

Snippet Window.py

# IMPORTS USED IN THIS EXAMPLEfrom gi.repository import GdkPixbuffrom CellRendererIcon import CellRendererIcon        from gi.repository import Gtk         # MAIN CODE        # VIEWPORT CREATED WITH GLADE
      self.viewport = self.builder.get_object('viewport')

        # CREATE LISTSTORE & TREEVIEW
        self.liststore = Gtk.ListStore(str, str)
        self.treeview = Gtk.TreeView(self.liststore)

        # COLUMNS
        column_text = Gtk.TreeViewColumn("Name")
        column_text.set_expand(True)
        column_icon = Gtk.TreeViewColumn("Delete")
        column_icon.set_expand(False)
        
        # ADD COLUMNS
        self.treeview.append_column(column_text)
        self.treeview.append_column(column_icon)        
        
        # CREATE TEXTRENDERER
        cellrenderer_text = Gtk.CellRendererText()
        column_text.pack_start(cellrenderer_text, False)
        column_text.add_attribute(cellrenderer_text, "text", 0)
     
        # CREATE ICONRENDERER
        cellrenderer_icon = CellRendererIcon()
        column_icon.pack_start(cellrenderer_icon, False)
        column_icon.add_attribute(cellrenderer_icon, "stock-id", 1)

        # CONNECT SIGNALS FOR CALLBACK CLICK ON CELL
        cellrenderer_icon.connect('clicked', self.on_custom_function)
        
        # CONNECT LISTSTORE WITH TREEVIEW
        self.treeview.set_model(self.liststore)
        
        # FILL DATASET IN TABLE
        for row in dataset:
            self.liststore.append([row['name'], Gtk.STOCK_DELETE])
        
        # SHOW & ADD treeview to viewport
        self.treeview.show()   
        self.viewport.add(self.treeview)

Code CellRendererIcon.py

#!/usr/bin/python
# import needed for this project
from gi.repository import Gtk
from gi.repository import GObject

class CellRendererIcon(Gtk.CellRendererPixbuf):
     __gsignals__    = { 'clicked' : (GObject.SIGNAL_RUN_LAST,
                                      GObject.TYPE_NONE,
                                      (GObject.TYPE_STRING,)), }
 
     def __init__(self):
         Gtk.CellRendererPixbuf.__init__(self)
         self.set_property('mode', 1)
         self.set_property('follow-state', True)
 
     def do_activate(self, even, widget, path, background_area, cell_area, flags):
  self.emit('clicked', path)


Source


UPnP Android stack

In this tutorial I will try to cover the basics steps of implementing an UPnP control point in an Android application. By doing this we can discover/integrate/control UPnP devices in our local area network. This tutorial focuses on discovering one UPnP device, invoking a control event on this device and handeling the callback event coming from the device.

Final result

What is UPnP 

For a better understanding of what Universal Plug and Play is you shoud visit the websites Wikipedia  and UPnP.org.


Requirements

Eclipse + Android SDK

You should have a eclipse environment installed for Android development

UPnP Developer tools by intel

By using the developer tools delivered by intel, setting up and testing with the UPnP protocol isn't that dificult. To get started download the developer tools from the intel website:
Watch the following tutorials regarding the tools:

Tutorial

Control UPnP devices with developer tools

Now that we have had a simple introduction to UPnP-developer tools it's time to start working. First we need to start spying the network for UPnP-traffic. Device spy lists all UPnP enabled devices of your local area network. You can invoke events on these devices by opening an service in the treeview and double clicking an function (e.g. SetTarget). 

Open the Device Spy:
  • Start > Programs > Developer tools for UPnP technology > Device Spy

Create an UPnP-device

Open the Network Light:
  • Start > Programs > Developer tools for UPnP technology > Netwok Light

We are using the Network Light from the developer tools as our endpoint in this setup. Intel's Network Light is a virtual lightbulb that can be enabled, disabled and dimmed.Verify that the network light is listed in the device spy. Play around with the network light from the device spy, for example you can enable/disable the lightbulb by invoking the setTarget(True) and setTarget(False) function.

For more information on the Network Light module you can take a look at:
standardizeddcps/Lighting Controls_1/UPnP-ha-DimmableLight-v1-Device*.pdf


Generate the UPnP-stack for our application

Open Device Builder:
  • Start > Programs > Developer tools for UPnP technology > Device Builder
Do the following actions:

  • File > Open from network...
    • Select Network Light 
    • Click ok
  • Select Network Light in the main window
    • Open the Configuration tab
      • alter the Generation type to Control Point
  • File > Generate stack...
    • Change the following values to
      • Target Platform : Java Stack - Android
      • Project Name : LightSwitch
      • Output Path : C:\upnp
      • Package : be.tvn.dev.upnp.lightswitch
These actions will generate the source code of an Android application which developers can use to make their own Android applications.


Listing generated files

the following java files are generated in the package  "be.tvn.dev.upnp.lightswitch" :
  • - CpDimming.java 
    • Resembles the service : um:schemas-upnp-org:service:Dimming:1
  • - CpSwitchPower.java
    • Resembles the service :  um:schemas-upnp-org:service:SwitchPower:1
  • - LightSwitch.java
    • MainActivity of our Android project


Import the generated code into Eclipse

  • File > Import > General tab > Existing Projects into Workspace
    • Select upnp as your root directory
    • Verify that LightSwitch-project is checked
    • Click Finish


Resolve Eclipse errors

Move the UPnP library to the libs folder
  • Right click project > New > Folder > Folder name : libs
  • Copy and paste UPnPLibrary.jar from the root folfer to the libs folder
  • Verify that UPnPLibrary.jar is referenced
Remove @Override annotations
  • Ctrl + F and Replace All
Fix project properties
  • Right click project > Android Tools > Fix Project Properties
Clean project
  • Project > Clean...


Run your application

If all errors are removed from the package explorer it's time to start running the application. Before continuing we should enable WiFi on our Android phone and enable debug information on the Network Light.
  • Network Light > right click > Debug information
    • enable debug information by clicking the green/orange/red icons
  • Eclipse > right click project > Run as > Android Application
When the application is installed you should see 2 buttons on the screen. One for starting the NetworkLight server and one for stopping the NetworkLight server. If you press the start button you should see the following debug information appear in the debug dialog.




Adding functionality to the Android application

Now that we can integrate with the Network Light is time to start adding buttons to toggle the bulb on & off. To accomplish this we only need to edit 2 files:
  • main.xml
  • LightSwitch.java

Add a button to our main.xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
<Button android:text="Start Device" android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
<Button android:text="Stop Device" android:id="@+id/Button02" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
<Button android:text="Toggle on/off" android:id="@+id/lightswitch" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>

</LinearLayout>


Add new variables to our LightSwitch.java variables
public class LightSwitch extends Activity 
{
 
 private UPnPControlPoint mCP1;

 // BUTTON
 private Button toggleButton;
 
 // UPNP 
 private CpSwitchPower.InvokeHandler mCpSwitchPowerInvokeHandler;
 private CpSwitchPower mCpSwitchPower;
 private Object mCpSwitchPowerObject;

 ...

}
Reference button and add onClickListener to the button in onCreate-function
/** Called when the activity is first created. */
    
    public void onCreate(Bundle savedInstanceState) 
    {
        // ONCREATE AND CONTENTVIEW
        // START AND STOP BUTTONS
        ...
                
        // FIND REFERENCE TO BUTTON
        toggleButton = (Button)findViewById(R.id.lightswitch);
        
        // DISABLE BUTTON UNTIL INITIATED BY SERVICE
        toggleButton.setEnabled(false);
        
        // DEFINE ONCLICK EVENT
        toggleButton.setOnClickListener(new OnClickListener() {
   
    public void onClick(View v) {
        if((Boolean)v.getTag()){
        // lightbulb is on -> switch off
        mCpSwitchPower.action_SetTarget.Invoke(false, mCpSwitchPowerObject, mCpSwitchPowerInvokeHandler);
       }else{
        // lightbulb is off -> switch on
        mCpSwitchPower.action_SetTarget.Invoke(true, mCpSwitchPowerObject, mCpSwitchPowerInvokeHandler);
       }
       // DISABLE BUTTON UNTIL CALLBACK
             v.setEnabled(false);
    }
   });

    }



Change implementation of OnAddedDevice(UPnPDevice device)-function
       public void OnAddedDevice(UPnPDevice device)
       {
        //STORE REFERENCE OF INVOKE HANDLER
        mCpSwitchPowerInvokeHandler = mHandler_SwitchPower;
        
        // INITIATE SERVICE
           UPnPService service;
           service = device.GetService(CpSwitchPower.ServiceType).get(0);
           service.userObject = new CpSwitchPower(service);
           ((CpSwitchPower)service.userObject).LoadSCPD(null, new CpSwitchPower.LoadedSCPDHandler()
           {
   /** Called when service is initated */   
   public void OnCpSwitchPower_LoadedSCPD(CpSwitchPower sender,boolean success, Object userObject) {    
    // STORE REFERENCE TO UPNP OBJECTS
    mCpSwitchPower = sender;
    mCpSwitchPowerObject = userObject;
    // GET INITIAL STATE OF LIGHTBULB 
    mCpSwitchPower.action_GetTarget.Invoke(mCpSwitchPowerObject, mCpSwitchPowerInvokeHandler);
   }
           });
       }
Change implementation of mHandler_SwitchPower
CpSwitchPower.InvokeHandler mHandler_SwitchPower = new CpSwitchPower.InvokeHandler()
       {
           
           public void OnGetStatus(int errorCode, boolean ResultStatus, Object userState)
           {
           }
           
           public void OnGetTarget(int errorCode, boolean newTargetValue, Object userState)
           {
             final boolean value = newTargetValue;
             runOnUiThread(new Runnable() {
               public void run() {
                 // store state of lightbulb 
                 toggleButton.setTag(value);
                 // enable button
                 toggleButton.setEnabled(true);
               }
             });
           }
           
           public void OnSetTarget(int errorCode, Object userState)
           {
              runOnUiThread(new Runnable() { 
                public void run() {
                  // switch state of lightbulb
                  Boolean isOn = ((Boolean)toggleButton.getTag() == true) ? false : true;
                  // store state of lightbulb
                  toggleButton.setTag(isOn);
                  // enable button
                  toggleButton.setEnabled(true);
                }
              });
           }
       };

Resolve small errors and run application



Download


NOTES

  • This example doesn't handle error codes
    • Your application should manage error codes
  • This example mimics a situation with one particular UPnP-device.
    • Your application should have the possibility to manage more than one device
  • This example ignores the state of a service
    • Your application should manage state of services
    • Your application should check services before invoking functions
  • This example implements one of the two services available in the Network Light

Friday, July 6, 2012

LG Optimus 2X to ICS

I updated my Optimus 2X (gingerbread) phone to an Nova HD (ICS) version.
The Nova HD kernel is based of the CM9-rom.

Positive points:

  • Feels more responsive then the stock rom
  • Feels like a new phone
  • No more waiting for LG to come out with the update
  • Battery life seems to be same
Negative points
  • Chrome is lagging, not usable
  • Stock browser app sometimes closes
  • Stock camera app sometimes crashes
  • Cannot use video recording in stock camera app