Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Department of Information Engineering, CUHK MScIE – 2nd Semester, 2016/17 IEMS 5722 Mobile Network Programming and Distributed Server Architecture Lecture 12 Advanced Android Programming Lecturer: Albert C. M. Au Yeung 30th March, 2017 Google Play Services 2 Google Play Services • Google Play Services is a set of cloud services and APIs for Android devices • Version 8.4 released 18 Dec, 2015 • Allows you to integrate various services from Google into the mobile app • Some of Google’s services include › Location detection › Geocoding and reverse geo-coding › Maps API (e.g. navigation, street views) › Google drive for cloud storage › Google Wallet for online payment 3 Google Play Services Google Services API Requests and Responses Google Play App Store Automatic Update Your Mobile App GMS Client Library An Android Device Google Play Services APK 4 Google Play Services Setting up Google Play Services • Download latest Google Play services SDK • Update your build.gradle file (Refer to the link below) Reference: https://developers.google.com/android/guides/setup 5 Accessing Google APIs To access various Google APIs, you need to create an instance of GoogleApiClient • Acts as a common entry point to all Google services • Manages network connection between the device and each service Reference: https://developers.google.com/android/guides/api-client 6 Accessing Google APIs public class MyActivity extends FragmentActivity implements OnConnectionFailedListener { private GoogleApiClient mGoogleApiClient; You can create an instance of GoogleApiClient with connection to specific APIs by using a builder: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } } // Create a GoogleApiClient instance mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .build(); // ... @Override public void onConnectionFailed(ConnectionResult result) { // An unresolvable error has occurred and a connection to Google // APIs could not be established. Display an error message, // or handle the failure silently // ... } 7 Google APIs for Android For a list of Google APIs for Android, see: • https://developers.google.com/android/ 8 Location Detection 9 Location Detection • Location detection is one of the most commonly used features of smartphones • Many apps offers location-based services, e.g.: Ø Maps, transportation and navigation Ø Location-based social networking Ø Tracking Ø News Ø Weather forecast Ø ... 10 Location Detection • Mobile phones can detect locations by using a variety of data sources 1. GPS (Global Positioning System) 2. Information of base stations (Cell ID) (e.g. http://opencellid.org/) 3. Wi-Fi + IP Address 4. Others 11 Location Detection • Android provides simple APIs that return user’s current location by combining the input from different sources Android Framework’s Location APIs (android.location) Google Play Services Location APIs (com.google.android.gms.location) Preferred Option 12 Google Play Services Location APIs • If your app needs to use location services, you need to request permission from the user • Two permissions: 1. ACCESS_COARSE_LOCATION (accurate to the level of a city block) 2. ACCESS_FINE_LOCATION (accurate to a few metres) <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 13 Google Play Services Location APIs • The flow of setting up the app to use the location APIs 2 1 Connect to Google Play services 3 Set up a location request with parameters Request location updates from the API 4 5 Obtain the last known location of the phone Receive location updates 14 1. Connecting to Google Play Services • Firstly, you need to get an instance of the Google Play services API client GoogleApiClient mGoogleApiClient; protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } Adding the location service API here NOTE: We do not enable auto-management of connection here. 15 1. Connecting to Google Play Services • Connect the API client when the activity is started, and disconnect when it is stopped @Override protected void onStart() { super.onStart(); if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } } @Override protected void onStop() { if (mGoogleApiClient != null) { mGoogleApiClient.disconnect(); } super.onStop(); } 16 1. Connecting to Google Play Services • To receive status updates from the API client, your activity need to implements some interfaces and callback functions import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationListener; public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { ... } 17 2. Setting up a Location Request • The Location APIs will notify your app when it has an updated information about the location of the user • You need to submit a request to receive location updates Android System Submit location request with parameters Send location updates when there is changes or according to a preset frequency Your App 18 2. Setting up a Location Request • Creating a location request: protected void createLocationRequest() { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(10000); mLocationRequest.setFastestInterval(5000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); } • Interval (ms): how frequent you would like to receive updates • Fastest Interval (ms): the fastest rate at which your app will receive updates • Priority: Different priority settings affect power consumption (ref.: https://developer.android.com/training/location/receive-location-updates.html) 19 3. Request Location Updates • Once the API client is connected, you can submit your location request: @Override public void onConnected(Bundle connectionHint) { ... LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, mLocationRequest, this); ... } You need to pass to this method a location listener. If your activity has implemented the location listener interface, you can provide the reference of the current activity here. 20 4. Obtain the Last Known Location • Usually it takes some time before you will receive the first location update • You can obtain the “last known location” of the user first, so that you can start executing some functions in your app ... @Override public void onConnected(Bundle connectionHint) { mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation != null) { mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude())); mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude())); } } ... 21 5. Receiving Location Updates • Finally, set up the callback functions so that you can receive location updates ... @Override public void onLocationChanged(Location location) { mCurrentLocation = location; mLastUpdateTime = DateFormat.getTimeInstance().format(new Date()); ... // Perform actions based on the updated location // e.g. update the UI, alert the user, etc. } ... 22 Stop Receiving Location Updates • To save power, you should stop requesting location updates when it is no longer necessary. For example: @Override protected void onPause() { super.onPause(); LocationServices.FusedLocationApi.removeLocationUpdates( mGoogleApiClient, this); } @Override public void onResume() { super.onResume(); if (mGoogleApiClient.isConnected()) { LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, mLocationRequest, this); } } 23 Using Google Maps 24 Using Google Maps in Your App • You can embed an interactive map in your app by using Google Maps Android API • Google Maps functions include: Ø Provide interactive maps with 3D maps, satellite view, terrain view, road maps, etc. Ø Allow overlaying of different components, such as markers, polygons, etc. Ø Control user’s view such as rotation, zoom, pan Ø Street view 25 Getting Started • To embed Google Maps in your app, you need to set up your app and obtain an API key from Google • Follow the instructions at: https://developers.google.com/maps/documentation/android/start • Once you have a key, add it to your manifest file: <meta-data android:name="com.google.android.geo.API_KEY" android:value="API_KEY"/> 26 Adding a Map to Your App • To add a map to your activity, add a fragment with android:name equals to “com.google.android.gms.maps.MapFragment”: <?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:name="com.google.android.gms.maps.MapFragment" android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent"/> 27 Adding a Map to Your App • To control the map, in the code of the activity, you need to obtain the map object: public class MainActivity extends FragmentActivity implements OnMapReadyCallback { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); MapFragment mapFragment = (MapFragment) getFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } } @Override public void onMapReady(GoogleMap map) { map.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker")); } 28 Other Maps SDKs • Nokia HERE Map https://developer.here.com/ • OpenStreetMap http://www.openstreetmap.org/ • Baidu Map http://lbsyun.baidu.com/sdk/download 29 Geocoding & Reverse Geocoding 30 Geocoding & Reverse Geocoding Geocoding • Converting an address to a geographic location (latitude/longitude) Reverse Geocoding • Converting a geographic location (latitude/longitude) to an address Both of these functions can be performed by using the Geocoder class in Android 31 Reverse Geocoding Reverse Geocoding • In a mobile app, you might need want to let the user choose a location on the map, and then retrieve the address of that location (or when you need to locate the user using GPS/Wi-Fi signals) • To use reverse geocoding, you need a precise geolocation, therefore you should ask for the ACCESS_FINE_LOCATION permission • You can use the Geocoder class to perform reverse geocoding (see next page) Reference: http://developer.android.com/training/location/display-address.html 32 Reverse Geocoding • The function getFromLocation is a blocking and may take a long time (several seconds) to response • You should not execute this on the UI thread • Instead, you should use one of the following methods › AsyncTask › Intent service (IntentService) with result receiver (ResultReceiver) or local broadcasting (LocalBroadcastManager) 33 Geocoding • Similarly, you can obtain a geolocation by providing a address (i.e. geocoding) • For example: String address = "The Chinese University of Hong Kong, Shatin, Hong Kong"; List<Address> list = null; try { addresses = geocoder.getFromLocationName(address, 1); } catch (IOException ioException) { // Catch network or other I/O problems } catch (IllegalArgumentException illegalArgumentException) { // Catch invalid latitude or longitude values } 34 Other Cloud Services 35 Cloud Services & APIs • Facebook https://developers.facebook.com/ • Instagram https://www.instagram.com/developer/ • WeChat https://open.weixin.qq.com/ • Baidu http://developer.baidu.com/ • YouTube https://www.youtube.com/yt/dev/ • IBM Developer Cloud https://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/ 36 Auto-complete Text Views 37 Auto-complete Text Views • A text view that automatically suggests words or phrases for input while the user is typing • Useful when you allow the user to perform searching and input specific information (e.g. country names, addresses, etc.) • You can use one of the following classes depending on your requirements › AutoCompleteTextView › MultiAutoCompleteTextView 38 Auto-complete Text Views • Adding AutoCompleteTextView to your Activity <AutoCompleteTextView android:id="@+id/ac1" android:layout_width="match_parent" android:layout_height="wrap_content“/> 39 Auto-complete Text Views • Auto-complete involves providing a candidate list, this is done by using an adapter (similar to what you do when using ListView) • For example, the following use a pre-defined string array as a candidate list AutoCompleteTextView ac = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1); String[] countries = new String[] { “Algeria”, “Belgium”, “Canada”, “Denmark”, “Ethiopia”, “France” }; ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, countries); ac.setAdapter(adapter); 40 Auto-complete Text Views • What if you don’t want to hard-code the list of candidates in the app? • You need to send the intermediate input of the user to the server, and use the data returned by the server to update the data in the adapter User input texts in the AutoCompleteTextView Extract data from the response of the server Submit texts input by the user to the server Update data in the adapter of the AutoCompleteTextView 41 ac.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { final String query = s.toString().trim(); if (query.length() > 1) { AsyncHttpClient client = new AsyncHttpClient(); RequestParams params = new RequestParams(); params.put("query", query); client.get(url, parmas, new TextHttpResponseHandler() { @Override public void onSuccess( int statusCode, Header[] headers, String response) { // Extract data ... // Update data of the adapter ... adapter.notifyDataSetChanged(); } }); } } }); 42 MultiAutoCompleteTextView • MultiAutoCompleteTextView allows user to input multiple items separated by a separator (e.g. a comma) • Suggestions will be provided for the latest item in the text view 43 Gradle 44 Gradle • Gradle is the official build tool for Android applications • It helps you build (compile), test, run and package your apps • It is integrated into Android Studio through the Android Gradle Plugin • It can also be executed independently from the command line Reference: http://gradle.org/ 45 Gradle • The Gradle build process 46 What are the benefits? • Using Gradle allows you to › Configure and customise the build process › Create different versions of your app with different features, settings or parameters under the same project › Easily incorporate third-party modules into your application 47 Build Configuration • An Android Studio project contain a top-level build file and a build file for each module (‘app’ is a module in the project) • The build files are all named ‘build.gradle’ • In most cases, you only need to modify the build files at the module level Reference: http://developer.android.com/tools/building/configuring-gradle.html 48 apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.2" Apply the Android plugin for Gradle in this build Build Configuration defaultConfig { Configure the core settings and entries applicationId "hk.edu.cuhk.ie.iems5722" minSdkVersion 15 in the AndroidManifest.xml file targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { Specify different build release { types. The two default build minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), types are “debug” and 'proguard-rules.pro' “release”. } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.1.1' } Declare dependencies to libraries, jar files, remote packages 49 Product Flavours • When publishing an app, you might want to publish different variants of the app, which features different functions • You can specify different “product flavours” in the build.gradle file, and specify their individual parameters } productFlavors { pro { applicationId = "com.iems5722.pro" } free { applicationId = "com.iems5722.free" } buildTypes { debug { applicationIdSuffix ".debug" } } 50 Using BuildConfig • You can specify constant values in the build.gradle file, and use them in your Java code • When building, different build types or product flavours will use the corresponding values automatically • Steps: 1. Specify constant values in build.gradle using buildConfigField 2. Use the values in your Java code using the BuildConfig class 51 Using BuildConfig android { buildTypes { debug { buildConfigField ‘int’, ‘CREDITS’, ‘10000’ buildConfigField ‘String’, ‘APP_NAME’, ‘“APP DEBUG VERSION”’ buildConfigField ‘boolean’, ‘LOG’, ‘true’ } } } release { buildConfigField ‘int’, ‘CREDITS’, ’10’ buildConfigField ‘String’, ‘FOO_STRING’, ‘“APP”’ buildConfigField ‘boolean’, ‘LOG’, ‘false’ } 52 Using BuildConfig public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); int credits = BuildConfig.CREDITS; String app_name = BuildConfig.APP_NAME; boolean log = BuildConfig.LOG; } ... } 53 Using BuildConfig • In developing client-server systems, one scenario in which you will use BuildConfig is to specify the URL to the APIs for the debug and release build types of your app android { buildTypes { debug { buildConfigField ‘String’, ‘DOMAIN’, ‘dev.myapp.com’ } } } release { buildConfigField ‘int’, ‘DOMAIN’, ‘api.myapp.com’ } 54 ProGuard 55 ProGuard • ProGuard is a tool that helps you shrinks, optimises, and ofuscates the codes of your app • It does so by removing unused code, renaming classes, fields, and methods with semantically obscure names • Why? › Creates an APK file with smaller size › Makes the app more difficult to reverse engineer Reference: http://developer.android.com/tools/help/proguard.html http://proguard.sourceforge.net/ 56 ProGuard • ProGuard will only be run when you build your application in release mode (and if you have enabled it) • To enable ProGuard: android { ... } Set minifyEnabled to true buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } The file containing the } customised rules 57 Configuring ProGuard • In some cases, ProGuard might not analyse your code correctly, and might remove codes that are actually required in your app • You should specifically ask ProGuard to not modify some of the codes in your app when necessary • Whenever you see ClassNotFoundException when building your app for release, you can add lines in the following format to the proguard-rules.pro files in the app module -keep public class com.iems5722.app.MyClass001 58 Project Presentations 59 Project • To facilitate testing and marking, please name the package of your app using the following format: com.iems5722.groupX (Replace X with your group number) • Send your app’s APK file (or a link to that file if it is too large) to my email ([email protected]) before the end of 26th April, 2017 (Wednesday) • The APK files will be shared to the class so that everyone can try your apps 60 Project Presentations • You will have your project presentations on 27th April, 2017 (Thursday) • Each group will have 6 minutes to present their app • Your presentation slides should follow the format below: 1. Introduction: what is the app you have developed? (1 slides) 2. Functions: what are the major functions? (1-2 slides with screenshots) 3. Demonstration: 3 mins video (a trial run / an example usage / demonstrate most important features) 4. What is the most challenging part? (name 1 issue, and describe how you solved it) 5. What additional things will you add if you have more time? 61 Project Presentations • Send you a link to the project report and all source codes to my email ([email protected]) on or before 4th May, 2017 (Thursday) • What should you include in your report: 1. Problem definition what problem does your app try to solve? 2. Features / Functions what are the major (networking) functions of the app? (with screenshots) 3. System architecture (use diagrams and illustrations to describe how does the system (client/server) works) (no need to describe specific implementation of the UI) 4. How would you further improve it? 5. A list of third party libraries that you have used in your project 62 End of Lecture 12 Looking forward to your project presentations! 63