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.