SlideShare una empresa de Scribd logo
1 de 71
Descargar para leer sin conexión
St. Pölten University of Applied SciencesSt. Pölten University of Applied Sciences
Platzhalter für möglichen
Bildeinsatz
Android Development with Kotlin, Part 2
Internet Services & JSON
Andreas Jakl
Digital Healthcare
FH St. Pölten
Platzhalter für möglichen
Bildeinsatz
Version 1.3
Andreas Jakl
▪ Focus areas
▪ AR / VR, mobile apps, sensors, interaction
technology, software architecture, open source
developer (NFC, Bluetooth Beacons)
▪ Microsoft MVP (Most Valuable Professional)
▪ mobility.builders community: Mobile Developer
After-Work Events
▪ Previous Experience
▪ Tieto, Start-up (Mopius), Nokia (Finland),
Siemens Mobile (Munich), FH Hagenberg
(Mobile Computing)
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten
https://www.andreasjakl.com/
@andijakl
andreas.jakl@fhstp.ac.at
2
Contents
▪ Language Understanding Services (Microsoft LUIS)
▪ Android Menus
▪ Web Service Client / REST & HTTP Request
▪ Threads & Multitasking
▪ AsyncTask
▪ Permissions
▪ JSON Parsing
▪ Dynamic Lists
▪ RecyclerView & Adapter
▪ Click Handling
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 3
LANGUAGE UNDERSTANDING SERVICE
Control Computers using Natural Language
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 4
Natural Language Understanding
▪ Identify information from conversations
▪ Train scenarios you want to differentiate simply by supplying examples
▪ Extract information from free-form sentences: dates, locations, numbers & more
▪ Reinforcement learning for continuous improvement
▪ Usage
▪ Chat bots, speech, analyzing text, smart speakers
▪ Services
▪ Microsoft LUIS, Amazon Comprehend, Facebook NLP, Google Cloud Natural
Language, Watson Natural Language Understanding
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 5
LUIS Architecture
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 6
client (phone) cloud (LUIS)
1. Client sends request to cloud.
Query contained in URL.
https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/<appid>
?subscription-key=<key>&q=Turn on lights
HTTPS connection /
GET request (REST)
LUIS Architecture
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 7
client (phone) cloud (LUIS)
HTTPS connection /
JSON response (REST)
2. AI analyzes request, responds
with results in JSON
LUIS Architecture
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 8
client (phone) cloud (LUIS)
2. AI analyzes request, responds
with results in JSON
{
"query": "turn on lights",
"topScoringIntent": {
"intent": "HomeAutomation.TurnOn",
"score": 0.990858853
},
"entities": [
{
"entity": "on",
"type": "HomeAutomation.Operation",
"startIndex": 5,
"endIndex": 6,
"score": 0.553411
}
]
}
Create LUIS Service
▪ Follow instructions at
▪ https://www.andreasjakl.com/using-natural-language-understanding-part-
3-luis-language-understanding-service/
▪ Create your own vocabulary!
▪ If you like, additionally test “Home Automation” prebuilt domain:
https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-get-
started-create-app
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 9
ANDROID MENUS
User Interaction, in a different way
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 10
Exercise: Create SmartHomeClient
▪ Create new project
▪ Empty Activity, Kotlin support
▪ Layout
▪ Change from ConstraintLayout to LinearLayout
▪ Add EditText, ScrollView + nested TextView
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 11
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 12
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
tools:context="com.andresjakl.smarthomeclient.MainActivity">
<EditText
android:id="@+id/et_query_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your command"
android:inputType="text"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<TextView
android:id="@+id/tv_results"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Results" />
</ScrollView>
</LinearLayout>
Create Menu Resource
▪ Add title for menu action to strings.xml
▪ Create new menu:
▪ Right-click res > New > Android Resource File
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 13
<string name="send">Send</string>
Android
MainActivity.kt
onOptionsItem
Selected()
Add Menu Item
▪ Use designer to create “Menu Item”
▪ Handle menu item in MainActivity.kt
▪ Override onCreateOptionsMenu()
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 14
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.main, menu)
return true
}
Handle Tapped Menu Item
▪ Override onOptionsItemSelected()
▪ Show toast
▪ Test!
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 15
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
val selectedMenuItem = item?.itemId
if (selectedMenuItem == R.id.action_send_command) {
// TODO: Show toast!
return true
}
return super.onOptionsItemSelected(item)
}
WEB SERVICE CLIENT
REST & More – access URLs
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 16
Build Uri
▪ Uri.Builder (Android API)
▪ Creates well-formed URI
▪ Takes care of particulars (encoding invalid characters, ? or & query codes, …)
▪ Configure parameters & URLs
▪ Best practices for securely using API keys
▪ https://developers.google.com/console/help/api-key-best-practices
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 17
private val ENDPOINT = "https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/xxx";
private val APPKEY = "yyy";
Uri -> URL
▪ Create build function
▪ Add query parameters to base URL
▪ Convert Android Uri to Java URL
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 18
var builtUri = Uri.parse(ENDPOINT).buildUpon()
.appendQueryParameter("subscription-key", APPKEY)
.appendQueryParameter("q", queryText)
.build()
return URL(builtUri.toString())
private fun buildUrl(queryText : String) : URL { }
Make Search Query
▪ Create function to make search query
▪ Call from menu item handler
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 19
private fun makeSearchQuery() {
var queryCommand = et_query_text.text.toString()
var queryUrl = buildUrl(queryCommand)
Log.d(TAG, queryUrl.toString())
}
HTTP Request
▪ Add helper
function to
your class
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 20
/**
* This method returns the entire result from the HTTP response.
*
* @param url The URL to fetch the HTTP response from.
* @return The contents of the HTTP response.
* @throws IOException Related to network and stream reading
*/
fun getResponseFromHttpUrl(url: URL): String? {
val urlConnection = url.openConnection() as HttpURLConnection
try {
val inStream = urlConnection.inputStream
val scanner = Scanner(inStream)
// Using pattern a (beginning of the stream) - force scanner to read
// the entire contents of the stream into the next token string
// -> buffers data, different data sizes are allowed, converts
// from UTF-8 to UTF-16
scanner.useDelimiter("A")
val hasInput = scanner.hasNext()
return if (hasInput) {
scanner.next()
} else {
null
}
} finally {
urlConnection.disconnect()
}
}
Extend makeSearchQuery()
▪ Call new function after Uri conversion
▪ Test app!
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 21
android.os.NetworkOnMainThreadException
var queryResults : String?
try {
queryResults = getResponseFromHttpUrl(queryUrl)
tv_results.text = queryResults
} catch (e: IOException){
e.printStackTrace()
}
THREADS AND MULTITASKING
Keeping the UI responsive
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 22
Multi-Threading
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 23
Single User Interface Thread
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 24
Networking Takes Seconds
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 25
Loading …
App freezes
No user interaction
possible!
After ~ 5 Seconds
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 26
Loading …
App freezes
No user interaction
possible!
Multi-Threading Within Your App
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 27
Perform work on secondary execution thread
UI stays responsive
Background
thread:
UI
thread:
progress and results
AsyncTask
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 28
Main / UI Thread Background Thread
onPreExecute
AsyncTask.execute()
publishProgress… doInBackground
onPostExecute
Variable types
(in AsyncTask definition)
Create AsyncTask
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 29
Main / UI Thread Background Thread
onPreExecute
AsyncTask.execute()
publishProgress… doInBackground
onPostExecute
Variable types
(in AsyncTask definition)
inner class WebQueryTask :
AsyncTask<URL, Void, String?>() {
}
Create AsyncTask
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 30
Main / UI Thread Background Thread
onPreExecute
AsyncTask.execute()
publishProgress… doInBackground
onPostExecute
Variable types
(in AsyncTask definition)
inner class WebQueryTask :
AsyncTask<URL, Void, String?>() {
}
Kotlin: inner class may access
members of outer class
Set Up AsyncTask
▪ Override doInBackground()
▪ Move getResponseFromHttpUrl() into WebQueryTask class
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 31
override fun doInBackground(vararg params: URL): String? {
}
Kotlin: vararg = variable
number of parameters
Note: change URL? to URL
Implement AsyncTask
▪ Similar to previous web service call
▪ Update UI when finished
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 32
override fun doInBackground(vararg params: URL): String? {
var queryUrl = params[0]
var queryResults : String? = null
try {
queryResults = getResponseFromHttpUrl(queryUrl)
} catch (e: IOException){
e.printStackTrace()
}
return queryResults
}
override fun onPostExecute(result: String?) {
tv_results.text = result
}
Test!
▪ Start thread!
▪ Test app!
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 33
java.lang.SecurityException: Permission denied (missing
INTERNET permission?)
android_getaddrinfo failed: EACCES (Permission denied)
private fun makeSearchQuery() {
var queryCommand = et_query_text.text.toString()
var queryUrl = buildUrl(queryCommand)
Log.d(TAG, queryUrl.toString())
WebQueryTask().execute(queryUrl)
}
PERMISSIONS
Access sensitive data
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 34
Permissions
▪ Each app gets its unique Linux user ID
▪ Runs within its own instance of an Android runtime
▪ -> completely sandboxed
▪ -> request access to resources + data outside of sandbox
▪ Permission list
▪ https://developer.android.com/guide/topics/permissions/index.html
▪ Why not just request all permissions?
▪ Users get suspicious!
▪ Think of alternatives: using camera app through Intent
-> no camera permission needed for your app
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 35
Network Permissions
▪ Add permission to AndroidManifest.xml
▪ Device: Android 6+ (API level 23+) & targetSdkVersion = 23+
▪ Dangerous permissions acknowledged while app is running
▪ Normal permissions: granted automatically at install time, no prompts
▪ https://developer.android.com/guide/topics/permissions/normal-
permissions.html
▪ Granted permissions can be revoked
▪ < 23: install-time permissions
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 36
<uses-permission android:name="android.permission.INTERNET"/>
Final Test!
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 37
Network Libraries
▪ More powerful libraries
▪ Include caching, compression, etc.
▪ Volley (Google)
▪ OkHttp
▪ Retrofit
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 38
Exercise
▪ Repetition: save state of TextView to survive screen rotation!
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 39
JSON PARSING
Data Formats
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 40
JSON Parsing
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 41
{
"query": "turn on lights",
"topScoringIntent": {
"intent": "HomeAutomation.TurnOn",
"score": 0.990858853
},
"entities": [
{
"entity": "on",
"type": "HomeAutomation.Operation",
"startIndex": 5,
"endIndex": 6,
"score": 0.553411
}
]
}
val parsedJson = JSONObject(result)
tv_top_intent.text = parsedJson.getJSONObject("topScoringIntent")?.getString("intent")
val entitiesArray = parsedJson.getJSONArray("entities")
if (entitiesArray != null && entitiesArray.length() > 0) {
tv_top_entity_type.text = entitiesArray.getJSONObject(0)?.getString("type")
}
Exercise
▪ Add additional TextViews
▪ Parse JSON and extract information
▪ Check that your app doesn’t crash if
entering strange text
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 42
DYNAMIC LISTS
Populating better lists
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 43
Scrolling TextView?
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 44
Handle tap events
on items?
More complex
layouts per item?
Different fonts &
images?
Performance:
keeping everything
in memory?
Animations &
effects?
RecyclerView
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 45Image credits: Google, https://developer.android.com/training/material/lists-cards.html
Ali Connors
Brunch this weekend?
I’ll be in your neighborhood doing errands…
15m
Layout instance
1. Layout instance scrolls out of view
queue
TextView
TextView
TextView
TextView
Image
Layout instance
2. Placed in queue
Lorem ipsum
dolor sit amet
consectetur adipiscing elit…
17h
Layout instance 3. Filled with new content &
scrolls in again
RecyclerView
RecyclerView Flow
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 46
Data source
Adapter
Provides new data to RecyclerView
when needed
Adapter binds data from
data source to views
ViewHolder
Used to send views to RecyclerView
LayoutManager
Tells RecyclerView how to layout
views
Kotlin: Data Class
▪ Only contains data, no operations
▪ Auto-created utility functions
▪ Generates properties (no more getters and setters)
▪ equals(), hashCode(), toString(), copy()
▪ https://kotlinlang.org/docs/reference/data-classes.html
▪ Comparison to Java: https://antonioleiva.com/data-classes-kotlin/
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 47
data class PartData ( val id: Long, val itemName: String)
Data source
Creating Demo Data
▪ Create some demo data in onCreate() of MainActivity
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 48
Data source
var partList = ArrayList<PartData>()
partList.add(PartData(100411, "LED Green 568 nm, 5mm"))
partList.add(PartData(101119, "Aluminium Capacitor 4.7μF"))
partList.add(PartData(101624, "Potentiometer 500kΩ"))
// ...
Create List Item Layout
▪ New layout xml file:
part_list_item.xml
▪ Layout: LinearLayout (vertical)
▪ Width: match_parent
▪ Height: wrap_content
▪ Padding: 16dp
▪ Child: 2x TextView
▪ Id 1: @+id/tv_part_item_name (larger
text size)
▪ Id 2: @+id/tv_part_id (smaller text size)
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 49
Add RecyclerView
▪ Add RecyclerView to dependencies in build.gradle of app
▪ compile 'com.android.support:recyclerview-v7:26.1.0’
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 50
RecyclerView
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:recyclerview-v7:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
ViewHolder
▪ Create class PartAdapter
▪ Create child class ViewHolder inside PartAdapter
▪ Describes item view
▪ Stores metadata about its place within RecyclerView
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 51
class PartViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
// bind() = Custom function. Copies items from supplied instance of our
// "PartData" data class to the "itemView" we got through the constructor
fun bind(part: PartData) {
itemView.tv_part_item_name.text = part.itemName
}
}
ViewHolder
Kotlin: this is actually the primary constructor. Declares and
initializes properties (here: itemView).
https://kotlinlang.org/docs/reference/classes.html
Adapter Tasks
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 52
Adapter
1. Return information, e.g., about the number of items
getItemCount()
2. Create new view instances
onCreateViewHolder()
3. Populate view items with data
onBindViewHolder()
Adapter
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 53
AdapterRecyclerView Data source
1. Return information, e.g., about the number of items
getItemCount()
2. Create new view instances
onCreateViewHolder()
ViewHolder
3. Populate view items with data
onBindViewHolder()
id itemName
100411 LED Green 568 nm, 5mm
101119 Aluminium Capacitor
4.7μF
101629 Potentiometer 500kΩ
Create Adapter
▪ Extend PartAdapter
▪ Derive from RecyclerView.Adapter<RecyclerView.ViewHolder>
▪ Let Android Studio write required member implementations
▪ Add parameter to PartAdapter:
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 54
Adapter
(val partItemList: List<PartData>)
Implement PartAdapter
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 55
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
// LayoutInflater: takes ID from layout defined in XML.
// Instantiates the layout XML into corresponding View objects.
// Use context from main app -> also supplies theme layout values!
val inflater = LayoutInflater.from(parent.context)
// Inflate XML. Last parameter: don't immediately attach new view to the parent view group
val view = inflater.inflate(R.layout.part_list_item, parent, false)
return PartViewHolder(view)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
// Populate ViewHolder with data that corresponds to the position in the list
// which we are told to load
(holder as PartViewHolder).bind(partItemList[position])
}
override fun getItemCount() = partItemList.size
Add RecyclerView to MainActivity
▪ Update activity_main Layout
▪ Delete “Hello World” text
▪ Add RecyclerView
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 56
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_parts"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Wire Up RecyclerView
▪ 1. Assign LinearLayoutManager
▪ Measures and positions item views
▪ Linear list layout (default: vertical)
▪ 2. Optional optimization
▪ View contents do not change RecyclerView size
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 57
rv_parts.layoutManager = LinearLayoutManager(this)
rv_parts.hasFixedSize()
Wire Up RecyclerView
▪ 3. Assign PartAdapter to RecyclerView
▪ Supply test data we created earlier
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 58
rv_parts.adapter = PartAdapter(testData)
Final Test!
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 59
RECYCLERVIEW & CLICK HANDLING
Advanced Topics for the Pros
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 60
RecyclerView
RecyclerView & Click Listener
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 61
Data source
Adapter
Click Listener
ViewHolder
ViewHolder
ViewHolder
bind() function assigns data &
click handler callback to view holder instances
Click event executes registered
click handler callback function
Higher-Order Functions
▪ Function that
▪ Takes another function as parameter, or
▪ Returns a function
▪ Lambda
▪ Surrounded by { }
▪ Parameters -> Return type
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 62
Experiments I: Class with Parameters
▪ Create a class that has parameters
▪ Note that you can use the parameters as properties
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 63
/**
* Defines a class with a constructor. Its parameters are automatically available
* as properties in the class. Note that the keyword "constructor" is optional
* and could be stripped.
*/
class ClassWithConstructorProperties constructor (var a: Int, var b: Int) {
fun calculate() : Int {
return a + b;
}
} // Create new class instance
var calcTest = ClassWithConstructorProperties(10, 20)
// Print calculation results
Log.d("Tests", "Calculation result: " + calcTest.calculate())
Experiments II: Function Parameters
▪ Define a function with a function parameter
▪ Specify structure the supplied function must fulfil
▪ Parameter performCalculation is of type: (parameter types) -> return type
▪ When calling:
▪ Supply a function as lambda expression that matches the parameter
▪ Return type is inferred automatically if not Unit (= void in Java)
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 64
private fun testFunctionParameters(performCalculation: (Int, Int) -> Int) {
Log.d("Tests", "Calculation result: " + performCalculation(1, 2))
}
testFunctionParameters( {a : Int, b : Int -> a + b } )
Adapter with Click Listener
▪ 1. Add 2nd parameter to PartAdapter constructor
▪ Function parameter
▪ Reqiures PartData as parameter, no value is returned (“Unit”)
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 65
class PartAdapter (val partItemList: List<PartData>, val clickListener: (PartData) -> Unit) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
View Holder with Click Listener
▪ 2. Assign click listener in PartViewHolder
▪ Assigned to the whole view, not just a Button / TextView / …
▪ Supply click listener as 2nd parameter of bind() function
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 66
class PartViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(part: PartData, clickListener: (PartData) -> Unit) {
itemView.tv_part_item_name.text = part.itemName
itemView.tv_part_id.text = part.id.toString()
itemView.setOnClickListener { clickListener(part)}
}
}
Assign Click Listener
▪ 3. When Adapter binds ViewHolder, assign click listener
▪ clickListener part of constructor in PartAdapter
▪ -> automatically available as property in the PartAdapter class
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 67
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
// Populate ViewHolder with data that corresponds to the position in the list
// which we are told to load
(holder as PartViewHolder).bind(partItemList[position], clickListener)
}
Handle Clicks in MainActivity
▪ 4. Write function in MainActivity to handle clicked items
▪ 5. Extend construction of PartAdapter, supply function parameter
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 68
private fun partItemClicked(partItem : PartData) {
Toast.makeText(this, "Clicked: ${partItem.itemName}", Toast.LENGTH_LONG).show()
}
rv_parts.adapter = PartAdapter(testData, { partItem : PartData -> partItemClicked(partItem) })
Final Test!
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 69
Exercise: Detail Page
▪ Create a DetailActivity
▪ Shows part details
▪ Extend click handler in
MainActivity
▪ Launch second activity
▪ Pass data via Intent Extras
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 70
THANK YOU!
Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 71

Más contenido relacionado

La actualidad más candente (6)

Snowplow - Analytics & Data Rollout at Seven
Snowplow - Analytics & Data Rollout at SevenSnowplow - Analytics & Data Rollout at Seven
Snowplow - Analytics & Data Rollout at Seven
 
Android Jetpack - What's new
Android Jetpack - What's newAndroid Jetpack - What's new
Android Jetpack - What's new
 
Kotlin in industry
Kotlin in industryKotlin in industry
Kotlin in industry
 
Jive 7 Feature Overview
Jive 7 Feature OverviewJive 7 Feature Overview
Jive 7 Feature Overview
 
Mobile backends with Google Cloud Platform (MBLTDev'14)
Mobile backends with Google Cloud Platform (MBLTDev'14)Mobile backends with Google Cloud Platform (MBLTDev'14)
Mobile backends with Google Cloud Platform (MBLTDev'14)
 
LuminAR - Poster
LuminAR - PosterLuminAR - Poster
LuminAR - Poster
 

Similar a Android Development with Kotlin, Part 2 - Internet Services and JSON

Lecture 12 - Maps, AR_VR_aaaaHardware.pptx
Lecture 12 - Maps, AR_VR_aaaaHardware.pptxLecture 12 - Maps, AR_VR_aaaaHardware.pptx
Lecture 12 - Maps, AR_VR_aaaaHardware.pptx
NgLQun
 

Similar a Android Development with Kotlin, Part 2 - Internet Services and JSON (20)

Android Development with Kotlin, Part 1 - Introduction
Android Development with Kotlin, Part 1 - IntroductionAndroid Development with Kotlin, Part 1 - Introduction
Android Development with Kotlin, Part 1 - Introduction
 
From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...
From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...
From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...
 
Lecture 12 - Maps, AR_VR_aaaaHardware.pptx
Lecture 12 - Maps, AR_VR_aaaaHardware.pptxLecture 12 - Maps, AR_VR_aaaaHardware.pptx
Lecture 12 - Maps, AR_VR_aaaaHardware.pptx
 
Resume jyoti gupta
Resume jyoti guptaResume jyoti gupta
Resume jyoti gupta
 
WebKit and Blink: Bridging the Gap Between the Kernel and the HTML5 Revolutio...
WebKit and Blink: Bridging the Gap Between the Kernel and the HTML5 Revolutio...WebKit and Blink: Bridging the Gap Between the Kernel and the HTML5 Revolutio...
WebKit and Blink: Bridging the Gap Between the Kernel and the HTML5 Revolutio...
 
WebKit and Blink: Bridging the Gap Between the Kernel and the HTML5 Revolution
WebKit and Blink: Bridging the Gap Between the Kernel and the HTML5 RevolutionWebKit and Blink: Bridging the Gap Between the Kernel and the HTML5 Revolution
WebKit and Blink: Bridging the Gap Between the Kernel and the HTML5 Revolution
 
The WebKit project (LinuxCon North America 2012)
The WebKit project (LinuxCon North America 2012)The WebKit project (LinuxCon North America 2012)
The WebKit project (LinuxCon North America 2012)
 
Angular JS 2_0 BCS CTO_in_Res V3
Angular JS 2_0 BCS CTO_in_Res V3Angular JS 2_0 BCS CTO_in_Res V3
Angular JS 2_0 BCS CTO_in_Res V3
 
Simple stock market analysis
Simple stock market analysisSimple stock market analysis
Simple stock market analysis
 
Custom Reports & Integrations with GraphQL
Custom Reports & Integrations with GraphQLCustom Reports & Integrations with GraphQL
Custom Reports & Integrations with GraphQL
 
EGL Conference 2011 - Technical Workshop
EGL Conference 2011 - Technical WorkshopEGL Conference 2011 - Technical Workshop
EGL Conference 2011 - Technical Workshop
 
Nagendran resume
Nagendran resumeNagendran resume
Nagendran resume
 
GDG Oslo: Hidden Android features
GDG Oslo: Hidden Android featuresGDG Oslo: Hidden Android features
GDG Oslo: Hidden Android features
 
Unite Los Angeles 2018 - Unity 2019 R&D Roadmap
Unite Los Angeles 2018 - Unity 2019 R&D RoadmapUnite Los Angeles 2018 - Unity 2019 R&D Roadmap
Unite Los Angeles 2018 - Unity 2019 R&D Roadmap
 
Build Cutting edge Mobile Apps using QML and JavaScript for MeeGo N9: Linux F...
Build Cutting edge Mobile Apps using QML and JavaScript for MeeGo N9: Linux F...Build Cutting edge Mobile Apps using QML and JavaScript for MeeGo N9: Linux F...
Build Cutting edge Mobile Apps using QML and JavaScript for MeeGo N9: Linux F...
 
apidays LIVE Australia 2020 - From micro to macro-coordination through domain...
apidays LIVE Australia 2020 - From micro to macro-coordination through domain...apidays LIVE Australia 2020 - From micro to macro-coordination through domain...
apidays LIVE Australia 2020 - From micro to macro-coordination through domain...
 
Android in 2018 Google I/O
Android in 2018 Google I/OAndroid in 2018 Google I/O
Android in 2018 Google I/O
 
Apple watch deck yodel meetup 4-16
Apple watch deck  yodel meetup 4-16Apple watch deck  yodel meetup 4-16
Apple watch deck yodel meetup 4-16
 
Improve your Android-Fu with Kotlin
Improve your Android-Fu with KotlinImprove your Android-Fu with Kotlin
Improve your Android-Fu with Kotlin
 
Sravanthi Kolla Resume
Sravanthi Kolla ResumeSravanthi Kolla Resume
Sravanthi Kolla Resume
 

Más de Andreas Jakl

Symbian OS - Mopoid Next Gen - Tutorial
Symbian OS - Mopoid Next Gen - TutorialSymbian OS - Mopoid Next Gen - Tutorial
Symbian OS - Mopoid Next Gen - Tutorial
Andreas Jakl
 

Más de Andreas Jakl (20)

Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?
Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?
Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?
 
Mobile Test Automation
Mobile Test AutomationMobile Test Automation
Mobile Test Automation
 
Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...
Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...
Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...
 
WinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows Phone
WinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows PhoneWinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows Phone
WinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows Phone
 
Nokia New Asha Platform Developer Training
Nokia New Asha Platform Developer TrainingNokia New Asha Platform Developer Training
Nokia New Asha Platform Developer Training
 
Windows Phone 8 NFC Quickstart
Windows Phone 8 NFC QuickstartWindows Phone 8 NFC Quickstart
Windows Phone 8 NFC Quickstart
 
Windows (Phone) 8 NFC App Scenarios
Windows (Phone) 8 NFC App ScenariosWindows (Phone) 8 NFC App Scenarios
Windows (Phone) 8 NFC App Scenarios
 
Windows 8 Platform NFC Development
Windows 8 Platform NFC DevelopmentWindows 8 Platform NFC Development
Windows 8 Platform NFC Development
 
NFC Development with Qt - v2.2.0 (5. November 2012)
NFC Development with Qt - v2.2.0 (5. November 2012)NFC Development with Qt - v2.2.0 (5. November 2012)
NFC Development with Qt - v2.2.0 (5. November 2012)
 
06 - Qt Communication
06 - Qt Communication06 - Qt Communication
06 - Qt Communication
 
05 - Qt External Interaction and Graphics
05 - Qt External Interaction and Graphics05 - Qt External Interaction and Graphics
05 - Qt External Interaction and Graphics
 
04 - Qt Data
04 - Qt Data04 - Qt Data
04 - Qt Data
 
03 - Qt UI Development
03 - Qt UI Development03 - Qt UI Development
03 - Qt UI Development
 
02 - Basics of Qt
02 - Basics of Qt02 - Basics of Qt
02 - Basics of Qt
 
Basics of WRT (Web Runtime)
Basics of WRT (Web Runtime)Basics of WRT (Web Runtime)
Basics of WRT (Web Runtime)
 
Java ME - Introduction
Java ME - IntroductionJava ME - Introduction
Java ME - Introduction
 
Intro - Forum Nokia & Mobile User Experience
Intro - Forum Nokia & Mobile User ExperienceIntro - Forum Nokia & Mobile User Experience
Intro - Forum Nokia & Mobile User Experience
 
Quickstart: Qt for Windows, Symbian and Maemo / Meego v2.0.8 (January 10th, 2...
Quickstart: Qt for Windows, Symbian and Maemo / Meego v2.0.8 (January 10th, 2...Quickstart: Qt for Windows, Symbian and Maemo / Meego v2.0.8 (January 10th, 2...
Quickstart: Qt for Windows, Symbian and Maemo / Meego v2.0.8 (January 10th, 2...
 
Qt App Development for Symbian & MeeGo - v3.4.6 (17. January 2012)
Qt App Development for Symbian & MeeGo - v3.4.6 (17. January 2012)Qt App Development for Symbian & MeeGo - v3.4.6 (17. January 2012)
Qt App Development for Symbian & MeeGo - v3.4.6 (17. January 2012)
 
Symbian OS - Mopoid Next Gen - Tutorial
Symbian OS - Mopoid Next Gen - TutorialSymbian OS - Mopoid Next Gen - Tutorial
Symbian OS - Mopoid Next Gen - Tutorial
 

Último

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Último (20)

Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 

Android Development with Kotlin, Part 2 - Internet Services and JSON

  • 1. St. Pölten University of Applied SciencesSt. Pölten University of Applied Sciences Platzhalter für möglichen Bildeinsatz Android Development with Kotlin, Part 2 Internet Services & JSON Andreas Jakl Digital Healthcare FH St. Pölten Platzhalter für möglichen Bildeinsatz Version 1.3
  • 2. Andreas Jakl ▪ Focus areas ▪ AR / VR, mobile apps, sensors, interaction technology, software architecture, open source developer (NFC, Bluetooth Beacons) ▪ Microsoft MVP (Most Valuable Professional) ▪ mobility.builders community: Mobile Developer After-Work Events ▪ Previous Experience ▪ Tieto, Start-up (Mopius), Nokia (Finland), Siemens Mobile (Munich), FH Hagenberg (Mobile Computing) Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten https://www.andreasjakl.com/ @andijakl andreas.jakl@fhstp.ac.at 2
  • 3. Contents ▪ Language Understanding Services (Microsoft LUIS) ▪ Android Menus ▪ Web Service Client / REST & HTTP Request ▪ Threads & Multitasking ▪ AsyncTask ▪ Permissions ▪ JSON Parsing ▪ Dynamic Lists ▪ RecyclerView & Adapter ▪ Click Handling Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 3
  • 4. LANGUAGE UNDERSTANDING SERVICE Control Computers using Natural Language Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 4
  • 5. Natural Language Understanding ▪ Identify information from conversations ▪ Train scenarios you want to differentiate simply by supplying examples ▪ Extract information from free-form sentences: dates, locations, numbers & more ▪ Reinforcement learning for continuous improvement ▪ Usage ▪ Chat bots, speech, analyzing text, smart speakers ▪ Services ▪ Microsoft LUIS, Amazon Comprehend, Facebook NLP, Google Cloud Natural Language, Watson Natural Language Understanding Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 5
  • 6. LUIS Architecture Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 6 client (phone) cloud (LUIS) 1. Client sends request to cloud. Query contained in URL. https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/<appid> ?subscription-key=<key>&q=Turn on lights HTTPS connection / GET request (REST)
  • 7. LUIS Architecture Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 7 client (phone) cloud (LUIS) HTTPS connection / JSON response (REST) 2. AI analyzes request, responds with results in JSON
  • 8. LUIS Architecture Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 8 client (phone) cloud (LUIS) 2. AI analyzes request, responds with results in JSON { "query": "turn on lights", "topScoringIntent": { "intent": "HomeAutomation.TurnOn", "score": 0.990858853 }, "entities": [ { "entity": "on", "type": "HomeAutomation.Operation", "startIndex": 5, "endIndex": 6, "score": 0.553411 } ] }
  • 9. Create LUIS Service ▪ Follow instructions at ▪ https://www.andreasjakl.com/using-natural-language-understanding-part- 3-luis-language-understanding-service/ ▪ Create your own vocabulary! ▪ If you like, additionally test “Home Automation” prebuilt domain: https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-get- started-create-app Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 9
  • 10. ANDROID MENUS User Interaction, in a different way Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 10
  • 11. Exercise: Create SmartHomeClient ▪ Create new project ▪ Empty Activity, Kotlin support ▪ Layout ▪ Change from ConstraintLayout to LinearLayout ▪ Add EditText, ScrollView + nested TextView Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 11
  • 12. Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 12 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="16dp" tools:context="com.andresjakl.smarthomeclient.MainActivity"> <EditText android:id="@+id/et_query_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Enter your command" android:inputType="text"/> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp"> <TextView android:id="@+id/tv_results" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:text="Results" /> </ScrollView> </LinearLayout>
  • 13. Create Menu Resource ▪ Add title for menu action to strings.xml ▪ Create new menu: ▪ Right-click res > New > Android Resource File Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 13 <string name="send">Send</string> Android MainActivity.kt onOptionsItem Selected()
  • 14. Add Menu Item ▪ Use designer to create “Menu Item” ▪ Handle menu item in MainActivity.kt ▪ Override onCreateOptionsMenu() Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 14 override fun onCreateOptionsMenu(menu: Menu?): Boolean { menuInflater.inflate(R.menu.main, menu) return true }
  • 15. Handle Tapped Menu Item ▪ Override onOptionsItemSelected() ▪ Show toast ▪ Test! Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 15 override fun onOptionsItemSelected(item: MenuItem?): Boolean { val selectedMenuItem = item?.itemId if (selectedMenuItem == R.id.action_send_command) { // TODO: Show toast! return true } return super.onOptionsItemSelected(item) }
  • 16. WEB SERVICE CLIENT REST & More – access URLs Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 16
  • 17. Build Uri ▪ Uri.Builder (Android API) ▪ Creates well-formed URI ▪ Takes care of particulars (encoding invalid characters, ? or & query codes, …) ▪ Configure parameters & URLs ▪ Best practices for securely using API keys ▪ https://developers.google.com/console/help/api-key-best-practices Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 17 private val ENDPOINT = "https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/xxx"; private val APPKEY = "yyy";
  • 18. Uri -> URL ▪ Create build function ▪ Add query parameters to base URL ▪ Convert Android Uri to Java URL Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 18 var builtUri = Uri.parse(ENDPOINT).buildUpon() .appendQueryParameter("subscription-key", APPKEY) .appendQueryParameter("q", queryText) .build() return URL(builtUri.toString()) private fun buildUrl(queryText : String) : URL { }
  • 19. Make Search Query ▪ Create function to make search query ▪ Call from menu item handler Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 19 private fun makeSearchQuery() { var queryCommand = et_query_text.text.toString() var queryUrl = buildUrl(queryCommand) Log.d(TAG, queryUrl.toString()) }
  • 20. HTTP Request ▪ Add helper function to your class Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 20 /** * This method returns the entire result from the HTTP response. * * @param url The URL to fetch the HTTP response from. * @return The contents of the HTTP response. * @throws IOException Related to network and stream reading */ fun getResponseFromHttpUrl(url: URL): String? { val urlConnection = url.openConnection() as HttpURLConnection try { val inStream = urlConnection.inputStream val scanner = Scanner(inStream) // Using pattern a (beginning of the stream) - force scanner to read // the entire contents of the stream into the next token string // -> buffers data, different data sizes are allowed, converts // from UTF-8 to UTF-16 scanner.useDelimiter("A") val hasInput = scanner.hasNext() return if (hasInput) { scanner.next() } else { null } } finally { urlConnection.disconnect() } }
  • 21. Extend makeSearchQuery() ▪ Call new function after Uri conversion ▪ Test app! Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 21 android.os.NetworkOnMainThreadException var queryResults : String? try { queryResults = getResponseFromHttpUrl(queryUrl) tv_results.text = queryResults } catch (e: IOException){ e.printStackTrace() }
  • 22. THREADS AND MULTITASKING Keeping the UI responsive Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 22
  • 23. Multi-Threading Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 23
  • 24. Single User Interface Thread Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 24
  • 25. Networking Takes Seconds Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 25 Loading … App freezes No user interaction possible!
  • 26. After ~ 5 Seconds Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 26 Loading … App freezes No user interaction possible!
  • 27. Multi-Threading Within Your App Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 27 Perform work on secondary execution thread UI stays responsive Background thread: UI thread: progress and results
  • 28. AsyncTask Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 28 Main / UI Thread Background Thread onPreExecute AsyncTask.execute() publishProgress… doInBackground onPostExecute Variable types (in AsyncTask definition)
  • 29. Create AsyncTask Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 29 Main / UI Thread Background Thread onPreExecute AsyncTask.execute() publishProgress… doInBackground onPostExecute Variable types (in AsyncTask definition) inner class WebQueryTask : AsyncTask<URL, Void, String?>() { }
  • 30. Create AsyncTask Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 30 Main / UI Thread Background Thread onPreExecute AsyncTask.execute() publishProgress… doInBackground onPostExecute Variable types (in AsyncTask definition) inner class WebQueryTask : AsyncTask<URL, Void, String?>() { } Kotlin: inner class may access members of outer class
  • 31. Set Up AsyncTask ▪ Override doInBackground() ▪ Move getResponseFromHttpUrl() into WebQueryTask class Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 31 override fun doInBackground(vararg params: URL): String? { } Kotlin: vararg = variable number of parameters Note: change URL? to URL
  • 32. Implement AsyncTask ▪ Similar to previous web service call ▪ Update UI when finished Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 32 override fun doInBackground(vararg params: URL): String? { var queryUrl = params[0] var queryResults : String? = null try { queryResults = getResponseFromHttpUrl(queryUrl) } catch (e: IOException){ e.printStackTrace() } return queryResults } override fun onPostExecute(result: String?) { tv_results.text = result }
  • 33. Test! ▪ Start thread! ▪ Test app! Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 33 java.lang.SecurityException: Permission denied (missing INTERNET permission?) android_getaddrinfo failed: EACCES (Permission denied) private fun makeSearchQuery() { var queryCommand = et_query_text.text.toString() var queryUrl = buildUrl(queryCommand) Log.d(TAG, queryUrl.toString()) WebQueryTask().execute(queryUrl) }
  • 34. PERMISSIONS Access sensitive data Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 34
  • 35. Permissions ▪ Each app gets its unique Linux user ID ▪ Runs within its own instance of an Android runtime ▪ -> completely sandboxed ▪ -> request access to resources + data outside of sandbox ▪ Permission list ▪ https://developer.android.com/guide/topics/permissions/index.html ▪ Why not just request all permissions? ▪ Users get suspicious! ▪ Think of alternatives: using camera app through Intent -> no camera permission needed for your app Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 35
  • 36. Network Permissions ▪ Add permission to AndroidManifest.xml ▪ Device: Android 6+ (API level 23+) & targetSdkVersion = 23+ ▪ Dangerous permissions acknowledged while app is running ▪ Normal permissions: granted automatically at install time, no prompts ▪ https://developer.android.com/guide/topics/permissions/normal- permissions.html ▪ Granted permissions can be revoked ▪ < 23: install-time permissions Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 36 <uses-permission android:name="android.permission.INTERNET"/>
  • 37. Final Test! Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 37
  • 38. Network Libraries ▪ More powerful libraries ▪ Include caching, compression, etc. ▪ Volley (Google) ▪ OkHttp ▪ Retrofit Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 38
  • 39. Exercise ▪ Repetition: save state of TextView to survive screen rotation! Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 39
  • 40. JSON PARSING Data Formats Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 40
  • 41. JSON Parsing Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 41 { "query": "turn on lights", "topScoringIntent": { "intent": "HomeAutomation.TurnOn", "score": 0.990858853 }, "entities": [ { "entity": "on", "type": "HomeAutomation.Operation", "startIndex": 5, "endIndex": 6, "score": 0.553411 } ] } val parsedJson = JSONObject(result) tv_top_intent.text = parsedJson.getJSONObject("topScoringIntent")?.getString("intent") val entitiesArray = parsedJson.getJSONArray("entities") if (entitiesArray != null && entitiesArray.length() > 0) { tv_top_entity_type.text = entitiesArray.getJSONObject(0)?.getString("type") }
  • 42. Exercise ▪ Add additional TextViews ▪ Parse JSON and extract information ▪ Check that your app doesn’t crash if entering strange text Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 42
  • 43. DYNAMIC LISTS Populating better lists Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 43
  • 44. Scrolling TextView? Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 44 Handle tap events on items? More complex layouts per item? Different fonts & images? Performance: keeping everything in memory? Animations & effects?
  • 45. RecyclerView Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 45Image credits: Google, https://developer.android.com/training/material/lists-cards.html Ali Connors Brunch this weekend? I’ll be in your neighborhood doing errands… 15m Layout instance 1. Layout instance scrolls out of view queue TextView TextView TextView TextView Image Layout instance 2. Placed in queue Lorem ipsum dolor sit amet consectetur adipiscing elit… 17h Layout instance 3. Filled with new content & scrolls in again
  • 46. RecyclerView RecyclerView Flow Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 46 Data source Adapter Provides new data to RecyclerView when needed Adapter binds data from data source to views ViewHolder Used to send views to RecyclerView LayoutManager Tells RecyclerView how to layout views
  • 47. Kotlin: Data Class ▪ Only contains data, no operations ▪ Auto-created utility functions ▪ Generates properties (no more getters and setters) ▪ equals(), hashCode(), toString(), copy() ▪ https://kotlinlang.org/docs/reference/data-classes.html ▪ Comparison to Java: https://antonioleiva.com/data-classes-kotlin/ Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 47 data class PartData ( val id: Long, val itemName: String) Data source
  • 48. Creating Demo Data ▪ Create some demo data in onCreate() of MainActivity Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 48 Data source var partList = ArrayList<PartData>() partList.add(PartData(100411, "LED Green 568 nm, 5mm")) partList.add(PartData(101119, "Aluminium Capacitor 4.7μF")) partList.add(PartData(101624, "Potentiometer 500kΩ")) // ...
  • 49. Create List Item Layout ▪ New layout xml file: part_list_item.xml ▪ Layout: LinearLayout (vertical) ▪ Width: match_parent ▪ Height: wrap_content ▪ Padding: 16dp ▪ Child: 2x TextView ▪ Id 1: @+id/tv_part_item_name (larger text size) ▪ Id 2: @+id/tv_part_id (smaller text size) Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 49
  • 50. Add RecyclerView ▪ Add RecyclerView to dependencies in build.gradle of app ▪ compile 'com.android.support:recyclerview-v7:26.1.0’ Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 50 RecyclerView dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.0.2' implementation 'com.android.support:recyclerview-v7:26.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' }
  • 51. ViewHolder ▪ Create class PartAdapter ▪ Create child class ViewHolder inside PartAdapter ▪ Describes item view ▪ Stores metadata about its place within RecyclerView Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 51 class PartViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { // bind() = Custom function. Copies items from supplied instance of our // "PartData" data class to the "itemView" we got through the constructor fun bind(part: PartData) { itemView.tv_part_item_name.text = part.itemName } } ViewHolder Kotlin: this is actually the primary constructor. Declares and initializes properties (here: itemView). https://kotlinlang.org/docs/reference/classes.html
  • 52. Adapter Tasks Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 52 Adapter 1. Return information, e.g., about the number of items getItemCount() 2. Create new view instances onCreateViewHolder() 3. Populate view items with data onBindViewHolder()
  • 53. Adapter Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 53 AdapterRecyclerView Data source 1. Return information, e.g., about the number of items getItemCount() 2. Create new view instances onCreateViewHolder() ViewHolder 3. Populate view items with data onBindViewHolder() id itemName 100411 LED Green 568 nm, 5mm 101119 Aluminium Capacitor 4.7μF 101629 Potentiometer 500kΩ
  • 54. Create Adapter ▪ Extend PartAdapter ▪ Derive from RecyclerView.Adapter<RecyclerView.ViewHolder> ▪ Let Android Studio write required member implementations ▪ Add parameter to PartAdapter: Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 54 Adapter (val partItemList: List<PartData>)
  • 55. Implement PartAdapter Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 55 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { // LayoutInflater: takes ID from layout defined in XML. // Instantiates the layout XML into corresponding View objects. // Use context from main app -> also supplies theme layout values! val inflater = LayoutInflater.from(parent.context) // Inflate XML. Last parameter: don't immediately attach new view to the parent view group val view = inflater.inflate(R.layout.part_list_item, parent, false) return PartViewHolder(view) } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { // Populate ViewHolder with data that corresponds to the position in the list // which we are told to load (holder as PartViewHolder).bind(partItemList[position]) } override fun getItemCount() = partItemList.size
  • 56. Add RecyclerView to MainActivity ▪ Update activity_main Layout ▪ Delete “Hello World” text ▪ Add RecyclerView Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 56 <android.support.v7.widget.RecyclerView android:id="@+id/rv_parts" android:layout_width="match_parent" android:layout_height="match_parent" />
  • 57. Wire Up RecyclerView ▪ 1. Assign LinearLayoutManager ▪ Measures and positions item views ▪ Linear list layout (default: vertical) ▪ 2. Optional optimization ▪ View contents do not change RecyclerView size Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 57 rv_parts.layoutManager = LinearLayoutManager(this) rv_parts.hasFixedSize()
  • 58. Wire Up RecyclerView ▪ 3. Assign PartAdapter to RecyclerView ▪ Supply test data we created earlier Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 58 rv_parts.adapter = PartAdapter(testData)
  • 59. Final Test! Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 59
  • 60. RECYCLERVIEW & CLICK HANDLING Advanced Topics for the Pros Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 60
  • 61. RecyclerView RecyclerView & Click Listener Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 61 Data source Adapter Click Listener ViewHolder ViewHolder ViewHolder bind() function assigns data & click handler callback to view holder instances Click event executes registered click handler callback function
  • 62. Higher-Order Functions ▪ Function that ▪ Takes another function as parameter, or ▪ Returns a function ▪ Lambda ▪ Surrounded by { } ▪ Parameters -> Return type Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 62
  • 63. Experiments I: Class with Parameters ▪ Create a class that has parameters ▪ Note that you can use the parameters as properties Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 63 /** * Defines a class with a constructor. Its parameters are automatically available * as properties in the class. Note that the keyword "constructor" is optional * and could be stripped. */ class ClassWithConstructorProperties constructor (var a: Int, var b: Int) { fun calculate() : Int { return a + b; } } // Create new class instance var calcTest = ClassWithConstructorProperties(10, 20) // Print calculation results Log.d("Tests", "Calculation result: " + calcTest.calculate())
  • 64. Experiments II: Function Parameters ▪ Define a function with a function parameter ▪ Specify structure the supplied function must fulfil ▪ Parameter performCalculation is of type: (parameter types) -> return type ▪ When calling: ▪ Supply a function as lambda expression that matches the parameter ▪ Return type is inferred automatically if not Unit (= void in Java) Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 64 private fun testFunctionParameters(performCalculation: (Int, Int) -> Int) { Log.d("Tests", "Calculation result: " + performCalculation(1, 2)) } testFunctionParameters( {a : Int, b : Int -> a + b } )
  • 65. Adapter with Click Listener ▪ 1. Add 2nd parameter to PartAdapter constructor ▪ Function parameter ▪ Reqiures PartData as parameter, no value is returned (“Unit”) Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 65 class PartAdapter (val partItemList: List<PartData>, val clickListener: (PartData) -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
  • 66. View Holder with Click Listener ▪ 2. Assign click listener in PartViewHolder ▪ Assigned to the whole view, not just a Button / TextView / … ▪ Supply click listener as 2nd parameter of bind() function Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 66 class PartViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(part: PartData, clickListener: (PartData) -> Unit) { itemView.tv_part_item_name.text = part.itemName itemView.tv_part_id.text = part.id.toString() itemView.setOnClickListener { clickListener(part)} } }
  • 67. Assign Click Listener ▪ 3. When Adapter binds ViewHolder, assign click listener ▪ clickListener part of constructor in PartAdapter ▪ -> automatically available as property in the PartAdapter class Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 67 override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { // Populate ViewHolder with data that corresponds to the position in the list // which we are told to load (holder as PartViewHolder).bind(partItemList[position], clickListener) }
  • 68. Handle Clicks in MainActivity ▪ 4. Write function in MainActivity to handle clicked items ▪ 5. Extend construction of PartAdapter, supply function parameter Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 68 private fun partItemClicked(partItem : PartData) { Toast.makeText(this, "Clicked: ${partItem.itemName}", Toast.LENGTH_LONG).show() } rv_parts.adapter = PartAdapter(testData, { partItem : PartData -> partItemClicked(partItem) })
  • 69. Final Test! Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 69
  • 70. Exercise: Detail Page ▪ Create a DetailActivity ▪ Shows part details ▪ Extend click handler in MainActivity ▪ Launch second activity ▪ Pass data via Intent Extras Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 70
  • 71. THANK YOU! Android Development with Kotlin, Part 2 | 2018 | Andreas Jakl | FH St. Pölten 71