Post on 05-Dec-2014
description
Intro to Android App DevelopmentA Hobbyist's Perspective
presented by Steve Wiley
● Compare iPhone vs Android● Getting started with Android● SimpleCalc walk through
Language Comparison
● iPhone ObjectiveC→
● Android Java→
ObjectiveC JavaHeader files No header files
Object reference counting Automatic garbage collection
Class extension None
Messages to objects with [] Dot notation
Language Comparion
ObjectiveC
[instance setWidth:5andHeight:[tgt getHeight]];
Java
instance.setWidthAndHeight( 5, tgt.getHeight() );
IDE Comparison
● iPhone XCode→
– Intellisense
– Integrated debugging● Often force to resort to ”printf” debugging due to ”out
of scope” errors.
● Android Eclipse with Android Plugin→– Very fullfeatured
– I've bairly scratched the surface
Cost Comparison
iPhone
● Mac required
● Tools free→
● Device installation →$100/year
● Appstore submittal free→
● Apple's take 30%→
Android
● Mac, Linux, Windows
● Tools free→● Device installation
free→● Appstore submittal
$25 onetime→● Google's take →
30%
Getting Started
● Install Eclipse– http://www.eclipse.org
● Install the ADT plugin for Eclipse– http://www.android.com/sdk/index.html
● Add a browser bookmark for the documentation– <installdir>/docs/guide/samples/index.html
Create a New Project
● Start Eclipse● Click ”Workbench”● Window \ Android SDK and AVD Manager
‒ Available Packages‒ https://dlssl.google.com/android/repository/repository.xml
‒ Virtual Devices
● File \ New \ Android Project‒ Specify lowest possible SDK
What's Created for You?
● Activityin DefaultActivity.java
● res/layout/main.xml
● res/values/strings.xml
… and
● AndroidManifest.xml
Simple Calc
RPN Simple Calculator● 0 – 9 keys● Add, Subtract,
Multiply Divide● Change Sign● Backspace● Decimal Point● Exit
First... Create the Layouts
● Portrait & Landscape‒ res/layoutport/main.xml‒ res/layoutland/main.xml
● Contents:Layout
Controls...● Common Layout Choices:
‒ AbsoluteLayout, FrameLayout, LinearLayout, RelativeLayout, TableLayout
Nested TableLayouts
Outer Table
Inner Table
TableRows
Orientation<FrameLayout
android:layout_width="fill_parent"android:layout_height="fill_parent"android:padding="0dip">android:orientation="vertical"<TableLayout...
<FrameLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:padding="0dip">android:orientation="horizontal"<TableLayout...
Results TextView<TableRow>
<TextViewandroid:id="@+id/resultsView"android:layout_span="3"android:typeface="sans"android:gravity="right|fill_vertical"android:text="@string/hello"android:clickable="false"android:cursorVisible="false"android:focusable="false"android:focusableInTouchMode="false"android:lines="1"android:layout_margin="2sp"android:background="@drawable/yellowbox"android:textColor="@color/black"android:textStyle="bold"android:textSize="40dip"/>
</TableRow>
● Use ”+id” notation to provide lookup of control in code.
● @string resources are pulled from res/values/string.xml.
● @drawable resources come out of res/drawable/*.png
● @color resources come out of res/values/colors,xml.
Enter Button
<TableRow><Button
android:text="@string/Enter"android:id="@+id/enterButton"android:layout_span="2"android:typeface="serif"android:textStyle="bold"android:height="50dip"android:textSize="30dip"android:gravity="center"android:padding="0px"/>
<Button.../></TableRow>
● Layout_span = 2 causes the Enter button to span 2 columns.
Next... Add Controls to Code● Declare controls within DefaultActivity class:
private Button changeSignBtn;private Button enterBtn;
● Within DefaultActivity's onCreate() method:‒ this.setContentView( R.layout.main );
for res/layout*/main.xml
● Assign Controls using findViewById():this.changeSignBtn = (Button) this.findViewById( R.id.changeSignButton );this.enterBtn = (Button)
this.findViewById( R.id.enterButton );
Then... Connect Clicks to Actionsthis.changeSignBtn.setOnClickListener( new
OnClickListener() {public void onClick( View v ) {
DefaultActivity.this.indicateClick();DefaultActivity.this.toggleSignOfScratch();}
} );
this.enterBtn.setOnClickListener( newOnClickListener() {
public void onClick( View v ) {DefaultActivity.this.indicateClick();DefaultActivity.this.onEnterClick();}
} );
At This Point
● UI is Layed Out● Controls are Connected to Actions● What next?
‒ Add preferences for: # of digits to display Keystroke feedback:
‒ Clicks (redundant)‒ Vibrations (redundant)‒ Animated Visual
Preferences
● Create folder res/xml● Add preferences.xml
‒ Rightclick on xml folder‒ New / Other... / Android XML File
New Android XML File Dialog
● Name the file ”preferences.xml”
● Check ”Preferene”● No Qualifier needed● Finish
Types of Preferences● CheckBoxPreference – checked/unchecked
‒ Click on Key Press (on/off)
‒ Vibrate on Key Press (on/off)
‒ Animation on Key Pres (on/off)
● RingtonePreference – sound selection
● EditTextPreference – editable text
● ListPreference – select a string from a list
● DialogPreference – customization
‒ # of Digits to Display‒ SeekBar from http://android.hlidskialf.com/blog/code/androidseekbarpreference
Edit preferences.xml<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreferenceandroid:key="AudibleKeyStrokes"android:title="@string/AudibleKeyStrokes"android:defaultValue="true"/>
<CheckBoxPreferenceandroid:key="VibrationOnKeyStroke"android:title="@string/VibrationOnKeyStroke"android:defaultValue="false"/>
<CheckBoxPreferenceandroid:key="AnimateKeyStrokes"android:title="@string/AnimateKeyStrokes"android:defaultValue="false"/>
<com.boisecodecamp.wiley.steve.SeekBarPreferenceandroid:key="digits"android:title="Fraction digits"android:defaultValue="2"android:summary="Number of digits to display = %?"android:dialogMessage="Fraction digits"android:text=" digits"android:max="8"/>
</PreferenceScreen>
Create Preferences Activity
● Rightclick package
● New / Class...
● Set Superclass to:android.preference.PreferenceActivity
● Add following in onCreate() method:this.addPreferencesFromResource(
R.xml.preferences );
● ”preferences” is from the name of the xml file created earlier
Binding Preferences
● Override onCreateOptionsMenu()@Overridepublic boolean onCreateOptionsMenu( Menu menu ) {
menu.add( R.string.DecimalDigitsSetting ).setIcon( android.R.drawable.ic_menu_preferences );
return super.onCreateOptionsMenu( menu );}
● Override onOptionsItemSelected()@Overridepublic boolean onOptionsItemSelected( MenuItem item ) {
super.onOptionsItemSelected( item );Intent optionsItent = new Intent().setClass( this,
SimpleCalcPreferenceActivity.class );this.startActivityForResult( optionsItent, 0 );return true;
}
Binding Preferences...
● Override onActivityResult()@Overrideprotected void onActivityResult( int requestCode,
int resultCode, Intent data ) {super.onActivityResult( requestCode, resultCode, data );this.setPreferences();
}
Binding Preferences...private void setPreferences() {
SharedPreferences sharedPref =PreferenceManager.getDefaultSharedPreferences( this );
this.stackManager.setVibrate( sharedPref.getBoolean("VibrationOnKeyStroke", false ) );
this.stackManager.setBeep( sharedPref.getBoolean( "AudibleKeyStrokes", true ) );
this.stackManager.setAnimateKeystrokes( sharedPref.getBoolean("AnimateKeyStrokes", false ) );
this.stackManager.setDigits( sharedPref.getInt( "digits", 2 ) );
}
Adding Menus
Override two methods:● onCreateOptionsMenu – invoked when the users presses the Menu
button.
‒ Create menu items.● OnOptionsItemSelected – invoked when the user selects a
MenuItem.
‒ Perform the desired action.
For Example, Settings Menu@Overridepublic boolean onCreateOptionsMenu( Menu menu ) {
menu.add( R.string.DecimalDigitsSetting ).setIcon( android.R.drawable.ic_menu_preferences );
return super.onCreateOptionsMenu( menu );}
@Overridepublic boolean onOptionsItemSelected( MenuItem item ) {
super.onOptionsItemSelected( item );Intent optionsIntent = new Intent().setClass(
this, SimpleCalcPreferenceActivity.class );this.startActivityForResult( optionsIntent, 0 );return true;
}
Maintaining State
Android moves Activites through states.
Changing orientation will cause a Stop/Create cycle.
Saving State
Override at least these methods to save state:@Overrideprotected void onSaveInstanceState( Bundle outState ) {
super.onSaveInstanceState( outState );outState.putParcelable(
DefaultActivity.stackManagerName,this.stackManager );
}
@Overrideprotected void onPause() {
super.onPause();final ObjectOutputStream out = new ObjectOutputStream(
this.openFileOutput( SETTINGS_FILENAME,MODE_PRIVATE ) );
out.writeObject( this.stackManager );out.close();
}
Restoring Statepublic void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );if( savedInstanceState != null ) {
this.stackManager =savedInstanceState.getParcelable(
DefaultActivity.stackManagerName );}if( this.stackManager == null ) {
ObjectInputStream in = new ObjectInputStream(this.openFileInput( SETTINGS_FILENAME ) );this.stackManager = (StackManager)
in.readObject();}if( this.stackManager == null ) {
this.stackManager = new StackManager();}
Now What do We Have?
● Functional UI● Preferences● Menu to Invoke Preferences● Next:
‒ Run it in the Emulator
Creating a Virtual Device
Within Eclipse: Window / Android SDK and AVD Manager
● New...‒ Name‒ Target
Start an Emulator
Can be started from Eclipse or Command Line:‒ Just be sure $PATH is set correctly
● Emulator avd <avdname> scale 0.8
‒ Scale as needed for best results
Telnet to the Emulator to help debug.
Favorite keys:
CntlF11 Rotate
F6 Trackball
Run within Emulator
● Run / Debug...● Android Application / OK● Choose Emulator / OK
Run on a Device
● Attached the device via USB● Enable USB debugging on the device● Run or Debug...● Android Application / OK● Choose Device
Thank You
● Questions?