48
Платформа Android Ведущий семинара: Максим Лейкин, компания «МЕРА НН»

Платформа Android

Embed Size (px)

DESCRIPTION

Платформа Android. Ведущий семинара: Максим Лейкин, компания «МЕРА НН». План семинара. 1. Android - FAQ 2 . Инструменты Android- разработчика 3. Примеры приложений Жизненный цикл приложения + AsyncTasks , Threads Простые ресурсы , размещения Элементы управления Хранилища данных - PowerPoint PPT Presentation

Citation preview

Page 1: Платформа  Android

Платформа AndroidВедущий семинара: Максим Лейкин, компания «МЕРА НН»

Page 2: Платформа  Android

План семинара

1. Android - FAQ

2. Инструменты Android-разработчика

3. Примеры приложений• Жизненный цикл приложения + AsyncTasks,

Threads • Простые ресурсы, размещения• Элементы управления• Хранилища данных• Content Providers• Intents, receivers• Сервисы• LBS-приложения

Page 3: Платформа  Android

План семинара

Часть 1. Android - FAQ1.Что такое Android?

2.Кто его разрабатывает?

3.Какие версии Android существуют?

4.Какие аппаратные платформы поддерживаются?

5.Под какой лицензией распространяется Android?

6.В чем ключевые особенности Android?

7.Из чего состоит Android?

8.Какова доля Android на рынке мобильных платформ?

9.Какие существуют устройства на платформе Android?

10.Что такое Google Play?

11.В чем преимущества и недостатки платформы Android?

Page 4: Платформа  Android

Android Activity Lifecycle

В любой момент времени всякая активность может находиться в

одном из 4-х состояний:

1) Active – видна на экране и может взаимодействовать с

пользователем

2) Paused – видна на экране, но не может взаимодействовать с

пользователем (не имеет фокуса ввода), например по причине

перекрытия всплывающим окном. Состояние сохраняется. Может

быть уничтожена системой в случае серьезной нехватки памяти

3) Stopped – запущена, но не видна пользователю и не может

взаимодействовать с ним. Состояние сохраняется. Может быть

уничтожена системой в случае нехватки памяти

4) Dead – активность не была запущена, либо была снята с

выполнения системой из-за нехватки ресурсов . Состояние не

сохраняется.

Page 5: Платформа  Android

Android Activity Lifecycle

Entire

lifetime

Visible

lifetime

Foreground

lifetime

Page 6: Платформа  Android

Android Activity Lifecycle

public class Activity extends ApplicationContext {

protected void onCreate(Bundle savedInstanceState);

protected void onStart();

protected void onRestart();

protected void onResume();

protected void onPause();

protected void onStop();

protected void onDestroy();

}

Внимание! Сохранять состояние активности надо в методе onPause(), а не в onSaveInstanceState(Bundle), последний может в некоторых случаях не вызываться.

Page 7: Платформа  Android

Android Activity Lifecycle

Page 8: Платформа  Android

Intents

Intent – специальный объект, который используется для передачи

сообщений между компонентами как внутри одного приложения так

и между разными приложениями.

С помощью Intents системе передается намерение совершить какое-

либо действие и данные, с которыми надо совершить это действие.

В ОС Android с помощью Intents можно делать следующее:

- стартовать другие активности (явно или неявно)

- передавать «широковещательные» сообщения операционной

системе

- получать «широковещательные» сообщения от операционной

системы

Intents – рекомендованный способ взаимдействия между

компонентами даже внутри одного приложения.

Page 9: Платформа  Android

Intents

Структура Intent

1) Обязательные параметры:

• action – действие, которое нужно произвести, например

ACTION_VIEW, ACTION_EDIT, etc.

• data – элемент данных, над которым надо произвести action,

задается с помощью Uri

Page 10: Платформа  Android

Intents

Структура Intent

2) Необязательные параметры:

• category – дополнительная информация о действии, которое

нужно произвести (например, CATEGORY_LAUNCHER,

СATEGORY_ALTERNATIVE)

• type – позволяет явно указать MIME type данных,

поставляемых с Intent (обычно извлекается из data)

• component - позволяет явно указать имя класса, для

выполнения Intent (обычно извлекается из action, data/type,

categories). Если указан – перекрывает действие всех

остальных атрибутов.

• extras – дополнительные данные, в виде набора пар «ключ-

значение»

Page 11: Платформа  Android

Intents: запуск активностей

Intent intent = new Intent(MyActivity.this, MyOtherActivity.class);

startActivity(intent);

Явно (explicitly):

Внимание! Вызываемая активность д.б. прописана в AndroidManifest.xml

Page 12: Платформа  Android

Intents: запуск активностей

Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(“tel:555-2368”));

startActivity(intent);

Неявно (implicitly):

Page 13: Платформа  Android

Приложение SimpleCaller

/res/values/strings.xml:

<?xml version="1.0" encoding="utf-8"?>

<resources>

<string name="hello">Hello World, SimpleCallerActivity!</string>

<string name="app_name">SimpleCaller</string>

<string name="call">Call</string>

<string name="number">Number:</string>

</resources>

Page 14: Платформа  Android

Приложение SimpleCaller

/src/layout/main.xml:<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/number" />

<EditText

android:id="@+id/Number"

android:layout_width="103dp"

android:layout_height="wrap_content" />

<Button

android:layout_height="wrap_content"

android:text="@string/call"

android:layout_width="wrap_content"

android:id="@+id/btnCall">

</Button>

</LinearLayout>

Page 15: Платформа  Android

Приложение SimpleCaller

/src/com/nnsu/mobileweek/SimpleCallerActivity.java:

package com.nnsu.mobileweek;

import android.app.Activity;

import android.content.Intent;

import android.net.Uri;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

public class SimpleCallerActivity extends Activity implements OnClickListener{

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

Button btnCall;

EditText numberField;

Page 16: Платформа  Android

Приложение SimpleCaller

/src/com/nnsu/mobileweek/SimpleCallerActivity.java:

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

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

numberField = (EditText)findViewById(R.id.Number);

btnCall.setOnClickListener(this);

}

private void phoneCall() {

String phoneCallUri = "tel:" + numberField.getText().toString();

Intent phoneCallIntent = new Intent(Intent.ACTION_CALL);

phoneCallIntent.setData(Uri.parse(phoneCallUri));

startActivity(phoneCallIntent);

}

public void onClick(View v) {

phoneCall();

}

}

Page 17: Платформа  Android

Приложение SimpleCaller

AndroidManifest.xml:<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.nnsu.mobileweek"

android:versionCode="1"

android:versionName="1.0">

<application

android:label="@string/app_name"

android:debuggable="true">

<activity android:name=".SimpleCallerActivity" android:label="@string/app_name">

<intent-filter>

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

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

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

</manifest>

Page 18: Платформа  Android

Приложение SimpleCaller

Page 19: Платформа  Android

Приложение SimpleCaller

Page 20: Платформа  Android

Intents: Intent Filters

Intent Filters предназначены для того, чтобы сообщить

операционной системе, что компонент (активность,

сервис) может принимать и обрабатывать Intents,

c параметрами определенного типа.

В приложении создается Intent, заполняются параметры action, data,

category. С помощью startActivity() этот Intent отправляется на поиски

подходящей Activity, которая сможет выполнить то, что определено

параметрами Intent. В системе есть разные приложения, и в каждом из

них несколько Activity. Для некоторых Activity определен Intent Filter т.д.),

для некоторых нет. Метод startActivity() сверяет набор параметров Intent

и наборы параметров Intent Filter для каждой Activity. Если наборы

совпадают – Activity считается подходящей. Если в итоге нашлась

только одна Activity – она и отображается. Если же нашлось несколько

подходящих Activity, то пользователю выводится список, где он может

сам выбрать какое приложение ему использовать.

Page 21: Платформа  Android

Intents: Intent Filters

Для задания Intent Filter используется тег intent-filter в

файле AndroidManifest.xml:

<activity android:name=".TourViewActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.cursor.item/vnd.com.niit.android" /> </intent-filter></activity>

1) action – задает действие, которое надо свершить или компонент, который надо

запустить

2) category – определяет, при каких условиях надо совершить action

3) data – набор дополнительных данных, который используется при выборе

компонента, выполняющего Intent, и передается ему для обработки

Можно считать, что Intent – ключ, IntentFilter - замок

Page 22: Платформа  Android

Intents: Resolution Rules

1) Собирается список всех доступных Intent Filters

2) Intent Filters, которые не соответствуют действию или категории удаляются из списка.

a) Совпадение происходит только в том случае, если Intent Filter содержит указанное действие (или если действие для него вовсе не задано). Совпадения не произойдет, только если ни одно из действий Intent Filter не будет эквивалентно тому, которое задано в Intent

b) Для категорий процесс соответствия более строгий. Intent Filter должен включать в себя все категории, заданные в полученном Intent. Фильтр, для которого категории не указаны, может соответствовать только таким же Intent без категорий.

3) Каждая часть пути URI из Intent сравнивается с тегом data Intent Filter. Если в Intent Filter указаны схема (протокол), сервер/принадлежность, путь или тип MIME, все эти значения проверяются на соответствие пути URI из Intent. При любом несовпадении Фильтр будет удален из списка. Если в Intent Filter не указано ни одного параметра data, его действие будет распространяться на любые данные.

Page 23: Платформа  Android

Intents: Resolution Rules

a) MIME — тип данных, который должен совпасть. При сравнении типов данных вы можете использовать маски, чтобы охватывать все подтипы (например, cats/*). Если в Intent Filter указан тип данных, он должен совпасть с тем, который значится в намерении, при отсутствии тега data подойдет любой тип.

b) Схема — это протокольная часть пути URI, например http:, mailto: или tel:.

c) Имя сервера (или принадлежность данных) — часть URI между схемой и самим путем (например, www.google.com). Чтобы совпало имя сервера, схема Intent Filter также должна подойти.

d) После имени сервера идет путь к данным (например, /ig). Путь пройдет проверку только после схемы и имени сервера, содержащихся в теге.

4) Если вышеописанный процесс возвращает более одного совпадения, пользователю выводится список со всеми вариантами

Sample 15

Page 24: Платформа  Android

Intents: чтение Intent

Если активность была запущена в результате совпадения

Intent с IntentFilter, то она может получить Intent, с которым

ее вызывали:

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

Intent intent = getIntent();

String action = intent.getAction();

Uri data = intent.getData();

}

Page 25: Платформа  Android

Intents: передача Intent

Можно передать Intent в активность, следующую в списке

подходящих (предварительно выполнив проверки\

обработки):

Intent intent = getIntent();

if (isAfterMidnight) {

startNextMatchingActivity(intent);

}

Page 26: Платформа  Android

Intents: возврат результата из активности

private static final int SHOW_SUBACTIVITY = 1;

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

startActivityForResult(intent, SHOW_SUBACTIVITY);

...

private static final int PICK_CONTACT_SUBACTIVITY = 2;

Uri uri = Uri.parse(“content://contacts/people”);

Intent intent = new Intent(Intent.ACTION_PICK, uri);

startActivityForResult(intent, PICK_CONTACT_SUBACTIVITY);

Основная активность:

Page 27: Платформа  Android

Intents: возврат результата из активности

Button okButton = (Button) findViewById(R.id.ok_button);

okButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {

Uri data = Uri.parse(“content://vendors/” + vendor_id);

Intent result = new Intent(null, data);

result.putExtra(IS_INPUT_CORRECT, inputCorrect);

setResult(RESULT_OK, result);

finish();

}

});

Вспомогательная активность

Page 28: Платформа  Android

Intents: возврат результата из активности

Обработка возвращенного результата:

public void onActivityResult(int requestCode,

int resultCode, Intent data)

- requestCode – код, с которым была запущена активность (переданный

в кач-ве второго параметра в startActivityForResult())

- resultCode – код, возвращенный из активности, обычно

Activity.RESULT_OK или Activity.RESULT_CANCELLED

- data – Intent, сорфмированный по результатам запуска sub-Activity

Page 29: Платформа  Android

Intents: возврат результата из активности

private static final int SHOW_SUB_ACTIVITY_ONE = 1;

private static final int SHOW_SUB_ACTIVITY_TWO = 2;

public void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

switch(requestCode) {

case (SHOW_SUB_ACTIVITY_ONE) :

if (resultCode == Activity.RESULT_OK) {

Uri vendor = data.getData();

boolean inputCorrect = data.getBooleanExtra(IS_INPUT_CORRECT, false); }

break;

case (SHOW_SUB_ACTIVITY_TWO) :

if (resultCode == Activity.RESULT_OK) {

// TODO: Handle OK click. }

break;

}

}

Page 30: Платформа  Android

Отладка Android-приложений

Отладка из Eclipse:

- The Debug Perspective

- The DDMS Perspective

(Dalvik Debug Monitor Server )

Page 31: Платформа  Android

Отладка Android-приложений: Breakpoints

Page 32: Платформа  Android

Отладка Android-приложений: запуск в debug

Page 33: Платформа  Android

Отладка Android-приложений: Debug Perspective

Debug – показывает отлаживаемые приложения и выполняющиеся в данный момент потоки

Variables – значения переменных (работает если есть установленные breakpoints)

Breakpoints – расставленные точки останова

LogCat – Системные сообщения платформы (в т.ч. exceptions)

Page 34: Платформа  Android

Отладка Android-приложений: Debug Perspective

Page 35: Платформа  Android

Отладка Android-приложений: DDMS Perspective

Devices – список подключенных эмуляторов и устройств

Threads – выполняющиеся потоки

Heap – использование динамической памяти

Allocation Tracker – выделение памяти

Allocation Tracker – выделение памяти

Emulator Control – управление эмулятором

Page 36: Платформа  Android

Android-приложения работающие с картами и GPS

Все устройства на платформе Android включают датчик GPS и встроенные средства работы с данными местоположения и картами.

Устройства на платформе Android позволяют определять местоположение одним из 3-х способов:- датчик GPS- Cell-ID (триангуляция)- Wi-Fi spots

Типовая задача:

1) Получить координаты с датчика GPS

2) Показать местоположение на карте Google Maps

Page 37: Платформа  Android

Google API vs. Android API

Page 38: Платформа  Android

Приложение LocationMaps

/res/values/strings.xml:

<?xml version="1.0" encoding="utf-8"?>

<resources>

<string name="hello">Hello World, AndroidMapsActivity!</string>

<string name="app_name">AndroidMaps</string>

<string name="lat">Latitude</string>

<string name="lon">Longitude</string>

</resources>

Page 39: Платформа  Android

Приложение LocationMaps

/src/layout/main.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

<Button

android:id="@+id/bFindMe"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Find Me!" />

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/lat" />

Page 40: Платформа  Android

Приложение LocationMaps

<EditText

android:id="@+id/etLatitude"

android:layout_width="103dp"

android:layout_height="wrap_content" />

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/lon" />

<EditText

android:id="@+id/etLongitude"

android:layout_width="103dp"

android:layout_height="wrap_content" />

<Button

android:id="@+id/bShowMe"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Show Me!" />

</LinearLayout>

Page 41: Платформа  Android

Приложение LocationMaps

/src/com/nnsu/mobileweek/AndroidMapsActivity.java:

package com.nnsu.mobileweek;

import android.app.Activity;

import android.content.Context;

import android.content.Intent;

import android.location.Location;

import android.location.LocationListener;

import android.location.LocationManager;

import android.net.Uri;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

Page 42: Платформа  Android

Приложение LocationMaps

/src/com/nnsu/mobileweek/AndroidMapsActivity.java:

public class AndroidMapsActivity extends Activity implements LocationListener {

EditText lat, lon;

Button btnShow, btnFind;

LocationManager locMgr;

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

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

Button btnShow=(Button)findViewById(R.id.bShowMe);

Button btnFind=(Button)findViewById(R.id.bFindMe);

lat=(EditText)findViewById(R.id.etLatitude);

lon=(EditText)findViewById(R.id.etLongitude);

Page 43: Платформа  Android

Приложение LocationMaps

/src/com/nnsu/mobileweek/AndroidMapsActivity.java:

btnShow.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {

String _lat=lat.getText().toString();

String _lon=lon.getText().toString();

Uri uri=Uri.parse("geo:"+_lat+","+_lon);

startActivity(new Intent(Intent.ACTION_VIEW, uri));

}

});

btnFind.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {

getFix();

}

} );

}

Page 44: Платформа  Android

Приложение LocationMaps

/src/com/nnsu/mobileweek/AndroidMapsActivity.java:

public void getFix() {

locMgr = (LocationManager)

this.getSystemService(Context.LOCATION_SERVICE);

locMgr.requestLocationUpdates

(LocationManager.GPS_PROVIDER, 0L, 0, this);

}

public void onLocationChanged(final Location location) {

this.runOnUiThread(new Runnable() {

public void run() {

lat.setText(new Double(location.getLatitude()).toString());

lon.setText(new Double(location.getLongitude()).toString());

}

} );

}

Page 45: Платформа  Android

Приложение LocationMaps

/src/com/nnsu/mobileweek/AndroidMapsActivity.java:

public void onProviderDisabled(String provider) {}

public void onProviderEnabled(String provider) {}

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

}

Page 46: Платформа  Android

Приложение LocationMaps

AndroidManifest.xml:<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.nnsu.mobileweek"

android:versionCode="1"

android:versionName="1.0" >

<uses-sdk android:minSdkVersion="9" />

<application

android:icon="@drawable/ic_launcher"

android:label="@string/app_name" >

<activity

android:name=".AndroidMapsActivity"

android:label="@string/app_name" >

<intent-filter>

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

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

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

</manifest>

Page 47: Платформа  Android

Приложение LocationMaps

Page 48: Платформа  Android

Приложение LocationMaps