android create project -n thinger_1 -a thinger_1 -k com.nthist.samples.thinger_1 -t 25 -p thinger_1
Created project directory: thinger_1
Created directory /home/blunderdurst/thinger_1/src/com/nthist/samples/thinger_1
Added file thinger_1/src/com/nthist/samples/thinger_1/thinger_1.java
Created directory /home/blunderdurst/thinger_1/res
Created directory /home/blunderdurst/thinger_1/bin
Created directory /home/blunderdurst/thinger_1/libs
Created directory /home/blunderdurst/thinger_1/res/values
Added file thinger_1/res/values/strings.xml
Created directory /home/blunderdurst/thinger_1/res/layout
Added file thinger_1/res/layout/main.xml
Created directory /home/blunderdurst/thinger_1/res/drawable-hdpi
Created directory /home/blunderdurst/thinger_1/res/drawable-mdpi
Created directory /home/blunderdurst/thinger_1/res/drawable-ldpi
Added file thinger_1/AndroidManifest.xml
Added file thinger_1/build.xml
Added file thinger_1/proguard-project.txt

So one (simple) command created ten folders and six files.

cd thinger_1/src/com/nthist/samples/thinger_1/
cat thinger_1.java
package com.nthist.samples.thinger_1;

import android.app.Activity;
import android.os.Bundle;

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

Needs some work. Fortunately, that is what programmers do. Unfortunately, we want a GUI kind of screen with labels, and input boxes, and buttons. These do not go here, That is what the /res/layout folder is for.

cd
cd thinger_1/res/layout/
cat 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"
    >
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Hello World, thinger_1"
    />
</LinearLayout>

We will add labels, and input boxes, and a button to the "LinearLayout".

But first we will build it and see if it works.

cd
cd thinger_1
ant clean debug
Buildfile: /home/blunderdurst/thinger_1/build.xml

-check-env:
 [checkenv] Android SDK Tools Revision 25.2.5
 [checkenv] Installed at /home/blunderdurst

-setup:
     [echo] Project Name: thinger_1
  [gettype] Project Type: Application

-pre-clean:

clean:
   [delete] Deleting directory /home/blunderdurst/thinger_1/bin
[getlibpath] Library dependencies:
[getlibpath] No Libraries
   [subant] No sub-builds to iterate on

-set-mode-check:

-set-debug-files:

-check-env:
 [checkenv] Android SDK Tools Revision 25.2.5
 [checkenv] Installed at /home/blunderdurst

-setup:
     [echo] Project Name: thinger_1
  [gettype] Project Type: Application

-set-debug-mode:

-debug-obfuscation-check:

-pre-build:

-build-setup:
[getbuildtools] Using latest Build Tools: 28.0.3
     [echo] Resolving Build Target for thinger_1...
[gettarget] Project Target:   Google APIs
[gettarget] Vendor:           Google Inc.
[gettarget] Platform Version: 4.0.3
[gettarget] API level:        15
[gettarget] WARNING: No minSdkVersion value set. Application will install on all Android versions.  
     [echo] ----------
     [echo] Creating output directories if needed...
    [mkdir] Created dir: /home/blunderdurst/thinger_1/bin
    [mkdir] Created dir: /home/blunderdurst/thinger_1/bin/res
    [mkdir] Created dir: /home/blunderdurst/thinger_1/bin/rsObj
    [mkdir] Created dir: /home/blunderdurst/thinger_1/bin/rsLibs
    [mkdir] Created dir: /home/blunderdurst/thinger_1/gen
    [mkdir] Created dir: /home/blunderdurst/thinger_1/bin/classes
    [mkdir] Created dir: /home/blunderdurst/thinger_1/bin/dexedLibs
     [echo] ----------
     [echo] Resolving Dependencies for thinger_1...
[dependency] Ordered libraries:
[dependency]
[dependency] ------------------
[dependency] API<=15: Adding annotations.jar to the classpath.
     [echo] ----------
     [echo] Building Libraries with 'debug'...
   [subant] No sub-builds to iterate on

-code-gen:
[mergemanifest] Merging AndroidManifest files into one.
[mergemanifest] Manifest merger disabled. Using project manifest only.
     [echo] Handling aidl files...
     [aidl] No AIDL files to compile.
     [echo] ----------
     [echo] Handling RenderScript files...
     [echo] ----------
     [echo] Handling Resources...
     [aapt] Generating resource IDs...
     [echo] ----------
     [echo] Handling BuildConfig class...
[buildconfig] Generating BuildConfig class.

-pre-compile:

-compile:
    [javac] Compiling 3 source files to /home/blunderdurst/thinger_1/bin/classes

-post-compile:

-obfuscate:

-dex:
      [dex] input: /home/blunderdurst/thinger_1/bin/classes
      [dex] input: /home/blunderdurst/tools/support/annotations.jar
      [dex] Pre-Dexing /home/blunderdurst/tools/support/annotations.jar -> annotations-337af4fb5842b5439571dc0fd81e48a2.jar
      [dex] Converting compiled files and external libraries into /home/blunderdurst/thinger_1/bin/classes.dex...
       [dx] Merged dex #1 (7 defs/2.1KiB)
       [dx] Merged dex #2 (2 defs/1.1KiB)
       [dx] Result is 9 defs/3.2KiB. Took 0.1s

-crunch:
   [crunch] Crunching PNG Files in source dir: /home/blunderdurst/thinger_1/res
   [crunch] To destination dir: /home/blunderdurst/thinger_1/bin/res
   [crunch] Processing image to cache: /home/blunderdurst/thinger_1/res/drawable-hdpi/ic_launcher.png => /home/blunderdurst/thinger_1/bin/res/drawable-hdpi/ic_launcher.png
   [crunch]   (processed image to cache entry /home/blunderdurst/thinger_1/bin/res/drawable-hdpi/ic_launcher.png: 0% size of source)
   [crunch] Processing image to cache: /home/blunderdurst/thinger_1/res/drawable-ldpi/ic_launcher.png => /home/blunderdurst/thinger_1/bin/res/drawable-ldpi/ic_launcher.png
   [crunch]   (processed image to cache entry /home/blunderdurst/thinger_1/bin/res/drawable-ldpi/ic_launcher.png: 0% size of source)
   [crunch] Processing image to cache: /home/blunderdurst/thinger_1/res/drawable-mdpi/ic_launcher.png => /home/blunderdurst/thinger_1/bin/res/drawable-mdpi/ic_launcher.png
   [crunch]   (processed image to cache entry /home/blunderdurst/thinger_1/bin/res/drawable-mdpi/ic_launcher.png: 0% size of source)
   [crunch] Crunched 3 PNG files to update cache

-package-resources:
     [aapt] Creating full resource package...

-package:
[apkbuilder] Current build type is different than previous build: forced apkbuilder run.
[apkbuilder] Creating thinger_1-debug-unaligned.apk and signing it with a debug key...

-post-package:

-do-debug:
 [zipalign] Running zip align on final apk...
     [echo] Debug Package: /home/blunderdurst/thinger_1/bin/thinger_1-debug.apk
[propertyfile] Creating new property file: /home/blunderdurst/thinger_1/bin/build.prop
[propertyfile] Updating property file: /home/blunderdurst/thinger_1/bin/build.prop
[propertyfile] Updating property file: /home/blunderdurst/thinger_1/bin/build.prop
[propertyfile] Updating property file: /home/blunderdurst/thinger_1/bin/build.prop

-post-build:

debug:

BUILD SUCCESSFUL
Total time: 4 seconds

Wow! Many, many more files, and folders, and et ceteras!

Wait! Why is the API level set to 15? Didn't we set the target to 25 when we created the project?

The "andoid" command set the API level to 15. I am sure it was "helping" me. The last line of thinger_1/project.properties was target=Google Inc.:Google APIs:15. I changed the 15 to 23 despite the warning YOUR CHANGES WILL BE ERASED! at the top of the file.

Why isn't the minSdkVersion value set? How do we set it. Where are each of these details documented?

The minSdkVersion is set in the AndroidManifest.xml. It should be the first entry below the <mainfest ... ... > entry. It looks like <uses-sdk android:minSdkVersion="23" />

Well, in any case we want to install thinger_1/bin/thinger_1-debug.apk on our "device".

Installed ( with complaints ) and it ran.

cd
cd thinger_1/res/layout/
vi 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"
	>
	<TextView
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="Lattitude 1"
		/>
	<EditText
		android:id="@+id/e1"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:hint="Lattitude 1"
		/>
	<TextView
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="Longitude 1"
		/>
	<EditText
		android:id="@+id/e2"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:hint="Longitude 1"
		/>
	<TextView
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="Lattitude 2"
		/>
	<EditText
		android:id="@+id/e3"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:hint="Lattitude 2"
		/>
	<TextView
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="Longitude 2"
		/>
	<EditText
		android:id="@+id/e4"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:hint="Longitude 2"
		/>
	<Button
		android:id="@+id/button1"
		android:layout_height="wrap_content"
		android:layout_width="fill_parent"
		android:text="Get Distance"
		/>
	<TextView
		android:id="@+id/result"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text=""
		/>

Can you say "BoilerPlate"?

cd
cd thinger_1/src/com/nthist/samples/thinger_1/
vi thinger_1.java
package com.nthist.samples.thinger_1;

import android.app.Activity;
import android.os.Bundle;
import java.lang.*;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class thinger_1 extends Activity
{
	TextView e1 = null;
	TextView e2 = null;
	TextView e3 = null;
	TextView e4 = null;
	TextView result = null; 

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		e1 = (TextView)(this.findViewById(R.id.e1)); // lat 1
		e2 = (TextView)(this.findViewById(R.id.e2)); // lon 1
		e3 = (TextView)(this.findViewById(R.id.e3)); // lat 2
		e4 = (TextView)(this.findViewById(R.id.e4)); // lon 2
		result = (TextView)(this.findViewById(R.id.result));

		final Button button = (Button) findViewById(R.id.button1);

		button.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Double x1 = new Double( 0.0 );  // lon1
				Double x2 = new Double( 0.0 );  // lon2
				Double y1 = new Double( 0.0 );  // lat1
				Double y2 = new Double( 0.0 );  // lat2
				try {
					x1 = x1.parseDouble( e2.getText().toString() );
				} catch( NumberFormatException e ) {
					result.setText( e.toString() );
					return;
				}
				try {
					x2 = x2.parseDouble( e4.getText().toString() );
				} catch( NumberFormatException e ) {
					result.setText( e.toString() );
					return;
				}
				try {
					y1 = y1.parseDouble( e1.getText().toString() );
				} catch( NumberFormatException e ) {
					result.setText( e.toString() );
					return;
				}
				try {
					y2 = y2.parseDouble( e3.getText().toString() );
				} catch( NumberFormatException e ) {
					result.setText( e.toString() );
					return;
				}
				Double ew = new Double( ( x1 - x2 ) * Math.cos( 3.14159 * ( y1 + y2 ) / 360 ) ) ; // diff of lon * cos average lat
				Double ns = new Double( y1 - y2 ) ;	// diff lats
				Double dist = new Double( Math.sqrt( ew * ew + ns * ns ) * 69.0 );	// 69 miles / degree latitude
				result.setText( dist.toString() );
			}
		} ); 
	}
}

Now we have an app that takes a pair of latitudes and longitudes and crudely estimates the distance between the locations represented thereby.

there is much more that could be done, but I am going to leave this as it is and start a new thinger.