46
PROGRAMMING IN ANDROID IOANNIS (JOHN) PAPAVASILEIOU MARCH 31 2014 [email protected] 1

PROGRAMMING IN ANDROID IOANNIS (JOHN) PAPAVASILEIOU MARCH 31 2014 [email protected] 1

Embed Size (px)

Citation preview

1

PROGRAMMING IN ANDROID

IOANNIS (JOHN) PAPAVASILEIOU

MARCH 31 2014

[email protected]

2

WHAT IS IT• Software platform

• Operating system• Key apps

• Developers:• Google• Open Handset

Alliance

• Open Source (http://source.android.com/)

3

SOFTWARE STACK DESIGN

• Android ≠ Linux!!!

• The kernel is based on Linux kernel version 3.x (source Wikipedia)

• Written in C/C++

• Apps written in Java

• Use of Dalvik VM• Runs .dex files (dalvic executables)

4

API CAPABILITIES• Rich UI components

• Threads and Background processing

• Full network stack (Http, JSON)

• Database and file system access

• Access to hardware (Camera, Phone, GPS, sensors..)

• Plenty of libraries and services

5

LOW LEVEL ARCHITECTURE

Many of the APIs provided map 1:1 to the underlying HAL

Source: http://source.android.com/devices/images/system-architecture.png

crossing of process boundaries & call of system services code

Includes window and notification managers

Media services for playing and recording mediaInterface that allows

the Android system to call device driversKernel, includes device drivers and memory management

6

APPLICATION COMPONENTSEvery app may have:

• Activities

• A single screen with a UI. E.g. compose, read, list e-mails• Services

• Run in the background to perform long-running operations. E.g. play music, fetch data over the network

• Content Providers

• Manage a shared set of app data. Other apps can query or modify the data. E.g. contacts

• Broadcast Receivers

• Respond to a system-wide broadcast announcement. E.g. screen turned off, low-battery. May initiate services or notifications

• Intents

• Processes and threads

http://developer.android.com/guide/components/fundamentals.html

7

public void onClick(View v) {    new Thread(new Runnable() {        public void run() {            Bitmap b = loadImageFromNetwork("http://example.com/image.png");            mImageView.setImageBitmap(b);        }    }).start();}

APP FUNDAMENTALS

Every app lives in its own security sandbox:

• Every app runs its own Linux process

• Each process has it’s own Java VM

Every process can have multiple threads:

• UI thread (managed by the system)

• Worker threads

public void onClick(View v) {    new Thread(new Runnable() {        public void run() {            final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");            mImageView.post(new Runnable() {                public void run() {                    mImageView.setImageBitmap(bitmap);                }            });        }    }).start();}

Violates the rule: “do not access the Android UI toolkit from outside the UI”Will run on the UI thread

8

ACTIVITIES• The basis of android applications

• A viewable screen• the actions, not the layout

• Can have multiple per application

• Each is a separate entity

• They have a structured life cycle• Different events in their life happen either via the user

touching buttons or programmatically

9

ACTIVITYLIFECYCLE

The system can drop the activity from memory by just killing the process

It might not reach this point!

10

ACTIVITY RESTART• When there is a configuration change the app will be restarted

by the system

• Screen orientation• keyboard availability• Language• Etc.

• To save the state of the Activity the developer has to use the onSaveInstanceState() method.

• onCreate() or onRestoreInstancestate() will give you access to the restored state

• We can prevent the restart of the activity by handling the configuration change manually

• onPause() is guaranteed to be called in any case

11

SERVICES• Started

• Can continue even if Activity that started it dies• Something needs to be done while the user is not interacting

with application• Otherwise, a thread is probably more applicable

• Bound

• Multiple activities can bind to it• Allows multiple applications to communicate with it via a

common interface• Client-server interface

• Needs to be declared in manifest file

• Like Activities, has a structured life cycle

12

SERVICESLIFECYCLE

One component calls startService()

One component calls stopService() or service calls stopSelf()

One component calls bindService(),It can communicate with the Ibinder interface

To stop it calls unbindService(),Multiple clients can bind to the same service

13

CONTENT PROVIDERS• Encaptulate data provide data security

• Share data between processes

• Android has providers for

• Audio• Video• Images• Contact information

14

PROJECT COMPONENTS• src – your source code

• gen – auto-generated code (usually just R.java)

• Included libraries

• Resources

• Drawables (like .png images)• Layouts (define the UI)• Values (like strings)

• Manifest file

15

AndroidManifest.Xml

Configuration file for your application

• Permissions required from the app:

• E.g. access contacts, internet, vibration, camera, phone history, DB access

• Contains characteristics about your application

• Activities• Services• Content providers• Broadcast receivers

• Defines external libraries, like Google Maps API

16

MANIFEST FILE EXAMPLE<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android=http://schemas.android.com/apk/res/android package="com.abimed.ecg“ android:versionCode="5“ android:versionName="1.2.2"> <uses-sdk android:minSdkVersion="8"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <application android:label="@string/app_name“ android:icon="@drawable/logo“ android:debuggable="false"> <uses-library android:name="com.google.android.maps"/> <activity android:name="com.abimed.ecg.EcgActivity“ android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name="com.abimed.ecg.Preferences" android:label="@string/set_preferences"/> <activity android:name="com.abimed.ecg.About" android:label="@string/aboutActivity"/> <activity android:name="com.abimed.ecg.Report" android:label="@string/reportActivity"/> <activity android:name="com.abimed.ecg.GraphInfo" android:label="@string/graphInfoActivity"/> <activity android:name=".patients.Patients" android:label="@string/patients"/> <activity android:name=".patients.ViewPatient" android:label="@string/patient"/> <activity android:name=".patients.PatientInfo" android:theme="@android:style/Theme.NoTitleBar"/> <activity android:name=".patients.PatientEdit" android:theme="@android:style/Theme.NoTitleBar"/> </application></manifest>

17

STRINGS.XMLNice way to localize apps:

• res/values/strings.xml• res/values-en/strings.xml• res/values-fr/strings.xml• res/values-ja/strings.xml

Application wide available strings

Promotes good software engineering

UI components made in the UI editor should have text defined in strings.xml

Strings are just one kind of ‘Value’ there are many others

18

TOOLS TO DEVELOP• Phone or a Virtual Device

• Android Studio (http://developer.android.com/sdk/installing/studio.html) Provides:

• Development environment (based on IntelliJ IDEA)• SDK• Virtual devices

http://developer.android.com/training/basics/firstapp/building-ui.html

19

HELLO WORLD

20

LAYOUTS• Declare UI elements in XML

• Separates presentation from actual code• Visualize easy to debug• Almost Every Development Environment has nice Drag n

Drop editor• Instantiate layout elements at runtime (through Java code)

• Fast and easy when the layout is simple:• Has a few View elements• Has only a surface vew like GLSurfaceView

21

R CLASS• Auto-generated: you shouldn’t edit it

• Pairs Layout files with Activities

• Use findViewById and Resources object to get access to the resources

• Ex. Button buttonInfo = (Button)findViewById(R.id.buttonInfo);

buttonInfo.setOnClickListener(buttonInfoClickListener);• Ex. helloStr = getResources().getString(R.string.hello));

22

R CLASS

R.java

Activity.java Layout.xml

23

HELLO WORLD LAYOUT<!-- mainLayout.xml - -><?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="horizontal">    <EditText android:id="@+id/edit_message"        android:layout_weight="1"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:hint=“Enter a message" />    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text=“Send “        android:onClick="sendMessage" /></LinearLayout>

Only one root element

Additional elements as children

24

MAIN ACTIVITYpublic class MainActivity extends Activity {    public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";

@Override protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.mainLayout);

        // Make sure we're running on Honeycomb or higher to use ActionBar APIs        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {            // Show the Up button in the action bar.            getActionBar().setDisplayHomeAsUpEnabled(true);        }    }

/** Called when the user clicks the Send button */ public void sendMessage(View view) {    Intent intent = new Intent(this, DisplayMessageActivity.class);        EditText editText = (EditText) findViewById(R.id.edit_message);        String message = editText.getText().toString();       intent.putExtra(EXTRA_MESSAGE, message);        startActivity(intent);    }}

25

DISPLAY MESSAGE ACTIVITYpublic class DisplayMessageActivity extends Activity {

    @SuppressLint("NewApi")    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);

        // Get the message from the intent        Intent intent = getIntent();        String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);            // Create the text view        TextView textView = new TextView(this);        textView.setTextSize(40);        textView.setText(message);

        // Set the text view as the activity layout        setContentView(textView);

    }

}

http://developer.android.com/training/basics/intents/sending.html

26

INTENTS• Start new activity

• Send user to another App:• Implicit intent:

• Uri number = Uri.parse("tel:5551234");Intent intent = new Intent(Intent.ACTION_DIAL, number);

• Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");intent = new Intent(Intent.ACTION_VIEW, location);

• startActivity(intent);• Start a service

• Perform an operation in the background• Deliver a broadcast

• Something happened that other apps need to know

When multiple apps can handle the intent

27

APP CHOOSER

Intent intent = new Intent(Intent.ACTION_SEND);...

// Always use string resources for UI text.// This says something like "Share this photo with"String title = getResources().getString(R.string.chooser_title);// Create and start the chooserIntent chooser = Intent.createChooser(intent, title);startActivity(chooser);

28

STORAGE OPTIONS..

http://developer.android.com/guide/topics/data/data-storage.html

29

SHARED PREFERENCES• Store key-value sets

• Good for small setspublic class Calc extends Activity {    public static final String PREFS_NAME = "MyPrefsFile";

    @Override    protected void onCreate(Bundle state){       super.onCreate(state);       . . .

       // Restore preferences       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);       boolean silent = settings.getBoolean("silentMode", false);       setSilent(silent);    }

    @Override    protected void onStop(){       super.onStop();

      // We need an Editor object to make preference changes.      // All objects are from android.context.Context      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);      SharedPreferences.Editor editor = settings.edit();      editor.putBoolean("silentMode", mSilentMode);

      // Commit the edits!      editor.commit();    }}

http://developer.android.com/guide/topics/data/data-storage.html

30

FILE STORAGEInternal

• Always available

• Files accesible only by the app

• When the app is uninstalled, files are deleted

External

• Not always available

• World-readable

• When app is uninstalled, files will be deleted if the directory is gotten from getExternalFilesDir()

http://developer.android.com/guide/topics/data/data-storage.html

31

INTERNAL STORAGEString FILENAME = “myfile.txt";String string = "hello world!";

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);fos.write(string.getBytes());fos.close();

• When there is a need to cache some files use method: File createTempFile (String prefix, String suffix)

http://developer.android.com/guide/topics/data/data-storage.html

32

EXTERNAL STORAGE<manifest ... >    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

...</manifest>

/* Checks if external storage is available for read and write */public boolean isExternalStorageWritable() {    String state = Environment.getExternalStorageState();    if (Environment.MEDIA_MOUNTED.equals(state)) {        return true;    }    return false;}

/* Checks if external storage is available to at least read */public boolean isExternalStorageReadable() {    String state = Environment.getExternalStorageState();    if (Environment.MEDIA_MOUNTED.equals(state) ||        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {        return true;    }    return false;}

public File getAlbumStorageDir(Context context, String albumName) {    // Get the directory for the app's private pictures directory.     File file = new File(context.getExternalFilesDir(            Environment.DIRECTORY_PICTURES), albumName);    if (!file.mkdirs()) {        Log.e(LOG_TAG, "Directory not created");    }    return file;}

33

CREATE DATABASEpublic class DictionaryOpenHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 2;    private static final String DICTIONARY_TABLE_NAME = "dictionary";    private static final String DICTIONARY_TABLE_CREATE =                "CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +                KEY_WORD + " TEXT, " +                KEY_DEFINITION + " TEXT);";

    DictionaryOpenHelper(Context context) {        super(context, DATABASE_NAME, null, DATABASE_VERSION);    }

    @Override    public void onCreate(SQLiteDatabase db) {        db.execSQL(DICTIONARY_TABLE_CREATE);    }}

34

PUT INFO INTO THE DATABASE/ Gets the data repository in write modeSQLiteDatabase db = mDbHelper.getWritableDatabase();

// Create a new map of values, where column names are the keysContentValues values = new ContentValues();values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);values.put(FeedEntry.COLUMN_NAME_TITLE, title);values.put(FeedEntry.COLUMN_NAME_CONTENT, content);

// Insert the new row, returning the primary key value of the new rowlong newRowId;newRowId = db.insert(         FeedEntry.TABLE_NAME,         FeedEntry.COLUMN_NAME_NULLABLE,         values);

http://developer.android.com/guide/topics/sensors/sensors_overview.html

35

SENSORS• Types:

• Motion sensors• Environmental sensors• Position sensors

• Sensor Framework:

• Get available sensors• Get sensor capabilities• Acquire raw data for a given minimum rate• Register for sensor event listeners

36

MAGNETOMETER AVAILABILITY CHECKprivate SensorManager mSensorManager;...mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){  // Success! There's a magnetometer.  } else {  // Failure! No magnetometer.}

37

GET DATA EVENTS FROM THE LIGHT SENSOR

public class SensorActivity extends Activity implements SensorEventListener {  private SensorManager mSensorManager;  private Sensor mLight;

  @Override  public final void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);

    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);    mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);  }

  @Override  public final void onAccuracyChanged(Sensor sensor, int accuracy) {    // Do something here if sensor accuracy changes.  }

  @Override  public final void onSensorChanged(SensorEvent event) {    // The light sensor returns a single value.    // Many sensors return 3 values, one for each axis.    float lux = event.values[0];    // Do something with this sensor value.  }

  @Override  protected void onResume() {    super.onResume();    mSensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);  }

  @Override  protected void onPause() {    super.onPause();    mSensorManager.unregisterListener(this);  }}

http://developer.android.com/guide/topics/connectivity/index.html

38

CONNECTIVITY

Several APIs to let the app connect and interact with other devices:

• Bluetooth

• NFC

• Wi-Fi P2P

• USB

• SIP

39

CHECK NETWORK CONNECTIVITY

private void checkNetworkConnection() {

ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeInfo = connMgr.getActiveNetworkInfo(); if (activeInfo != null && activeInfo.isConnected()) {

wifiConnected = activeInfo.getType() == ConnectivityManager.TYPE_WIFI; mobileConnected=activeInfo.getType()==ConnectivityManager.TYPE_MOBILE; if(wifiConnected) {

Log.i(TAG, "Wifi connection"); } else if (mobileConnected){

Log.i(TAG, "Mobile connection"); }

} else { Log.i(TAG, "Not connected");

} }

http://developer.android.com/guide/topics/location/strategies.html

40

USER LOCATION<manifest ... >    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />    ...</manifest>

// Acquire a reference to the system Location ManagerLocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

// Define a listener that responds to location updatesLocationListener locationListener = new LocationListener() {    public void onLocationChanged(Location location) {      // Called when a new location is found by the network location provider.      makeUseOfNewLocation(location);    }

    public void onStatusChanged(String provider, int status, Bundle extras) {}

    public void onProviderEnabled(String provider) {}

    public void onProviderDisabled(String provider) {}  };

// Register the listener with the Location Manager to receive location updateslocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

http://developer.android.com/guide/topics/ui/notifiers/toasts.html

41

TOASTContext context = getApplicationContext();CharSequence text = "Hello toast!";int duration = Toast.LENGTH_SHORT;

Toast toast = Toast.makeText(context, text, duration);toast.show();

http://developer.android.com/reference/android/telephony/SmsManager.html

42

SEND SMS<manifest ... >    <uses-permission android:name="android.permission.SEND_SMS"/>    ...</manifest>

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

btnSendSMS = (Button) findViewById(R.id.btnSendSMS);

txtPhoneNo = (EditText) findViewById(R.id.txtPhoneNo);

txtMessage = (EditText) findViewById(R.id.txtMessage);

btnSendSMS.setOnClickListener(new View.OnClickListener() {

public void Onclick(View v) {

String phoneNo = txtPhoneNo.getText().toString();

String message = txtMessage.getText().toString();

if (phoneNo.length()>0 && message.length()>0)

sendSMS(phoneNo, message);

else

Toast.makeText(getBaseContext(), "Please enter both phone number and

message.",Toast.LENGTH_SHORT).show();

}});

}

43

SEND SMSprivate void sendSMS(String phoneNumber, String message) {

SmsManager sms = SmsManager.getDefault();

sms.sendTextMessage(phoneNumber, null, message, null, null);

}

http://developer.android.com/reference/android/telephony/SmsManager.html

44

GOOGLE LOCATION SERVICES• Fused location provider:

• Gives the bests location according to the needs• “high accuracy”, “low power”, etc.

• Geofencing APIs:

• App will receive notifications when the user enters specific geographic boundaries

• Activity recognition:

• In a vehicle• On a bicycle• On foot• Still• Tilting• Unknown

45

MY APP

46

THANKS!