Программирование мобильных устройств. Ч.1. Учебно-методическое пособие
.pdf
«table_name» – имя существующей таблицы, в которой вы хотите внести изменения.
«column_name» – имя нового столбца, который вы хотите добавить. «datatype» – тип данных для нового столбца.
Пример использования оператора «ALTER TABLE» для добавления столбца `Producer` к таблице `Artists` с типом данных `varchar(20)`:
ALTER TABLE Artists
ADD Producer varchar(20);
Врезультате выполнения этого запроса к таблице `Artists` будет добавлен новый столбец `Producer`.
После выполнения оператора «ALTER TABLE» вы можете использовать запрос `SELECT * FROM Artists`, чтобы убедиться, что столбец `Producer`
успешно добавлен к таблице.
7.1.Дополнительные теоретические сведения
Впроцессе выполнения лабораторной работы будут полезные некоторые теоретические сведения, представленные ниже.
7.1.1. Dagger 2
Проблемы зависимостей в разработке программного обеспечения возникают, когда классы или компоненты становятся слишком зависимыми друг от друга. Это может привести к жесткому связыванию, усложнению изменений и трудностям в тестировании. Для решения этих проблем внедрение зависимостей (Dependency Injection) становится полезным инструментом. Рассмотрим эти проблемы на примере и решения с помощью Dagger 2.
Жесткое связывание Проблема: классы непосредственно зависят от конкретных реализаций
других классов, что делает их менее переиспользуемыми и гибкими.
class Car {
private val engine = Engine() private val wheel = Wheel() // ...
}
Решение с Dagger 2: Использование аннотации `@Inject` для внедрения зависимостей, что позволяет передавать экземпляры зависимых классов через конструктора или методы.
Сложности в тестировании Проблема: при наличии жестких зависимостей тестирование становится
сложным из-за необходимости создания реальных объектов зависимостей.
class CarTest { @Test
41
fun testDrive() { val car = Car() car.drive()
// Assert driving behavior
}
}
Решение с Dagger 2: Внедрение зависимостей через конструктор или методы делает возможным подмену реальных зависимостей фиктивными объектами во время тестирования.
Создание и управление объектами Проблема: при большом количестве зависимостей создание и управление
объектами может стать сложной задачей.
class Car {
private val engine = Engine() private val wheel = Wheel() private val fuel = Fuel()
// ...
}
Решение с Dagger 2: Использование компонентов Dagger для предоставления зависимостей. Dagger автоматически создает экземпляры зависимых классов и управляет их жизненным циклом.
Таким образом, Dagger 2 позволяет эффективно решать проблемы зависимостей в приложениях Android, делая код более модульным, гибким и легким для тестирования.
7.1.2. Намерения (Intent) в Android
Намерение (Intent) – это механизм для описания операций в Android, таких как выбор фотографии, отправка письма, совершение звонка, запуск браузера и переход по указанному адресу. Они играют важную роль в многих аспектах разработки Android-приложений, включая работу с активностями, сервисами и широковещательными приёмниками.
Явные намерения используются для запуска компонентов приложения, к которым разработчик имеет прямой доступ. Пример использования явного намерения для запуска другой активности:
val intent = Intent(this, SecondActivity::class.java) startActivity(intent)
Здесь мы явно указываем класс активности (`SecondActivity`), который хотим запустить из текущей активности (`this`).
Также можно передавать данные между активностями с помощью намерений:
val fileList = ArrayList<File>()
val intent = Intent(this, SecondActivity::class.java) intent.putExtra("FILES_LIST", fileList)
42
startActivity(intent)
И получить их в целевой активности:
val fileList = intent.getSerializableExtra("FILES_LIST") as? ArrayList<File>
Неявные намерения позволяют запускать компоненты, к которым доступ осуществляется через систему Android, а не напрямую. Пример использования неявного намерения для открытия веб-страницы:
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"))
startActivity(intent)
Здесь мы указываем действие (`ACTION_VIEW`) и URI адрес вебстраницы. Система Android сама определит, какое приложение или сервис использовать для выполнения этого действия.
Неявные намерения также могут использоваться для взаимодействия с другими приложениями или компонентами системы, например, для отправки текстовых сообщений или выбора контактов из адресной книги.
43
8. Создание приложения Живые обои/Виджет
Целью занятия является: создать (на выбор) Живые обои «Аквариум» или виджет для рабочего стола.
8.1. Живые обои «Аквариум»
Необходимо создать виджет, в котором группа рыбок плавает в аквариуме. Уровень воды в аквариуме отображает заряд батареи. При низком заряде рыбки могут погибать (переворачиваются и не плавают).
Создайте новый проект в Android Studio, используя язык программирования Kotlin. Определите макет для аквариума с элементами, представляющими рыбок и уровень воды.
Используйте `BatteryManager` для получения информации о заряде батареи. Анимируйте уровень воды в аквариуме в зависимости от заряда батареи.
val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPAC ITY)
Реализуйте анимацию движения группы рыбок в аквариуме. Обработайте сценарий с низким зарядом батареи, при котором рыбки могут погибать.
if (batteryLevel < LOW_BATTERY_THRESHOLD) {
// Обработка сценария с низким зарядом батареи (анимация смерти рыбок)
}
else {
// Обычная анимация плавания рыбок
}
Управляйте жизненным циклом аквариума, чтобы предотвратить ненужное использование ресурсов при сворачивании приложения.
override fun onResume() { super.onResume()
// Возобновление анимации и обновление данных
}
override fun onPause() { super.onPause()
// Приостановка анимации и освобождение ресурсов
}
44
8.1.1.Дополнительные теоретические сведения
`
BatteryManager` – это системный сервис Android, предоставляющий информацию о состоянии батареи устройства. Используется для мониторинга уровня заряда батареи.
Анимации в Android могут быть реализованы с использованием различных методов, включая `ViewPropertyAnimator`, `ObjectAnimator` и
`AnimationDrawable`.
// Пример использования ViewPropertyAnimator view.animate().rotationBy(360f).setDuration(1000).start()
Важно корректно управлять жизненным циклом аквариума. Методы `onResume` и `onPause` используются для управления анимацией и ресурсами.
8.2. Виджет для Рабочего Стола
Виджет должен отображать котировки металлов на текущую дату по данным ЦБ. Данные подгружаются из http://www.cbr.ru/scripts/xml_metall.asp?date_req1=13/07/2020&date_req2=13/07/2 020. На виджете отображается только данные по одному металлу, но по нажатию на виджет открывается окно, где указаны данные по четырем металлам.
Добавьте новый виджет к проекту, расширяя класс `AppWidgetProvider`. Определите макет для отображения данных о котировках металлов. Используйте `HttpURLConnection` для выполнения запроса к серверу ЦБ и получения данных о котировках.
val url = URL("http://www.cbr.ru/scripts/xml_metall.asp?date_req1=13/07/2020&date_req2 =13/07/2020")
val connection = url.openConnection() as HttpURLConnection
Извлеките необходимые данные из XML-ответа сервера и обновите виджет.
val metalData = parseXmlResponse(connection.inputStream) updateWidgetViews(context, appWidgetManager, appWidgetId, metalData)
Реализуйте обработчик нажатия для виджета, который открывает окно с данными по четырем металлам.
val intent = Intent(context, MetalInfoActivity::class.java)
val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0) views.setOnClickPendingIntent(R.id.widgetLayout, pendingIntent)
45
8.2.1. Дополнительные теоретические сведения
`HttpURLConnection` – это класс в Java и Kotlin для выполнения HTTPзапросов. Он может использоваться для обращения к удаленным серверам и получения данных.
val url = URL("https://example.com/data")
val connection = url.openConnection() as HttpURLConnection
Для обработки XML-данных можно использовать различные библиотеки, такие как `XmlPullParser` или сторонние библиотеки парсинга XML.
// Пример использования XmlPullParser val parser = Xml.newPullParser() parser.setInput(inputStream, null)
Обновление виджета в Android производится с использованием `AppWidgetManager` и обновленных представлений виджета.
appWidgetManager.updateAppWidget(appWidgetId, views)
Добавление обработчика нажатий позволяет реагировать на действия пользователя и выполнять дополнительные операции.
val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0) views.setOnClickPendingIntent(R.id.widgetLayout, pendingIntent)
`PendingIntent` – это концепция в Android, представляющая намерение, которое будет выполнено в будущем, например, при нажатии на виджет. `PendingIntent.getActivity` используется для открытия активности.
8.2.2.Изображения
ВAndroid разработке ресурсы-изображения играют важную роль, предоставляя возможность отображения графических элементов в пользовательском интерфейсе.
Основные типы ресурсов-изображений:
• Bitmaps (Растровые изображения) – это обычные растровые изображения, представленные в форматах PNG, JPEG, GIF и других. Они хранятся в папке `res/drawable` и используются для отображения на экране.
val imageView: ImageView = findViewById(R.id.imageView)
val bitmapImage: Bitmap = BitmapFactory.decodeResource(resources, R.drawable.bitmap_image)
imageView.setImageBitmap(bitmapImage)
• Vector Drawables (Векторные изображения) позволяют создавать масштабируемые изображения без потери качества. Они хранятся в папке
46
`res/drawable` и могут быть векторизированы и масштабированы при необходимости.
val |
vectorDrawable: |
VectorDrawableCompat |
= |
AppCompatResources.getDrawable(context, |
R.drawable.vector_image) |
as |
|
VectorDrawableCompat |
|
|
|
imageView.setImageDrawable(vectorDrawable) |
|
||
• Shape Drawables (Геометрические фигуры) – это XML-файлы, которые определяют геометрические фигуры, такие как прямоугольники, овалы, линии и кольца. Они хранятся в папке `res/drawable` и позволяют создавать простые графические элементы.
//xml
<!-- res/drawable/rectangle_shape.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#FF0000" />
<size android:width="100dp" android:height="100dp" /> </shape>
//kotlin
val shapeDrawable: Drawable = ContextCompat.getDrawable(context, R.drawable.rectangle_shape)!!
imageView.background = shapeDrawable
• Layer Lists (Списки слоев) позволяют комбинировать несколько изображений в одно, добавляя каждое изображение как отдельный слой. Они хранятся в папке `res/drawable` и используются для создания комплексных графических элементов.
//xml
<!-- res/drawable/layer_list.xml -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/background_image" />
<item android:drawable="@drawable/foreground_image" /> </layer-list>
//kotlin
val layerDrawable: LayerDrawable = ContextCompat.getDrawable(context, R.drawable.layer_list) as LayerDrawable
imageView.setImageDrawable(layerDrawable)
Эти примеры демонстрируют различные способы работы с ресурсамиизображениями. Они позволяют создавать разнообразные графические элементы и эффективно управлять ими в приложении.
47
8.2.3.Работа с JSON
ВAndroid для работы с JSON предоставляются готовые классы, такие как
«JSONObject» и «JSONArray».
«JSONObject» – это класс, представляющий собой объект JSON, содержащий пары ключ-значение.
Методы класса «JSONObject» Конструкторы:
•JSONObject()`: создает пустой объект класса `JSONObject`;
•`JSONObject(String source)`: создает объект `JSONObject` из строки;
•JSONObject(Map mapsource)`: создает объект `JSONObject` из объекта класса `Map`.
val jsonObject1 = JSONObject()
val jsonObject2 = JSONObject("{\"name\":\"Иван\"}") val map = mapOf("key1" to "value1", "key2" to "value2") val jsonObject3 = JSONObject(map)
Методы для получения значений:
•`getBoolean(String key)`: получает значение по ключу и возвращает
`Boolean`;
•`getDouble(String key)`: получает значение по ключу и возвращает
`Double`;
•`getInt(String key)`: получает значение по ключу и возвращает `Int`;
•`getLong(String key)`: получает значение по ключу и возвращает
`Long`;
•`getString(String key)`: получает значение по ключу и возвращает
`String`;
•`getJSONArray(String key)`: получает значение по ключу и возвращает объект `JSONArray`;
•`getJSONObject(String key)`: получает значение по ключу и возвращает объект `JSONObject`.
val jsonObject = JSONObject("{\"name\":\"Елена\",\"age\":25}") val name = jsonObject.getString("name")
val age = jsonObject.getInt("age")
«JSONArray» – это класс, представляющий собой массив JSON, содержащий упорядоченный список значений.
Методы класса «JSONArray» Конструкторы:
•`JSONArray()`: Создает пустой массив `JSONArray`;
•`JSONArray(String source)`: Создает массив `JSONArray` из строки. val jsonArray1 = JSONArray()
val jsonArray2 = JSONArray("[\"value1\", \"value2\", \"value3\"]")
48
Методы для работы с элементами массива:
•`getBoolean(Int index)`: Получает значение по индексу и возвращает
`Boolean`;
•`getDouble(Int index)`: Получает значение по индексу и возвращает
`Double`;
•`getInt(Int index)`: Получает значение по индексу и возвращает `Int`;
•`getLong(Int index)`: Получает значение по индексу и возвращает
`Long`;
•`getString(Int index)`: Получает значение по индексу и возвращает
`String`;
•getJSONObject(Int index)`: Получает объект `JSONObject` по индексу;
•`getJSONArray(Int index)`: Получает объект `JSONArray` по индексу. val jsonArray = JSONArray("[\"apple\", \"banana\", \"orange\"]")
val fruit1 = jsonArray.getString(0) val fruit2 = jsonArray.getString(1)
49
Заключение
Входе изучения данного курса обучающийся овладеет ключевыми навыками разработки приложений на платформе Android с использованием языка программирования Kotlin. От создания игр и обработки сенсорных событий до разработки живых обоев и виджетов для рабочего стола, каждый этап курса призван расширить практические навыки обучающегося и предоставить полезный опыт.
• Создание игр включает в себя работу с графикой, обработку пользовательского ввода и внедрение звуковых эффектов.
• Знание работы с датчиками устройства, такими как акселерометр, гироскоп и датчик местоположения, расширит функциональность приложений.
• Овладение методами взаимодействия с базой данных SQLite на платформе Android станет важным активом для будущих проектов обучающегося. Создание базы данных студентов и сортировка записей по возрасту подчеркнет важность хранения и обработки данных в мобильных приложениях.
• Разработка живых обоев «Аквариум» и виджетов для рабочего стола предоставят опыт визуализации данных, работы с анимацией и взаимодействием пользователя с приложением.
Врезультате прохождения данного курса обучающийся получит фундаментальные знания и навыки, необходимые для разработки приложений на платформе Android с использованием языка программирования Kotlin. Эти компетенции будут востребованы в современной сфере разработки программного обеспечения, делая обучающегося способным к успешной профессиональной деятельности в области мобильной разработки.
50
