01 February, 2015

Setting Up Android For the Nth Time

Since I've been authoring Android apps, I've gone through numerous occasions of installing/re-installing/re-re-installing of the SDK and more recently AndroidStudio.  I've been a bit out of the loop, a bit of a hiatus from development but recently reacquainting with the SDK.

Start by downloading and extracting the SDK;

$ wget http://dl.google.com/android/android-sdk_r24.0.2-linux.tgz

$ tar -zxvf android-sdk_r24.0.2-linux.tgz


Append the locations of the new utilities to your Bash profile;


$ echo "export PATH=\$PATH:~/android-sdk-linux/tools" >> ~/.bashrc

$ echo "export PATH=\$PATH:~/android-sdk-linux/platform-tools" >> ~/.bashrc

The default install generally installs the latest APIs, but you can install additional ones;

$ android

Likely, if you've recently updated or reinstalled the Android SDK, you'll have to update the project XML files.  

The 'update project' command takes a numeric target id, listing the targets and 
find the appropriate id.

$ android list targets | grep id:
id: 1 or "android-7"
id: 2 or "android-8"
id: 3 or "android-21"
id: 4 or "Google Inc.:Google APIs:7"
id: 5 or "Google Inc.:Google APIs:8"
id: 6 or "Google Inc.:Google APIs:21"
The current API version is stored in the project.properties file within the project directory.


$ cat project.properties
.
.
target=Google Inc.:Google APIs:8
.
.

Updating the project to continue to use API 8 would therefore be done by;


$ android update project -p . -t 5

Get the list of devices available by issuing the following command;


$ adb devices
List of devices attached 
01aa7bcb8c8c07be device

$ adb -s 01aa7bcb8c8c07be install -r ./bin/Test01-debug-unaligned.apk


Whole buncha interesting stuff is available by examining the APK;

$ aapt dump badging ./bin/Test01-debug-unaligned.apk
package: name='com.abc.test01' versionCode='3' versionName='1.2' platformBuildVersionName=''
application-label:'Test01'
application-icon-160:'res/drawable/icon.png'
application: label='Test01' icon='res/drawable/icon.png'
application-debuggable
launchable-activity: name='com.abc.test01.Test01'  label='Test01' icon=''
uses-permission: name='android.permission.INTERNET'
uses-permission: name='android.permission.READ_PHONE_STATE'
uses-permission: name='android.permission.ACCESS_NETWORK_STATE'
sdkVersion:'7'
targetSdkVersion:'7'
feature-group: label=''
  uses-feature: name='android.hardware.screen.portrait'
  uses-implied-feature: name='android.hardware.screen.portrait' reason='one or more activities have specified a portrait orientation'
  uses-feature: name='android.hardware.touchscreen'
  uses-implied-feature: name='android.hardware.touchscreen' reason='default feature for all apps'
main
other-activities
supports-screens: 'small' 'normal' 'large'
supports-any-density: 'true'
locales: '--_--'
densities: '160'
That's all for now.  Cheers.






31 January, 2015

Android -- Introduction to Fragments (Part 2)

Building off our last example, we'll spend some time demonstrating how to introduce multiple fragments into a single activity.  Along the way, we'll pick up a little more knowledge on how the activities and fragment interaction with one another.

Let's start by extending the res/layout/main.xml to have two layouts as follows;


$ cat res/layout/main.xml 
<?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"
    >
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/container"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Hello World, FragTest01"
        />
    </LinearLayout>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/container2"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Hello World, FragTest02"
        />
    </LinearLayout>
</LinearLayout>

Notice we've duplicated the original linear layout (id=container) and identified the copy as container2.  In addition, both of these layouts have been contained within a parent layout, the layout_height attributes were modified to keep the first layout from using the full screen.

As you may recall, the activity FragTest01.java specifies adding an object of the MyFragment class into the desired container;


.
.
            getFragmentManager().beginTransaction()
                     .add(R.id.container, MyFragment.newInstance())
                     .commit();
.
.


If we extend on this call as follows we're left with creating two copies of the MyFragment fragment and placing into two independent containers.


.
.
            getFragmentManager().beginTransaction()
                     .add(R.id.container, MyFragment.newInstance())
                     .add(R.id.container2, MyFragment.newInstance())
                     .commit();
.
.



Ehh, not terribly interesting, two copies of the same fragment with the same layout.

We can now create specialized fragments, one for each layout.  We'll leave MyFragment.java/myfrag.xml in the top layout and create new elements MyFragment02.java/myfrag2.xml for the lower frame.

Duplicating res/layout/myfrag.xml, we simply change the text to demonstrate the difference from the original.

$ cat res/layout/myfrag2.xml 
<?xml version="1.0" encoding="utf-8"?>
   <LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="horizontal"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="#666666">
   <TextView
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="My Fragment Example 02"
   android:textColor="#000000"
   android:textSize="20px" />
</LinearLayout>

Similarly, we'll duplicate MyFragment.java for a new class, inflating from the new layout file.


$ cat src/com/fsk/example/FragTest01/MyFragment02.java

package com.fsk.example.FragTest01;

import android.os.Bundle;
import android.app.Fragment;
import android.view.ViewGroup;
import android.view.View;
import android.view.LayoutInflater;

public class MyFragment02 extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.myfrag2, container, false);
    }

   public static Fragment newInstance() {
        MyFragment02 fragment = new MyFragment02();
        fragment.setRetainInstance(true);
        return fragment;
    }

}


Finally, return to the activity and add unique fragments rather than adding two copies of the original.

             .

             .

            getFragmentManager().beginTransaction()

                     .add(R.id.container, MyFragment.newInstance())

                     .add(R.id.container2, MyFragment02.newInstance())

                     .commit();

             .

             .



We end with two specialized fragments within the same activity;

Nothing sexy, but a toy example that demonstrates tying and linking activities and fragments.

Cheers.

Android -- Introduction to Fragments (Part 1)

Life gets busy. As a result, I took a hiatus from Android development for a period of several months. What I returned to; the concept of fragments, support libraries, Android Studio and with it a new file structure, new IDE and numerous new technologies for Android development.

Surrounded by new concepts and tools, one must focus on ramping back up one area at a time. With the objective of increased productivity, tools such as Android Studio do much for the developer hiding subtleties from the developer by automating a good deal of the heavy lifting. While I fully recommend use of such tools, the course of this post will be working with the SDK, no IDE, to better understand the subtleties and reduce the complexity of the files and structures.

Let's start by creating a project;

$ android list
targets | grep id:
id: 1 or "android-7"
id: 2 or "android-8"
id: 3 or "android-21"
id: 4 or "Google Inc.:Google APIs:7"
id: 5 or "Google Inc.:Google APIs:8"
id: 6 or "Google Inc.:Google APIs:21"

Targeting Google API v21, we specify target 6.

$ android create project --name FragTest01 --path ./ws/FragTest01 --target 6 --package com.fsk.example.FragTest01 --activity FragTest01
Build it by executing the build via Ant;

$ cd ws/FragTest01
$ ant debug
$ adb devices
List of devices attached 
01aa7bcb8c8c07be device

With a connected device, start the logcat service, followed by installing and running the app;

$ xterm -e adb logcat &amp;
$ adb -s 01aa7bcb8c8c07be install -r ./bin/FragTest01-debug-unaligned.apk
$ adb -s 01aa7bcb8c8c07be shell am start -a android.intent.action.MAIN -n com.fsk.example.FragTest01/.FragTest01


We now have an initial project set up, we can continue to play.

First modification we'll make is to the res/layout/main.xml file that was generated as part of the project creation. We'll simply be adding an id to the layout, the usage will become apparent later.


$ cat res/layout/main.xml 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    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="Hello World, FragTest01"
    />
</LinearLayout>


We'll move along next by creating our first fragment. Before we do so though, let's spend a bit of time discussing the concept of fragments.

The Android developers website does solid job describing the concept of fragments, I'd recommend spending some candle-lit quality time with it, but for now the Cliff Notes for fragments are:

  • Fragments represent behavior, or portion of user interface in an activity. Think of fragments as a new container to stuff behaviors previously localized in activities with the overall goal of better supporting evolving screen sizes and resolutions.
  • A fragments meaning of life is to be contained within an activity, the activity gives the fragment(s) a purpose in life.

Since a fragment represents a portion of the UI, let's create a layout file for it;

$ cat res/layout/myfrag.xml 
<?xml version="1.0" encoding="utf-8"?>
   <LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="horizontal"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="#666666">
   <TextView
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="My Fragment Example"
   android:textColor="#000000"
   android:textSize="20px" />
</LinearLayout>

Linear layout, text view with some static text.
Next, we'll create a fragment that uses this layout.


$ cat src/com/fsk/example/FragTest01/MyFragment.java

package com.fsk.example.FragTest01;

import android.os.Bundle;
import android.app.Fragment;
import android.view.ViewGroup;
import android.view.View;
import android.view.LayoutInflater;

public class MyFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.myfrag, container, false);
    }
   public static Fragment newInstance() {
        MyFragment fragment = new MyFragment();
        fragment.setRetainInstance(true);
        return fragment;
    }
}
The two key methods of interest; onCreateView() and newInstance().   
The onCreateView() method is part of the Fragment Lifecycle, it's purpose is to return a View that is the root of the fragment layout. This is done in this case by inflating the myfrag.xml layout file.


The newInstance() method returns a new instance of the fragment, used by the activity which is shown below;

$ cat src/com/fsk/example/FragTest01/FragTest01.java 
package com.fsk.example.FragTest01;

import android.app.Activity;
import android.os.Bundle;
import java.util.Timer;
import java.util.TimerTask;

public class FragTest01 extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        init();
    }

    private void init()
    {
       Timer t=new Timer();
       t.schedule(new TimerTask() 
       {
           public void run()
           {
            getFragmentManager().beginTransaction()
                     .add(R.id.container, MyFragment.newInstance())
                     .commit();
           }
       },5000);
    }
}


The activity simply sets the content view, represented by main.xml, then schedules a timer to add (read that as create) the fragment after 5 seconds. Adding/removing/replacing of fragments is done in the form of 'transactions' which are executed on the UI thread some time after being committed.


About as simple of an example as there is. We'll expand on it in later posts.

Full source for this example can be retrieved here.

Cheers.

26 May, 2014

DVD Backup on Linux

It's been years now, all my primary computers have Linux as the host operating system.  Few things can't be done in Linux, but one in particular is backing up dvd's which required the installation of VirtualBox and Windows VM.  I've been using that setup for some time to backup dvd's, with applications such as DVDFab, DvdShrink or the like.  With WinXp at EOL and Nero failing to work with Win7 VMs I finally gave it up after finding an alternative application for native Linux.

K9copy seems to scratch the itch.  Using Ubuntu 12.04, I found setting it up takes the form:


$ sudo apt-get install libdvdcss libdvdcss2
$ sudo apt-get update
$ sudo apt-get install libdvdread4
$ sudo /usr/share/doc/libdvdread4/install-css.sh
$ sudo apt-get install k9copy


http://k9copy.sourceforge.net/web/index.php/en/

Happy viewing.

03 May, 2014

Google Archive

Did you know that you can export all your Google artifacts?

https://www.google.com/takeout
Check the items you want to export and kick out a Zip file.

Cheers.

11 April, 2014

Generating Multi-Plot Real-Time Plots with Python

In my last post the real-time plotting capabilities were demonstrated, we're extending on this by showing how to generate multiple plots simultaneously.  A couple noteworthy observations, in the past post the X and Y scaling was automatically scaled after each element addition.  While you can still do this, typically for multiplots we would prefer maintaining a shared X range.  While somewhat unnecessary, I've elected to maintain a uniform Y range.



#!/usr/bin/python
from pylab import *;
import time;

def log(M):
  print "__(log) " + M;

def test02():
  plt.ion();
  fig=plt.figure(1);
  ax1=fig.add_subplot(311);
  ax2=fig.add_subplot(312);
  ax3=fig.add_subplot(313);
  l1,=ax1.plot(100,100,'r-');
  l2,=ax2.plot(100,100,'r-');
  l3,=ax3.plot(100,100,'r-');
  time.sleep(3);

  D=[];
  i=0.0;
  while (i < 50.0):
    D.append((i,sin(i),cos(i),cos(i*2)));
    T1=[x[0] for x in D];
    L1=[x[1] for x in D];
    L2=[x[2] for x in D];
    L3=[x[3] for x in D];

    l1.set_xdata(T1);
    l1.set_ydata(L1);

    l2.set_xdata(T1);
    l2.set_ydata(L2);

    l3.set_xdata(T1);
    l3.set_ydata(L3);

    ax1.set_xlim([0,50]);
    ax2.set_xlim([0,50]);
    ax3.set_xlim([0,50]);
    ax1.set_ylim([-1.5,1.5]);
    ax2.set_ylim([-1.5,1.5]);
    ax3.set_ylim([-1.5,1.5]);

    plt.draw();
    i+=0.10;
  show(block=True);

#---main---
log("main process initializing");
test02();
log("main process terminating");

Easy Peasy;

04 April, 2014

Generating Real-Time Plots with Python

In my previous post we described plotting data using MatplotLib utilities and Python.  While this may be valuable, it becomes notably more valuable when you can generate 'live' plots during run-time.  In a past employment I worked with a series of controls engineers that utilized real-time data plots to debug and develop a highly complex multi-axis weapons system and it was the first time I understood how a real-time plot of sequence of steps simplified the development effort.

Let's get started.
Unlike the previous post, let's create the data and plot it as it is generated.


#!/usr/bin/python
from pylab import *;
import time;

def log(M):
  print "__(log) " + M;

def test01():
  plt.ion();
  fig=plt.figure(1);
  ax1=fig.add_subplot(111);
  l1,=ax1.plot(100,100,'r-');

  D=[];
  i=0.0;
  while (i < 50.0):
    D.append((i,sin(i)));
    T=[x[0] for x in D];
    L=[x[1] for x in D];
    l1.set_xdata(T);
    l1.set_ydata(L);
    ax1.relim();
    ax1.autoscale_view();
    plt.draw();
    i+=0.10;
    time.sleep(1/10.0);
  show(block=True);

#---main---
log("main process initializing");
test01();
log("main process terminating");

The result is a dynamically generated plot that resembles the following;

Tie this plotting routine to a system providing run-time information via a socket, or perhaps monitoring network traffic via pcapture libraries and you've got yourself the foundation of a real-time data monitoring system.

Cheers.