Differences

This shows you the differences between two versions of the page.

Link to this comparison view

fss:sessions:session2-android [2019/06/24 15:55]
beniamin.dobre created draft
fss:sessions:session2-android [2019/07/04 16:01] (current)
adriana.draghici [Session 2: Android Server Communication & Security]
Line 1: Line 1:
  
-====== Session 2: Android ​Server Communication & Security ======+====== ​Android ​Session 2: Server Communication & Security ======
  
 ===== Objectives ===== ===== Objectives =====
-  * Learn to make secure network calls+  * Learn to make secure network calls using the Retrofit network library
   * Learn how to use a RecyclerView List and a Dialog   * Learn how to use a RecyclerView List and a Dialog
-  * Learn how to use an API using the Retrofit network library+  * Learn how to interact with a public ​API 
  
 ===== Prerequisites ===== ===== Prerequisites =====
Line 18: Line 18:
  
 ===== Project Structure ===== ===== Project Structure =====
 +
 +{{ :​fss:​sessions:​screen_shot_2019-06-25_at_17.07.56.png?​200 |}}
 +
 +//​EmployeeData//​ is a data object that holds information about an Employee (id, name, age, salary). In order to be serializable as a Json we need to add the @SerializedName("​employee_name"​) annotation and a provided name. The provided name should correspond to the ones in the [[http://​dummy.restapiexample.com/​employee|API]] we use. 
 +
 +//​EmployeeApiService//​ holds the interface with the requests we will make to the server
 +
 +//​MainActivity//​ is the main screen of the app and also creates the Retrofit Service. The main content of the screen is a RecyclerView with the list of all employees. By long pressing on an item the user can delete an entry and if the user presses the Floating Button he will open a form to add a new entry.
 +
 +//​MyListAdapter//​ is a RecyclerView.Adapter See more [[https://​developer.android.com/​guide/​topics/​ui/​layout/​recyclerview#​Adapter|Here]]
 +
 +===== Using Retrofit =====
 +//This section is adapted from [[http://​ocw.cs.pub.ro/​courses/​smd/​laboratoare/​05?&#​retrofit|Here]]//​
 +
 +[[https://​square.github.io/​retrofit/​|Retrofit]] is a type-safe HTTP Client for Android and Java. The basic functionality it is to turn the HTTP API into a Java interface. ​
 +
 +When working with retrofit you need to consider the following:
 +  * How is the data transmitted. For example, one popular way is to use JSON objects. Retrofit can handle their conversion to Java objects
 +  * A **model** for the data you need transmitted
 +    * this is usually a class with fields that reflect the JSON schema you use in your requests. In our app it will be called EmployeeData.java
 +  * Define the endpoints and the requests you need to make in an interface, we refer to it as **service** (not to be confused with Android services) In our case it will be the EmployeeApiService.java interface
 + 
 +
 +Basic steps for using this library:
 +  - Add dependencies in the build.gradle file of your project (see example below)
 +  - Add the INTERNET permission in the manifest file
 +  - Create the classes for your model
 +  - Define the requests and endpoints you need
 +     * create "​service interfaces"​ and use [[https://​futurestud.io/​tutorials/​java-basics-for-retrofit-annotations|annotations]] such as @GET, @POST to define the operations you need.
 +  - Create a retrofit instance and provide it the service interface
 +  - Make calls to the api by calling the service'​s methods.
 +     * provide callbacks to the calls in order to react to the results or failures
 +
 +
 +In this section'​s code examples we're going to create basic HTTP GET / POST / DELETE request for the employee API service. ​
 +
 +As stated above in Retrofit we only need to declare our service interface. Below we declared our //​EmployeeApiService//​ which has a //GET// request for the employee list, a //POST// to create a new entry and a //DELETE// request to remove an employee from the list using his id. Retrofit uses [[https://​docs.oracle.com/​javase/​tutorial/​java/​annotations/​|Annotations]] to show how a request will be handled. In our case we simply defined in the GET request the path to the employee API endpoint. For the DELETE we will also need to add the //​{userId}//​ parameter using //{}//. In order to complete this we added the //​@Path("​userId"​)//​ annotation before the userId parameter. This way we link the method parameter to the URL parameter. ​
 +
 +<​code>​
 +public interface EmployeeApiService {
 +    @GET("​employees"​)
 +    Call<​List<​EmployeeData>>​ getUserDetails();​
 +
 +    @POST("​create"​)
 +    Call<​EmployeeData>​ createUser(@Body EmployeeData employeeData);​
 +
 +    @DELETE("​delete/​{userId}"​)
 +    Call<​ResponseBody>​ deleteEmployeeById(@Path("​userId"​) int userId);
 +}
 +</​code>​
 +
 +From here the [[https://​square.github.io/​retrofit/​2.x/​retrofit/​retrofit2/​Retrofit.html|Retrofit]] class generates an implementation of the EmployeeApiService interface. When creating the Retrofit instance we need to pass our //​baseUrl//​. Using this and appending the requests path will create the complete URL.
 +
 +<​code>​
 +apiService = (new Retrofit.Builder())
 +                .baseUrl("​http://​dummy.restapiexample.com/​api/​v1/"​)
 +                .build()
 +                .create(EmployeeApiService.class);​
 +</​code>​
 +
 +Using the service we can make the [[https://​square.github.io/​retrofit/​2.x/​retrofit/​retrofit2/​Call.html|Call]] that will make synchronous or asynchronous HTTP request to the remote WebServer.
 +
 +<​code>​
 +Call<​List<​EmployeeData>>​ employeeCall = apiService.getUserDetails();​
 +</​code>​
 +
 +In order to make the call and get the result in our app will need to call [[https://​square.github.io/​retrofit/​2.x/​retrofit/​retrofit2/​Call.html#​enqueue-retrofit2.Callback-|enqueue()]]. This sends asynchronously the request and notifies the application through the //​onResponse()//​ callback when a response is received or through //​onFailure()//​ callback if something goes wrong. This call is handled on a background thread by Retrofit. ​
 +
 +<​code>​
 +employeeCall.enqueue(new Callback<​List<​EmployeeData>>​() {
 +            @Override
 +            public void onResponse(Call<​List<​EmployeeData>>​ call, Response<​List<​EmployeeData>>​ response) {
 +                // Do some cool stuff with the response
 +            }
 +
 +            @Override
 +            public void onFailure(Call<​List<​EmployeeData>>​ call, Throwable t) {
 +                // Show error message
 +            }
 +        });
 +</​code>​
 +
 +If the service responds with [[https://​www.json.org/​|JSON]] objects, Retrofit can help deserialize them by using //​converters//​. A popular JSON library is [[https://​github.com/​google/​gson|GSON]]. This helps converting JSON responses into [[https://​en.wikipedia.org/​wiki/​Plain_old_Java_object|POJO]]s. In order to use this we need to add a [[http://​square.github.io/​retrofit/​2.x/​converter-gson/​retrofit2/​converter/​gson/​GsonConverterFactory.html|GsonConvertorFactory]] when creating the service:
 +
 +<​code>​
 +apiService = (new Retrofit.Builder())
 +                .addConverterFactory(GsonConverterFactory.create())
 +                .baseUrl("​http://​dummy.restapiexample.com/​api/​v1/"​)
 +                .build()
 +                .create(EmployeeApiService.class);​
 +</​code>​
 +
 +In order to add the two libraries to our application we need to add them as dependencies in the //​app/​build.gradle//​ configuration file.
 +
 +<​code>​
 +dependencies {
 +    implementation '​com.squareup.retrofit2:​retrofit:​2.5.0'​
 +    implementation "​com.squareup.retrofit2:​converter-gson:​2.5.0"​
 +}
 +</​code>​
  
 ===== Tasks ===== ===== Tasks =====
 +  * **Fix the Crash when starting the app.**
 +
 +  * **Get and display the age of the employee:** In the example provided in the zip file the "​employee_age"​ field is not parsed from the response we get in the requests. Add the necessary code in the EmployeeData class to get it and also display it in the RecyclerView
 +<spoiler Hint: how to display the age>​Hint:​ In order to display it you will have to add a TextView in the list_item_layout.xml and manage it in the MyListAdapter </​spoiler>​
 +
 +  * **Make a Delete entry request:** You will need to add a new method in the EmployeeServiceApi and make the Retrofit call in the MainActivity.
 +
 +  * //**Bonus Task:**// When pressing the Floating Add Button open a form screen (could be a Dialog or a new Activity) with the fields needed to create a Employee. On pressing a "​Save"​ button create the Retrofit Call to add the new entry   
 +
 +  * //**Bonus Task:**// Add fingerprint login to the app. See [[https://​developer.android.com/​topic/​security/​best-practices#​ask-for-credentials|Fingerprint login]] for details on how you can do it
 +
 +
 +  * //**Bonus Task:**// Check the connectivity to the Internet and display a message when not connected
  
 ===== Resources ===== ===== Resources =====
 +  - [[https://​drive.google.com/​open?​id=1_plcVwNmo0S8OoBBa90Wwfvmbx-IZZ8J|Slides]]
   - [[https://​ocw.cs.pub.ro/​courses/​smd/​laboratoare/​index|Android Labs for SMD course]] - created in Spring 2019 by Fitbit developers   - [[https://​ocw.cs.pub.ro/​courses/​smd/​laboratoare/​index|Android Labs for SMD course]] - created in Spring 2019 by Fitbit developers
 +  - [[https://​square.github.io/​retrofit/​|Retrofit Main Page Link]] - A type-safe HTTP client for Android and Java
 +  - [[http://​dummy.restapiexample.com/​|Public API]] Public API used in this Session
 +  - [[https://​developer.android.com/​guide/​topics/​ui/​layout/​recyclerview|RecyclerView List]] RecyclerView Android Documentation
 +
 +
 +===== Files =====
 +{{:​fss:​sessions:​lab-2-android-retrofit.zip|}}
fss/sessions/session2-android.1561380958.txt.gz ยท Last modified: 2019/06/24 15:55 by beniamin.dobre
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0