Mobile Application Development
Table of Contents
1. Prelude
- These notes don’t include Android Studio tutorials as:
- Graphical tutorials are a lot of effort
- Android Studio keeps evolving so it’s going to be different when you’re reading this.
- Unlike most of my other notes, these should be used as complementary material. I really don’t think these notes can replace lectures or a course itself.
2. Introduction to Android
2.1. Why Android
Android is a mobile operating system based on the Linux Kernel, designed for touch screen devices. There are several reasons to use it such as:
2.1.1. Large Market Reach
It is used in 80% of the smartphones in the world.
2.1.2. Open Source
All of the code is open to the developers for customization.
2.1.3. Versatility
Android is used in smartphones, smart watches, TVs and cars.
2.1.4. Customizable
Vendors can tailor Android to specific hardware or user needs.
2.2. Sensors that Android Uses
2.2.1. Accelerometer
- Detects device orientation, motion and speed.
2.2.2. Gyroscope
- Measures angular rotation.
- Used in steering in games.
2.2.3. GPS/Location
- Detects the user’s geographic position.
2.2.4. Proximity Sensor
- Detects how close the user’s face is.
- This disables the screen during phone calls.
2.3. Four Components of Android Application Development
2.3.1. Resources
- This contains all static data which is to be separated from the code.
- Includes:
- XML Layouts (stored in
res/layout/) - Strings
- Images
- Colors
- Media Files
- XML Layouts (stored in
2.3.2. Components / Android Stack
- These are the executable of an app.
- These includes:
System Apps OR User Apps |
| Java API Framework |
Native C/C++ Runtime OR Android Runtime (ART) |
| Hardware Abstraction Layer |
| Linux Kernel |
- Every layer in this stack, uses services of the layer below, to serve the layer above.
- The linux kernel is responsible for low-level memory management and security features.
- The kernel talks to the hardware directly, and hardware abstraction layer makes accessing hardware more abstract and standardized.
- Native C/C++ libraries (Android Native Development Kit, or NDK) or Android Runtime (ART), do all the backend work involved in an app. These include managing databases, graphics, web rendering engines, and in basic system functions too.
- The Java API Framework consists of premade classes which correspond to different parts of an app.
2.3.3. Manifest
- A configuration file that the Android Runtime reads first.
- This declares all of the components of the App.
2.3.4. Build Configuration (Gradle)
- Manages dependencies and build settings using the
.gradleconfig files. - It also manages APK (Android Package) versions.
2.4. Navigation
- The back button on the bottom of the screen is called the temporal/back navigation button and that is controlled by the Android System’s back stack.
- The left-arrow on the top-left of the screen is called the ancestral/up navigation button, and it’s provided by the app’s action bar.
- Ancestral navigation is controlled by defining parent-child relationships between activities in the Android manifest.
2.5. Android Application Components
| Component | What it is |
|---|---|
Activity |
A visible screen |
Service |
Background work |
Intent |
A message/request |
BroadcastReceiver |
Listens to system level broadcast messages (like “battery low”) |
ContentProvider |
Data Management |
3. How the App works
3.1. Activity
3.1.1. What it is
- A Java Class that serves as a controller for a specific screen, is called an activity.
- Such a Java Class must
extend Activity(basic activity lifecycle features provided here) orextend AppCompatActivity(this is preferred because modern Android features are backported to older versions too).AppCompatActivityextendsFragmentActivitywhich extendsComponentActivitywhich extendsActivity. - The screen that the app starts with, is controlled with the help of the
MainActivity.javafile.
3.1.2. Activity Life Cycle
- It is a set of states an activity can be in during it’s lifetime, from when it is created until it is destroyed.
- It’s a graph where the nodes are the states, the edges are the callbacks.
- Created (not visible yet)
- Started (visible)
- Resume (In foreground and interactive)
- Paused(partially invisible)
- Stopped (hidden)
- Destroyed (gone from memory)
3.2. Views
- All of the components of the UI of a particular screen is created using an XML file or a group of XML files.
- Such a component is called a view.
- They’re the building blocks of the user interface.
- Examples of views include
TextView(for displaying text),EditText(for taking text input),RadioButton,Switch,SeekBar(sliders), etc. - Each view will have an
id(an integer), which can be accessed in a Java Class asR.id.nameOfID, whereRis afinal classcreated by Android at build time. An activity is connected to the XML layout because of a line that looks like:
setContentView(R.layout.activity_main);where
activity_main.xmlis the name of the xml file.- Views have properties like:
- Color, dimensions, positions (all static properties)
- May have Focus
- May be interactive
- May be visible or not
- May have relationship with other views.
3.2.1. How it looks like in XML
Let’s arbitrarily take the <TextView/> view and study its properties defined in XML.
<TextView android:id="@+id/nameOfID" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/myBackgroundColor" android:text="@string/count_initial_value" android:textColor="@color/#0000aa" android:textSize="@dimen/count_text_size" android:gravity="center" android:textAlignment="center" android:textStyle="bold" android:autoLink="web" />
layout_widthorlayout_height
Value Meaning wrap_contentOnly as tall/wide as the size of the text 100dpFixed width 0dpUsed with layout_weightor ConstraintLayoutmatch_constraintConstraintLayout only dp(density-independent pixels) are used for layout dimensions, whilesp(scale-independent pixels) are used for text-sizes.All of these properties can be modified by changing the XML file, by changing things graphically on Android Studio, or by using the Java code.
android:autoLink="web"
You can make the content inside a
TextViewclickable, by specifying where it should take the user to after clicking.web: Detects URLs like https://example.com or www.example.com and opens them in the browser when tapped.email: Detects email addresses like user@gmail.com and opens the email client (mailto intent) when tapped.phone: Detects phone numbers like +1-800-555-0199 and opens the dialer when tapped.map: Detects addresses and opens them in Maps when tapped. This one is the least reliable — address detection is fuzzy and often misses or false-positives.all: Enables all four of the above at once.
3.2.2. Three ways to define a view
- The three ways to define a view is:
- Graphically
- Through XML
- Programmatically
- A constraint represents connection or alignment to another view.
3.2.3. ViewGroup
- A
ViewGroupis a type of View that can contain other Views. - You can see the View Hierarchy in the component tree.
- Use the smallest number of simplest views
- Keep the view hierarchy flat by limiting nesting of views.
3.2.4. Layout
Layoutis a type ofViewGroupthat are designed to position and arrange those views on the screen.
- Creating Layouts using Java
We’ll use
LinearLayout, which just puts items in a row or in a column. To create one and then set the direction, we use:LinearLayout x = new LinearLayout(this); x.setOrientation(LinearLayout.VERTICAL);
Let’s have a
TextViewinside theLinearLayout. To create theTextView:TextView tv = new TextView(this); tv.setText("hi loll"); tv.setWidth(LayoutParams.MATCH_PARENT); tv.setMinLines(3);
To add the
TextViewinside theLinearLayout:x.addView(tv); setContentView(x);To modify properties:
LinearLayout.LayoutParams layoutParams = new Linear.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT ); x.setLayoutParams(layoutParams);
4. Basic Addition
- This code follows from this video.
First declare private variables in the
MainActivityclass:private EditText num1, num2; private Button add; private TextView result;
Make sure you do
alt + enterwhen your mouse is over theEditText,ButtonorTextViewdatatype, to resolve all imports.Next, in the end of
onCreate()function, get all of views using their IDsR.id.idName, and then assign them to the private variables you created:num1 = (EditText) findViewById(R.id.no1); num2 = (EditText) findViewById(R.id.no2); result = (TextView) findViewById(R.id.result); add = (Button) findViewById(R.id.addButton);
Before assigning, make sure you appropriately typecast the View.
To the button object
add, use thesetOnClickListener()method asadd.setOnClickListener();. Inside, add a parameter that starts fromnew Viewand just pick the first suggestion (it’s most likely what we need). So the function will look like this:add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // here is where we do the logic } });
Use the
setTextmethod on theresultTextView. It can only take a String, so typecast whatever you want to show usingString.valueOf().add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { result.setText(String.valueOf( Integer.parseInt(num1.getText().toString()) + Integer.parseInt(num2.getText().toString()) )); } });
Just try typing whatever is inside, all you need to do is tab your way through.
The complete app looks like this:
public class MainActivity extends AppCompatActivity { // declare these variables private EditText num1, num2; private Button add; private TextView result; @Override protected void onCreate(Bundle savedInstanceState) { // some code already here, just add the below code num1 = (EditText) findViewById(R.id.no1); num2 = (EditText) findViewById(R.id.no2); result = (TextView) findViewById(R.id.result); add = (Button) findViewById(R.id.addButton); add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { result.setText(String.valueOf( Integer.parseInt(num1.getText().toString()) + Integer.parseInt(num2.getText().toString()) )); } }); } }
5. Intent
- An Intent is an object used to request an action from another app component via the Android system.
- It’s a message to the Android runtime to run an Activity.
5.1. Types of Intent
- There are two types of intent: Explicit and Implicit
5.1.1. Explicit Intent
- This is the intent used to transfer from one activity to another activity within an application.
- Right click on the
appand create a new activity (Android Studio will automatically create and link the XML file). Trigger the new activity by setting onClick parameter of a button as the name of a function
doSomething(), which is a void function defined inMainActivity.public void doSomething(View view){ Intent intent = new Intent(this, Next.class); intent.putExtra("answer", String.valueOf(Integer.parseInt(someInput.getText().toString()) +100)); // in case you're using data instead of extras (both explained later): // intent.setData(Uri.parse("http://www.google.com")); startActivity(intent); }
where
someInputis the id of anEditTextobject.And in the new activity’s
onCreate()function:Intent intent = getIntent(); textView = (TextView) findViewById(R.id.textView); textView.setText(String.valueOf(intent.getStringExtra("answer")));
5.1.2. Implicit Intent
- This is used to invoke an activity from another app.
- Here the system is asked to find an activity that can handle this request.
5.2. Types of Sending data with Intents
| Data | Extras |
|---|---|
| Single piece of information represented by a URI | Key-Value Pairs of Information |
6. Scroll View
- ScrollView makes a single child under it, vertically scrollable. For
horizontal scrolling you’ll have to use
HorizontalScrollView. - When you use scroll view, drag and drop a linear layout into the component tree, and then put whatever you want in there.
- Drag and drop only into the component tree (bottom left corner, basically under palette), because all Views should be under the linear layout.
7. Spinner
Just add Spinner into the XML, and then in the
onCreate()function:List<String> spinnerList = new ArrayList<>(); spinnerList.add("Item 1"); spinnerList.add("Item 2"); spinnerList.add("Item 3"); spinnerList.add("Item 4"); Spinner spinner = findViewById(R.id.spinner); ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, spinnerList); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter);
8. Feedback app
8.1. RatingBar
You get the rating as:
float rating = ratingBar.getRating();
8.2. Radio Button
Given:
difficulty = findViewById(R.id.difficulty);
then the selected radio button is obtained through the id (int):
int selectedId = difficulty.getCheckedRadioButtonId();
8.3. CheckBox
recommendCheckBox = findViewById(R.id.recommend);
You check if it’s checked or not by the boolean return value:
boolean recommend = recommendCheckBox.isChecked();
8.4. Making a WebSearch Button
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH); intent.putExtra(SearchManager.QUERY, topic); startActivity(intent);
The
ACTION_WEB_SEARCHparameter passed to theIntentconstructor is actually a string defined like this:public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
8.5. Solving Data Loss after Screen Rotation
8.5.1. What happens when screen rotates
@Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); // the below line is what you add outState.putString("topic", feedbackTopic.getText().toString()); }
When you rotate the screen, the state of an activity is destroyed. This is the function that’s called just before the activity is destroyed.
8.5.2. What happens after screen rotates
@Override protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // the below line is what you add feedbackTopic.setText(savedInstanceState.getString("topic")); }
This is the function that is called when the activity is recreated after the screen rotates.