mobile application development · 2018. 9. 21. · storage in local databases •android has full...

66
Mobile Application Development MTAT.03.262 Jakob Mass [email protected]

Upload: others

Post on 24-Sep-2020

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Mobile Application Development

MTAT.03.262

Jakob Mass

[email protected]

Page 2: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Recap from last lecture

• Views & Layouts• Nesting

• LinearLayout, ConstraintLayout

• Fragments

• Intents & Components• Basic introduction to application components

• Intents & Intent Filters

• Launching Activities

• Context

Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 221/09/2018

Page 3: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

This lecture

• Other Application Components• Broadcast Receivers

• Content Providers

• Services

• Data Storage• File access

• Working with databases

• Handling Background tasks

• Home Assignment 1 (and HW3)

Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 321/09/2018

Page 4: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Broadcast Receivers

• Allows your app to receive events outside of user flow• System level messages

• E.g. Boot finished, picture was captured, charger connected

• App-initiated:• Data finished downloading & ready to use

• An entry-point to your app

• With System events, Android runtime notifies all receivers registered to that event• E.g. register for ACTION_BOOT_COMPLETED

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 4

https://developer.android.com/guide/components/broadcasts

Page 5: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Implementing a Broadcast receiver• Implement as subclass of BroadcastReceiver

• Receive Intent broadcast objects withonReceive(Context context, Intent intent)

• The Intent object may contain additional info• As we discussed last lecture

• E.g. the Intent for Airplane mode changing has a Boolean extra

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 5

https://developer.android.com/guide/components/broadcasts

Page 6: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Implementing a Broadcast receiver: Java

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 6

public class MyReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent){

// react to the broadcast event

}

}

Page 7: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Receiving broadcasts (1)

To register for a given type of broadcast, either:

• Declare the BroadcastReceiver in the Manifest:

The system launches your app if not running when broadcast is sent

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 7

https://developer.android.com/guide/components/broadcasts

<receiverandroid:name=".MyReceiver"android:enabled="true"android:exported="true"><intent-filter>

<action android:name="android.intent.action.BATTERY_LOW"></action>

</intent-filter></receiver>

Page 8: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

.. Or register using Context

• In this case, the lifecycle of the context influences how long the receiver can get events!

BroadcastReceiver br = new MyReceiver();

IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);

filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);this.registerReceiver(br, filter);// later:this.unregisterReceiver(br);

Receiving broadcasts (2)

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 8

https://developer.android.com/guide/components/broadcasts

Page 9: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Receiving implicit broadcasts

• Since API ver. 26, implicit broadcasts should not be declared in the manifest

• Instead, use the programmatic approach

• Currently, there’s a list of exceptions to this:• https://developer.android.com/guide/components/broa

dcast-exceptions

• The recommended approach is to use JobSchedulers

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 9

Page 10: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Sending Broadcasts

• LocalBroadcastManager.sendBroadcast( … )• Sent to receivers within your app• More performant

• sendBroadcast(Intent)• Sent to all receivers

• sendOrderedBroadcast(Intent, String) • Sent to all receivers, but one at a time• Order is specified with android:priority attribute of the

matching intent-filter• Can chain the broadcast

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 10

https://developer.android.com/guide/components/broadcasts#sending-broadcasts

Intent intent = new Intent();

intent.setAction("com.example.broadcast.MY_MESSAGE");

intent.putExtra("data","My custom message");

sendBroadcast(intent);

Page 11: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Example: logging the number of a call

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 11

public class CallReceiver extends BroadcastReceiver {String TAG = "CallReceiver";

@Overridepublic void onReceive(Context context, Intent intent) {

if (intent.getExtras() != null){String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);Log.i(TAG, state);

//System receives 2 “RINGING” broadcasts: 1 with number and 1 withoutif (intent.hasExtra(TelephonyManager.EXTRA_INCOMING_NUMBER)){

String phoneNo = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

Log.i(TAG, phoneNo);}

}

}}

Page 12: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Example (2) – registering the receiver

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 12

<receiver android:name=".CallReceiver"android:enabled="true"android:exported="true"><intent-filter>

<action android:name="android.intent.action.PHONE_STATE"></action>

</intent-filter></receiver>

Page 13: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

System Permissions

• Divided into 2 categories: normal and dangerous

• Normal:• Do not directly risk user’s privacy• E.g. setting the time zone• If declared in manifest, system grants the permissions

automatically

• Dangerous:• May give app access to user’s confidential data• In addition to listing the permissions in the manifest,

app has to ask user for each individual permission when running

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 13

https://developer.android.com/guide/topics/permissions/overview#normal-dangerous

Page 14: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Permissions example for Receiving Phone Calls

1. Declare in manifest ↑

2. Request permission from user in Activity:

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 14

https://developer.android.com/reference/android/telephony/TelephonyManager#ACTION_PHONE_STATE_CHANGED

String[] requestedPermissions = new String[]{Manifest.permission.READ_PHONE_STATE,Manifest.permission.READ_CALL_LOG

};ActivityCompat.requestPermissions(this, requestedPermissions, 1);

<uses-permission android:name="android.permission.READ_PHONE_STATE"/><uses-permission android:name="android.permission.READ_CALL_LOG"/>

@Overridepublic void onRequestPermissionsResult( … ) {

// User has made a choice, check & react to results}

Page 15: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Exercise 1

• Repeat call logging example

• Don’t forget about permissions

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 15

Page 16: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Data Storage with Android

• Storage in ‘normal’ files• External & internal storage

• Using Preference files

• Using local databases• Structured data with e.g. SQLite

• Network Storage (not part of this lecture)

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 16

https://developer.android.com/guide/topics/data/data-storage

Page 17: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

File storage (Internal)

• The default file save location is the Internal storage• Private to your app (even user cannot access)

• System provides a private directory for each app• Specified by package name

• Internal storage removed upon uninstall!

• getFilesDir()

• openFileInput()

• openFileOutput()

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 17

https://developer.android.com/training/data-storage/files#WriteInternalStorage

File file = new File(context.getFilesDir(), "foo.txt");

Page 18: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Internal Storage example

• Using openFileOutput, note the 2nd argument (file mode)• MODE_PRIVATE• MODE_WORLD_READABLE, MODE_WORLD_WRITEABLE –

deprecated since API 17!

getCacheDir()• Returns File for apps cache directory• Should keep usage low• System deletes files here when disk space is running out

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 18

https://developer.android.com/training/data-storage/files#WriteInternalStorage

String FILENAME = "myfile.txt";

FileOutputStream fos =

openFileOutput(FILENAME, Context.MODE_PRIVATE);

fos.write("Hello, file!".getBytes());

fos.close();

Page 19: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Exercise 2

• Working with files• Try to write a string to a file

• Then, read back the contents of the file

• Try to see that they are the same

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 19

Page 20: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

External Storage

• World-readable and modifiable by user

• Potentially removable – e.g. SD card

• Apps still need permissions to access:• android.permission.READ_EXTERNAL_STORAGE• android.permission.WRITE_EXTERNAL_STORAGE

• This is the right place to store data that survives application uninstall – e.g. photos, documentsThere is also an option to use ext. storage for app-

specific storage that is removed upon uninstalled and other apps cannot access (e.g. you don’t want to waste internal storage space)

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 20

https://developer.android.com/training/data-storage/files#WriteExternalStorage

Page 21: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

External Storage - continued

1. Make sure you have the right permission

2. Verify storage is available!Environment.getExternalStorageState() – returning• Environment.MEDIA_MOUNTED• Environment.MEDIA_MOUNTED_READ_ONLY• ..

3. Open directory• Public - getExternalStoragePublicDirectory()• Private - getExternalFilesDir()• Argument determines file type: e.g.

Environment.DIRECTORY_PICTURES, DIRECTORY_RINGTONES, can also use null

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 21

Page 22: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Ext. Storage: Scoped Directory access

• An API for accessing common external directories

• In cases where you are targeting specific directories• Avoid requesting READ_EXTERNAL_STORAGE

• Provides a simple permissions UI that clearly details what directory the application is requesting access to

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 22

https://developer.android.com/training/articles/scoped-directory-access

Page 23: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Summary of Internal/External Storage• Internal Storage

• Always available

• Files saved here accessible by only your app

• Files deleted when your app is uninstalled

• External storage• World-readable, outside of your control

• Files deleted during uninstall only if you save them to Private external storage directories (getExternalFilesDir())

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 23

Page 24: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Storage in Preference files

• For storing a “small” collection of key-value pairs• Light-weight & easy to use• Not shareable across applications• SharedPreferences object

• Points to a file containing the data• Provides simple read/write methods

• Create/access a preferences file with:• getSharedPreferences(String name, int mode)

• File identified with custom name• Call with any Context

• getPreferences()• Call from Activity Context• Single, default file for that activity

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 24

https://developer.android.com/training/data-storage/shared-preferences

Page 25: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

SharedPreferences Examples

• Recommended to prefix the preferences file with your app ID, e.g. “com.example.myapp.MY_PREFERENCE_FILE”

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 25

SharedPreferences prefs = getSharedPreferences(

getString(R.string.pref_file_key),

Context.MODE_PRIVATE);

// Changes to preference file are

// done using an Editor object

SharedPreferences.Editor editor = prefs.edit();

editor.putInt("highScore", newHighScore);

editor.commit(); // or apply() for asynchronous writing

// Read values:

prefs.getBoolean("silentMode", false);

Page 26: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Storage in local databases

• Android has full support for SQLite databases

• Databases are accessible only to apps which create them

• While SQLite can be used directly, we will be using the Room persistence library

• Room is an abstraction layer over SQLite:• Reduces boilerplate code• Provides verification of queries• Manages DB schema changes

• If you want to work with the lower level SQLite APIs:• https://developer.android.com/training/data-storage/sqlite

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 26

Page 27: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Room Overview

1. Database• main access point to

persisted data

2. Entity• A table within the

database

3. Data Access Object (DAO) • the methods used for

accessing the database

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 27

https://developer.android.com/training/data-storage/room/

Page 28: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

implementation ‘android.arch.persistence.room:runtime:1.1.1’

Defining Data

• Include the relevant dependencies, e.g. in build.gradle:

• For each field that's defined in the entity, a column is created in the DB• Use @Ignore annotation to avoid this

• Room needs access to your fields in order to persist them so either:• Fields need to be public• You must define getter and setters

• Each entitity must define at least 1 primary key field• Annotate with @PrimaryKey• Assign automatic ID-s with @PrimaryKey(autoGenerate = true)

• Let’s define a Entity representing users

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 28

https://developer.android.com/training/data-storage/room/defining-data

Page 29: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

@Entity

public class User {

@PrimaryKey

private int uid;

@ColumnInfo(name = "first_name")

private String firstName;

@ColumnInfo(name = "last_name")

private String lastName;

// Getters & setters are also needed

}

Getting started with Room

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 29

https://developer.android.com/training/data-storage/room/defining-data

Page 30: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Define access to data with DAOs

• Define the methods which correspond to queries

• Room has various convenience annotations for defining the DAO methods:• @Insert

• @Update

• @Delete

• @Query

• Let’s use these for the User entity

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 30

https://developer.android.com/training/data-storage/room/accessing-data

Page 31: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Getting started with Room (2)

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 31

https://developer.android.com/training/data-storage/room/accessing-data

@Dao

public interface UserDao {

@Query("SELECT * FROM user")

List<User> getAll();

@Query("SELECT * FROM user WHERE uid IN (:userIds)")

List<User> loadAllByIds(int[] userIds);

@Query("SELECT * FROM user WHERE first_name LIKE :first AND "

+ "last_name LIKE :last LIMIT 1")

User findByName(String first, String last);

@Insert

void insertAll(User... users);

@Delete

void delete(User user);

}

Page 32: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Define the database

To create a Room-Database class:

1. Create an abstract class extending RoomDatabase

2. Annotate class with @Database• Define associated entities

3. Define abstract method with 0 arguments that returns class annotated with @Dao

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 32

https://developer.android.com/training/data-storage/room/

@Database(entities = {User.class}, version = 1)

public abstract class AppDatabase extends RoomDatabase {

public abstract UserDao userDao();

}

Page 33: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Now we can use our database!

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 33

https://developer.android.com/training/data-storage/room/

// Get the DB

AppDatabase db = Room.databaseBuilder(

getApplicationContext(),

AppDatabase.class, "db-name")

.allowMainThreadQueries() // use non-UI-thread instead

.build();

// Use a method of the DAO

User user = db.userDao().findByName("John", "Doe");

db.userDao().delete(user);

Page 34: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Managing Schema changes

• As your app gets enhanced, the entities and their schema will change• E.g. what if we want to add the users birthday?

• If you simply add/change class fields, you will get:

• The proper solution is to• Update the version in @Database annotation• Define Migrations to manage how old data should be

handled when schema changes

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 34

https://developer.android.com/training/data-storage/room/migrating-db-versions

java.lang.RuntimeException: Unable to start activity …: java.lang.IllegalStateException:Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.

Page 35: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Content Providers

• Content providers manage access to a structured set of data

• Enable sharing of data across applications• Address book, Calendar, Photo Gallery, …

• By default, applications can’t access the data and files of other applications

• In effect, a Content Provider is an abstraction interface to data storage mechanisms• Uniform APIs for CRUD

• Create, Read, Update Delete

• Files, SQLite databases, in-memory hash maps• Secure

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 35

https://developer.android.com/guide/topics/providers/content-providers

Page 36: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Content Provider

• Presents data to external applications as one or more tables• Row – instance of some data type• Column – individual piece of data for an

instance

• Manages access to the stored data for various APIs and components:• Sharing data with other apps• Sending data to a widget• Loading data into UI• …

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 36

https://developer.android.com/guide/topics/providers/content-provider-basics

Page 37: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Accessing Content Providers

• To access data in a Content Provider, you use a ContentResolver―ContentResolver cr =

getContentResolver();

• ContentResolver provides methods to perform basic CRUD operations

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 37

https://developer.android.com/guide/topics/providers/content-provider-basics#ClientProvider

Page 38: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Example: user dictionary

• Stores the spellings of non-standard words that the user wants to keep

• _ID column acts as primary key, maintained by the provider

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 38

word app id frequency locale _ID

mapreduce user1 100 en_US 1

precompiler user14 200 fr_FR 2

applet user2 225 fr_CA 3

const user1 255 pt_BR 4

int user5 100 en_UK 5

Page 39: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Using ContentResolver example

• Call ContentResolver.query():

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 39

// Queries the user dictionary and returns results

getContentResolver().query(

UserDictionary.Words.CONTENT_URI, // Content URI of the words table

mProjection, // Columns to return for each row

mSelectionClause, // Selection criteria

mSelectionArgs, // Selection criteria

mSortOrder); // Sort order for returned rows

Page 40: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Content URIs

• A content URI is a URI that identifies data in a provider.

• Content URIs include• The fixed scheme value for content URI-s (content://)

• Symbolic name of the entire provider (its authority)

• a name that points to a table or file (a path).

• Optional: id part points to an individual row in a table (query.

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 40

https://developer.android.com/guide/topics/providers/content-provider-basics#ContentURIs

Scheme Authority Path Query

Page 41: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Example Continued

• Note: The User Dictionary Provider defines the android.permission.READ_USER_DICTIONARY in it’s manifest, so clients of it must request this permission

• Next, constructing the query

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 41

getContentResolver().query(

UserDictionary.Words.CONTENT_URI,

mProjection,

mSelectionClause

mSelectionArgs,

mSortOrder);

Page 42: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

• Projection defines which columns to return

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 42

https://developer.android.com/guide/topics/providers/content-provider-basics#Query

getContentResolver().query(

mURI,

mProjection,

mSelectionClause

mSelectionArgs,

mSortOrder);

// String array values are contract class constants

String[] mProjection = {

UserDictionary.Words._ID,

UserDictionary.Words.WORD,

UserDictionary.Words.LOCALE

};

Page 43: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

• Selection Clause – logical statement for filtering rows

• Selection Args – arguments for selection clause, if clause uses replaceable parameter “?”

• No filtering:

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 43

https://developer.android.com/guide/topics/providers/content-provider-basics#Query

getContentResolver().query(

mURI,

mProjection,

mSelectionClause

mSelectionArgs,

mSortOrder);

String mSelectionClause = null;

String[] mSelectionArgs = {""};

//SQL: SELECT .. FROM words WHERE word = “mobile”

mSelectionClause = UserDictionary.Words.WORD + " = ?";

mSelectionArgs = new String[]{"mobile"};

Page 44: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Content Provider Query Results

• As a result of the query, a Cursor object is returned

• Cursor provides random read access to returned rows & columns

• Cursor.getCount() returns no. of matches

• You can iterate over the Cursor’s rows

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 44

https://developer.android.com/guide/topics/providers/content-provider-basics#DisplayResults

Page 45: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Example - Contacts Content Provider

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 45

Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;

String[] SELECTED_COLUMNS = {

ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,

ContactsContract.CommonDataKinds.Phone.NUMBER,

};

private Cursor makeContactsQuery() {

Cursor cursor = getContentResolver().query(uri, SELECTED_COLUMNS, null,null,null);

return cursor;

}

Cursor cursor = makeContactsQuery();

Log.i(TAG, "Rows: " + cursor.getCount());

int indexName = cursor.getColumnIndex(SELECTED_COLUMNS[0]);

int indexNumber = cursor.getColumnIndex(SELECTED_COLUMNS[1]);

while (cursor.moveToNext()) {

String name = cursor.getString(indexName);

String number = cursor.getString(indexNumber);

Log.i(TAG, name + "; " + number);

}

Page 46: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Adapters

• Adapter – bridge between AdapterView and data• Binds the view to external data source

• Initializes and populates the View

• AdapterView – view that displays items loaded into an adapter

• Call Adapter.notifyDataSetChanged()to refresh the UI

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 46

https://developer.android.com/guide/topics/providers/content-provider-basics#DisplayResultshttps://developer.android.com/guide/topics/ui/binding

Array

Page 47: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Example with ArrayAdapter

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 47

https://developer.android.com/guide/topics/ui/declaring-layout#AdapterViews

ArrayList<String> nameList = new ArrayList<>();

ArrayAdapter<String> adapter = new ArrayAdapter<>( this,

android.R.layout.simple_list_item_1, //TextView for value

nameList // source data object

);

// Note: simple_list_item_1 is a Android OS default file

// Bind array to the list view

listView.setAdapter(adapter);

// Update the dataset

nameList.add("Johnny");

adapter.notifyDataSetChanged();

Page 48: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Cursor Adapter

• SimpleCursorAdapter – An AdapterViewimplementation for use with Cursors.• Specify layout to use for rows

• Specify which columns to use

• Cursor must include the _ID column!

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 48

https://developer.android.com/reference/android/widget/SimpleCursorAdapter

Page 49: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Example – ContactsProvider, ListView and CursorAdapter

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 49

https://developer.android.com/guide/topics/providers/content-provider-basics#DisplayResults

String[] SELECTED_COLUMNS = {

ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,

ContactsContract.CommonDataKinds.Phone.NUMBER,

};

int[] toViews = {R.id.textview_name, R.id.textview_number};

SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(

this, // context

R.layout.list_row, // layout that defines the views for this list item.

cursor, // The database cursor

SELECTED_COLUMNS, // "from" - column names of the data to bind to the UI

toViews, // TextViews that should display column in the "from" param

0 // Flags used to determine the behavior of the adapter

);

listView.setAdapter(cursorAdapter);

Page 50: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Modifying data

• ContentResolver.insert() – returns URI of inserted row

• ContentResolver.update()• Specify query selection criteria

• Use ContentValues to set new values

• ContentResolver.delete()• Specify query selection criteria

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 50

https://developer.android.com/guide/topics/providers/content-provider-basics#Modifications

ContentValues values = new ContentValues();

values.put(Data.RAW_CONTACT_ID, rawContactId);

values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);

values.put(Phone.NUMBER, "1-800-GOOG-411");

values.put(Phone.TYPE, Phone.TYPE_CUSTOM);

values.put(Phone.LABEL, "free directory assistance");

Uri dataUri = getContentResolver().insert(Data.CONTENT_URI, values);

Page 51: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Finding existing and creating new Content Providers• To find out about the existing various providers

available on Android, check out:• https://developer.android.com/reference/android/provi

der/package-summary

• You want to share data with other applications• E.g. widgets

• You want to implement custom search suggestions

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 51

Page 52: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Creating Content Providers

• Extend ContentProvider class

• Override the necessary methods• Insert, delete, update

• Query handling

• Declare provider in manifest

• For more info refer to the developer portal

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 52

https://developer.android.com/guide/topics/providers/content-provider-creating

<manifest>

<provider

android:name=".MyContentProvider"

android:authorities="ee.ut.cs.exampleprovider"

android:enabled="true"

android:exported="true"></provider>

</manifest>

Page 53: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Exercise

• Display contact names and phone numbers

• Don’t forget permissions

• Stick to ContactsContract.CommonDataKinds.Phone!

• The Contacts Provider can be complex, spans more than one table

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 53

Page 54: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Background Processing

• Main thread – handles UI• Drawing views

• User interaction

• Lifecycle events

• Too much work on Main/UI thread – slowdowns & hiccups

• All long-running tasks should be run on a separate background thread

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 54

https://developer.android.com/guide/background/

Page 55: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Homework 3

• Using services to run a background music player• Also include a SharedPreferences-based counter to see

how many times music has been played

• https://courses.cs.ut.ee/2018/MAD/fall/Main/Homework3

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 55

Page 56: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Services

• Faceless components that run in the background• E.g. music player, network download, etc.

• Have higher priority than background activities, thus suitable for long-running tasks• Recall runtime memory management

• Services can take 2 forms:• Started

• Called with startService()• Run indefinitely

• Bound • App components bind to the service with bindService()• Runs as long as there are components bound to it• Provides a binding – a client-server interface

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 56

https://developer.android.com/guide/components/services

Page 57: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Services - continued

• Explicitly starting a new Service:

• Implementing your own Service• Extend Service class and declare in Manifest• Override callback methods

• NOTE: A Service still runs in the main thread of host process. If you need to do blocking calls / CPU-heavy tasks, create a Java Thread within the Service!

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 57

https://developer.android.com/guide/components/services

Intent intent = new Intent(this, MyService.class);

startService(intent);

Page 58: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 58

https://developer.android.com/guide/components/services

public class MyService extends Service {

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

// invoked through startService()

}

@Override

public IBinder onBind(Intent intent) {

// invoked through bindService()

// TODO: Return the communication channel to the service.

}

// Other lifecycle methods like onCreate, onDestroy

}

Page 59: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Process Management Recap

• By default, components of a single app run in the same process

• When the system wants to run a new component• If app doesn’t yet have any running components, a new

process with a single execution thread is started

• Otherwise, component is started within that process

• It’s possible to control which process certain components run in• Manifest android:process XML attribute

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 59

https://developer.android.com/guide/components/processes-and-threads

Page 60: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Threads

• As there is 1 main execution thread, both application components and UI interactions are done synchronously

• Long computations, I/O background tasks on the main thread will block the UI

• If the UI thread hangs for more than a few seconds (5s), the “Application Not Responding” dialog is presented• Poor user experience

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 60

Page 61: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Threads continued

• The Android UI functions are NOT thread-safe

• All UI manipulation must be done from UI thread

• Thus• On one hand you should do work on worker threads

• On the other hand, you can’t update UI from those threads

• What to do? Use messages and/or helper methods:

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 61

https://developer.android.com/guide/components/processes-and-threads#WorkerThreads

• Activity.runOnUiThread(Runnable)• View.post(Runnable)• View.postDelayed(Runnable, long)

Page 62: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Working with threads

• Several ways for implementing background work:• Standard Java threads, extending Runnable

• Use the helper methods from prev. slide• Do messaging with Handlers

• Android AsyncTask• Useful for one-off tasks, e.g. download image• 4 callback methods:

• doInBackground• onPreExecute• onPostExecute• onProgressUpdate

• Only doInBackground run on worker threads, others on UI thread!

• For more complex applications, consider using WorkManager API

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 62

Page 63: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Example – Sending results from Worker Thread to UI thread

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 63

http://developer.android.com/guide/components/processes-and-threads.html

new Thread(new Runnable() {

public void run() {

// a time consuming task

final Bitmap bitmap = processBitMap("image.png");

// post results to UI thread

mImageView.post(new Runnable() {

public void run() {

mImageView.setImageBitmap(bitmap);

}

});

}

}).start();

Page 64: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Our Android skills so far…

• Lifecycle management of Android applications

• GUI development

• Working with Application Components• Activities• Broadcast Receivers• Content Providers• Services

• Managing Intents, Background tasks, Permissions

• Managing data: File storage, databases

We are ready to start creating serious applications!

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 64

Page 65: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Home Assignment 1: Contact Picker

• Have an activity with design in fig-A with contacts of the phone

• Select a contact• Opens details Activity

• Send an email to the selected contact

• Back to original screen and display as in fig-B• Indicate which contact e-

mail was composed to

• Have an action bar (app bar) and introduce search functionality

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 65

A B

Page 66: Mobile Application Development · 2018. 9. 21. · Storage in local databases •Android has full support for SQLite databases •Databases are accessible only to apps which create

Next week

• Working with Sensors & Internet of Things

21/09/2018 Mobile & Cloud Lab. Institute of Computer Science, University Of Tartu 66