Android Application Model I CSE 5236: Mobile Application Development Instructor: Adam C. Champion, Ph.D. Course Coordinator: Dr. Rajiv Ramnath 1
Framework Support (e.g. Android) 2
Framework Capabilities and Add-Ons Tailored to mobile apps Built-in services: GUI OS services (file I/O, threads, device management) Graphics Device access (GPS, camera, music and video players, sensors) Web services Networking XML processing Standard language libraries Add-ons: Maps Database support (SQLite) WebKit 3
IDE Support Eclipse, Android Studio (Beta) Testing tools (test management, unit tests) Performance profiling tools SCM integration (Git, SVN, CVS) Software emulators Sensor injection (GPS, other sensors) 4
Android Studio Project Components 5
Types of Android Programs Applications Home app, Home screen Take over screen Services Run in the background without UI App widgets and home screen widgets View-only interface to a service Home screen widget if on Home screen All apps are composed of Activities a cohesive step in an Android application 6
Activities in Tic-Tac-Toe 7
Specifying Activities AndroidManifest.xml <activity android:name=".splashscreen" android:label="@string/app_name" android:screenorientation="portrait"> <intent-filter> <action android:name="android.intent.action.main"/> <category android:name="android.intent.category.launcher /> </intent-filter> </activity> <activity android:name=".login" android:label="@string/app_name" android:launchmode="singleinstance" android:screenorientation="portrait"> <intent-filter> <action android:name="com.wiley.fordummies.androidsdk.login"/> <category android:name="android.intent.category.default"/> </intent-filter> </activity> 8
Implementing Activities Java public class LoginActivity extends SingleFragmentActivity {......... public class GameSessionActivity extends SingleFragmentActivity {...... Kotlin class LoginActivity : SingleFragmentActivity() {......... class GameSessionActivity : SingleFragmentActivity() {...... 9 Note: SingleFragmentActivity extends FragmentActivity
Activity UI Widgets View and ViewGroup Package android.view Specified declaratively in layout files Always use Fragments 10
Sample Layout: Login Activity <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android android:background="@color/background" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="20dip"> <LinearLayout android:orientation="vertical <TextView android:text="@string/login_title /> <TextView /> <EditText /> <TextView /> <EditText /> <Button /> <Button /> <Button /> </LinearLayout> </ScrollView> 11 <project>/app/src/main/res/layout/fragment_login.xml
Views, ViewGroups, Layouts, Widgets Many types of views, layouts and widgets: ScrollView, HorizontalScrollView LinearLayout, AbsoluteLayout, FrameLayout, RelativeLayout TextView, EditText, Button, DatePicker, Spinner Nested nature of layout ViewGroup base class for composite elements View base class for terminal UI components. Layout files compiled into resource R class in res subtree. 12
Implement UI Logic: Listener Objects: Java public class LoginActivity extends SingleFragmentActivity { // Create LoginFragment in oncreate() method. (See SingleFragmentActivity) public class LoginFragment extends Fragment implements View.OnClickListener { private EditText musernameedittext; private EditText mpasswordedittext; @Override public View oncreateview() { View v = inflater.inflate(r.layout.fragment_login, container, false); musernameedittext = (EditText) v.findviewbyid(r.id.username_text); mpasswordedittext = (EditText) v.findviewbyid(r.id.password_text); Button loginbutton = (Button) v.findviewbyid(r.id.login_button); loginbutton.setonclicklistener(this); Button cancelbutton = (Button) v.findviewbyid(r.id.cancel_button); cancelbutton.setonclicklistener(this); Button newuserbutton = (Button) v.findviewbyid(r.id.new_user_button); newuserbutton.setonclicklistener(this); return v; 13
Implement UI Logic: Listener Objects: Kotlin class LoginActivity : SingleFragmentActivity() { // Create LoginFragment in oncreate() method. (See SingleFragmentActivity) class LoginFragment : Fragment(), View.OnClickListener { private lateinit var musernameedittext: EditText private lateinit var mpasswordedittext: EditText override fun oncreateview( ): View? { val v = inflater.inflate(r.layout.fragment_login, container, false) musernameedittext = v.findviewbyid<edittext>(r.id.username_text) mpasswordedittext = v.findviewbyid<edittext>(r.id.password_text) val loginbutton = v.findviewbyid<button>(r.id.login_button) loginbutton.setonclicklistener(this) val cancelbutton = v.findviewbyid<button>(r.id.cancel_button) cancelbutton.setonclicklistener(this) val newuserbutton = v.findviewbyid<button>(r.id.new_user_button) newuserbutton.setonclicklistener(this) return v 14
The OnClick Handler Java public void onclick(view v) { switch (v.getid()) { case R.id.login_button: checklogin(); break; case R.id.cancel_button: finish(); break; case R.id.new_user_button: startactivity(new Intent(this, Account.class)); break; Kotlin override fun onclick(view: View) { when (view.id) { R.id.login_button -> checklogin() R.id.cancel_button -> activity.finish() R.id.new_user_button -> startactivity(intent(activity.applicationcontext, AccountActivity::class.java)) 15
Embedding a View: GameSession Activity, Fragment: Java public class GameSessionActivity extends SingleFragmentActivity { public class GameSessionFragment extends Fragment { <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android.. > <LinearLayout... <com.wiley.fordummies.androidsdk.board android:id="@+id/board" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </LinearLayout> <TextView... "/> <TextView... "/> </LinearLayout> 16
Embedding a View: GameSession Activity, Fragment: Kotlin class GameSessionActivity : SingleFragmentActivity() { class GameSessionFragment : Fragment() { <!-- Same XML as before --> 17
Embedding a View: Board Class Java // Board.java public class Board extends View {... public boolean ontouchevent( MotionEvent event) { switch (action) { case MotionEvent.ACTION_DOWN: break; return super.ontouchevent(event); Kotlin // Board.kt class Board : View { override fun ontouchevent( event: MotionEvent): Boolean { when (action) { MotionEvent.ACTION_DOWN -> { return super.ontouchevent(event) 18
Handling UI in the Activity Activity also a View Can handle UI without any widgets. Why? Handle non-widget-specific events (touch) Handle user interaction outside the boundaries of any UI components See ontouchevent method in SplashScreenFragment class. 19
Menus (Option menus) and Action Bars Declare the menu items Define oncreateoptionsmenu() and/or the oncreatecontextmenu() callback methods in Activity. Automatically called to create the menu (what if it doesn t exist?). Implement onoptionsitemselected() and/or oncontextitemselected() in activity. 20
Menu Layout File <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:title="settings" android:id="@+id/menu_settings" android:icon="@android:drawable/ic_menu_preferences" /> <item android:title="help" android:id="@+id/menu_help" android:icon="@android:drawable/ic_menu_info_details" /> <item android:title="exit" android:id="@+id/menu_exit" android:icon="@android:drawable/ic_menu_close_clear_cancel" /> <item android:title="contacts" android:id="@+id/menu_contacts" android:icon="@android:drawable/ic_menu_view" /> </menu> Action Bar: Declare menu item with additional attribute android:showasaction ="ifroom", "never", "withtext" or "always". 21
Menu Creation: Java public class GameOptionsFragment {... public View oncreateview( ) { sethasoptionsmenu(true); public boolean oncreateoptionsmenu(menu menu) { super.oncreateoptionsmenu(menu); MenuInflater inflater = getmenuinflater(); inflater.inflate(r.menu.menu, menu); return true;... 22
Menu Creation: Kotlin class GameOptionsFragment { fun oncreateview( ) { sethasoptionsmenu(true); fun oncreateoptionsmenu(menu: Menu?, inflater: MenuInflater?) { super.oncreateoptionsmenu(menu,inflater) inflater!!.inflate(r.menu.menu, menu) 23
Menu Handlers: Java public boolean onoptionsitemselected(menuitem item) { switch (item.getitemid()) { case R.id.menu_settings: startactivity(new Intent(getActivity(), SettingsActivity.class)); return true; case R.id.menu_help: startactivity(new Intent(getActivity(), HelpActivity.class)); return true; case R.id.menu_exit: showquitappdialog(); return true; case R.id.menu_contacts: startactivity(new Intent(getActivity(), ContactsActivity.class)); return true; return false; 24
Menu Handlers: Kotlin fun onoptionsitemselected(item: MenuItem?): Boolean { when (item!!.itemid) { R.id.menu_settings -> { startactivity(intent(activity, SettingsActivity::class.java)) return true R.id.menu_help -> { startactivity(intent(activity, HelpActivity::class.java)) return true R.id.menu_exit -> { showquitappdialog() return true R.id.menu_contacts -> { startactivity(intent(activity, ContactsActivity::class.java)) return true return false 25
UI for Larger Screens - Fragments In Android 3.0 and up with compatibility library (ACL) for earlier versions Further decouples UI interactions from activity lifecycle Standard concept in frameworks Allows reuse of UI components Specialized activity class FragmentActivity We will cover it in a later class 26
Special Types of Activities: Preferences: Java public class SettingsActivity extends AppCompatActivity { protected Fragment createfragment() { return new SettingsFragment(); @Override protected void oncreate(bundle savedinstancestate) { FragmentManager fm = getsupportfragmentmanager(); Fragment fragment = fm.findfragmentbyid(r.id.fragment_container); Fragment preferencefragment = createfragment(); fm.begintransaction().replace(r.id.fragment_container, preferencefragment).commit(); PreferenceManager.setDefaultValues(this, R.xml.settings, false); public class SettingsFragment extends PreferenceFragmentCompat { @Override public void oncreatepreferences(bundle savedinstancestate, String rootkey) { // Load preferences from XML resource. addpreferencesfromresource(r.xml.settings); 27
Special Types of Activities: Preferences: Kotlin class SettingsActivity : AppCompatActivity() { protected fun createfragment(): Fragment { return SettingsFragment() override fun oncreate(savedinstancestate: Bundle?) { val fm = supportfragmentmanager val fragment = fm.findfragmentbyid(r.id.fragment_container) val preferencefragment = createfragment() fm.begintransaction().replace(r.id.fragment_container, preferencefragment).commit() PreferenceManager.setDefaultValues(this, R.xml.settings, false) class SettingsFragment : PreferenceFragmentCompat() { override fun oncreatepreferences(savedinstancestate: Bundle?, rootkey: String?) { // Load preferences from XML resource. addpreferencesfromresource(r.xml.settings) 28
Layout File for a Preferences Activity <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android=http://schemas.android.com/apk/res/android android:title="settings" android:background="@color/background"> <EditTextPreference android:key="name" android:title="player Info" android:summary="select your name" android:defaultvalue="player 1"/> <CheckBoxPreference android:key="human_starts" android:title="human Plays First" android:summary="check box to play first" android:defaultvalue="true" /> </PreferenceScreen> 29
Settings Java // Settings.java public class Settings { public static String getname( Context context) { return PreferenceManager.getDefaultSharedPreferences(context).getString(OPT_NAME, OPT_NAME_DEF); public static boolean doeshumanplayfirst(context context) { return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(OPT_PLAY_FIRST, OPT_PLAY_FIRST_DEF); Kotlin // Settings.kt object Settings { fun getname(context: Context): String { return PreferenceManager.getDefaultSharedPreferences(context).getString(OPT_NAME, OPT_NAME_DEF) fun doeshumanplayfirst(context: Context): Boolean { return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(OPT_PLAY_FIRST, OPT_PLAY_FIRST_DEF) 30
Thank You Questions and comments? 31