Вы находитесь на странице: 1из 10

Введение

В этом Продвинутом курсе вы узнаете, как создать клиент-серверное андроид приложение


на языке Kotlin самостоятельно, независимо от опыта в программировании. В курсе
содержится пошаговая инструкция по разработке приложения, внедрению рекламных
баннеров AdMob, и публикации приложения в Google Play.

Приложение «ТОП-100 криптовалют» разрабатывается в среде разработки Android Studio с


использованием таких подходов, технологий и инструментов:

Язык разработки Kotlin

Архитектура с использованием паттерна MVP

Взаимодействие с REST API посредством Retrofit


Асинхронная обработка данных с RX Kotlin

Dependency injection с Dagger2

Рекламные баннеры AdMob


Чему вы научитесь в этом курсе?
В этом курсе вы сможете создать мобильное клиент-серверное андроид-приложение,
отображающее актуальный список криптовалют с графиком цен и статистической
финансовой информацией, полученный с сервера CoinGecko. Взаимодействие с сервером
построено с использованием типичных современных подходов. В качестве источника
данных для вашего приложения может быть использован любой другой сервер с REST API.

После прохождения курса вы будете знать:

как создать клиент-серверное android-приложение,

как уменьшить связанность компонентов с помощью MVP,

как реализовать Dependency injection с Dagger2,

как создавать макеты с ConstraintLayout,

как создавать списки с RecyclerView,

как отправлять сетевые запросы к REST API посредством Retrofit,

как обрабатывать ответы сервера с RX Kotlin,

как встроить баннеры и межстраничные объявления,

как монетизировать приложение с AdMob,

как опубликовать android-приложение в маркете Google Play.

Формат этих уроков этого курса несколько отличается от других курсов. Большая часть
уроков будет текстовой с вставками исходного кода. Видеофрагменты без комментариев
будут в тех местах, где требуется показать процесс создания компонентов или набора кода.
Такой формат более удобен для оперативного внесения изменений в уроки в будущем,
чтобы не перезаписывать курс полностью. Это может потребоваться, если какие-то
решения устареют и перестанут работать.

Уроки будут построены по принципу — от простого к сложному, чтобы всем было проще и
понятнее вникнуть в суть.

В первом уроке мы начнем с простых вещей —  создадим проект, добавим


информационный экран, который отображает информацию о приложении. Также  добавим
рекламные баннеры в приложение.
Добавление информационного активити
В окне дерева проекта слева выберите главный пакет и создайте пакет activities. Внутри
нового пакета создайте новое активити AboutActivity. В файле манифеста
AndroidManifest.xml определите для нового активити атрибут:

1 <activity android:name=".activities.AboutActivity"
2 android:parentActivityName=".MainActivity">
3 </activity>
4

Это определит навигационную привязку нового активити для возврата из него в главное
активити. Для завершения привязки пропишите в AboutActivity.onCreate() установку стрелки
возврата в тулбаре:

1 class AboutActivity : AppCompatActivity() {


2
3 override fun onCreate(savedInstanceState: Bundle?) {
4 super.onCreate(savedInstanceState)
5 setContentView(R.layout.activity_about)
6

7 supportActionBar?.setDisplayHomeAsUpEnabled(true)
8 }
9 }
10
Измените макет разметки res/layout/activity_about.xml в соответствии с этим кодом:

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


2 <android.support.constraint.ConstraintLayout
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 xmlns:tools="http://schemas.android.com/tools"
5 xmlns:app="http://schemas.android.com/apk/res-auto"
6 android:layout_width="match_parent"
7 android:layout_height="match_parent"
8 tools:context=".activities.AboutActivity">
9
10 <TextView
11 android:text="@string/the_index_is_calculated"
12 android:layout_width="0dp"
13 android:layout_height="wrap_content"
14 app:layout_constraintStart_toStartOf="parent"
15 app:layout_constraintEnd_toEndOf="parent"
16 android:id="@+id/textView" android:layout_marginTop="24dp"
17 app:layout_constraintTop_toTopOf="parent"
18 android:textSize="24sp" android:layout_marginStart="8dp"
19 app:layout_constraintHorizontal_bias="1.0"
20 android:layout_marginEnd="8dp" android:textAlignment="center"/>
21 <ImageView
22 android:layout_width="273dp"
23 android:layout_height="85dp" app:srcCompat="@drawable/coingecko"
24 app:layout_constraintStart_toStartOf="parent"
25 app:layout_constraintEnd_toEndOf="parent" android:id="@+id/imageView"
26 app:layout_constraintTop_toBottomOf="@+id/textView"
27 android:layout_marginStart="8dp" android:layout_marginEnd="8dp"
28 android:layout_marginTop="16dp"/>
29 <Button
30 android:layout_width="wrap_content"
31 android:layout_height="wrap_content"
32 app:layout_constraintStart_toStartOf="parent"
33 app:layout_constraintEnd_toEndOf="parent"
34 android:id="@+id/buttonRateApp" android:layout_marginTop="32dp"
app:layout_constraintTop_toBottomOf="@+id/imageView"
android:text="@string/rate_this_app_button_text"/>

</android.support.constraint.ConstraintLayout>
Вам понадобятся такие строки в файле ресурсов res/values/strings.xml:

1 <string name="the_index_is_calculated" translatable="false">The rating TOP-100


2 cryptocurrencies by market capitalization.\nPowered by CoinGecko API </string>
<string name="rate_this_app_button_text">Rate This App</string>

Изображение coingecko.webp скачайте и сохраните в папке res/drawable.

В вашем приложении вы можете использовать другие изображения и тексты, отражающие


специфику именно вашего приложения.

Создание кнопки меню для вызова AboutActivity


В папке res создайте папку menu. Внутри создайте  файл разметки main_menu.xml:

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


2 <menu xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto">
4
5 <item
6 android:id="@+id/action_about"
7 android:title="About"
8 android:icon="@drawable/baseline_info_white_36"
9 app:showAsAction="always"
10 />
11
12
13 </menu>
14

Иконку baseline_info_white_36.png можно скачать с сайта https://material.io/tools/icons/?


search=info&icon=info&style=baseline
Осталось подключить меню в MainActivity:

1 override fun onCreateOptionsMenu(menu: Menu?): Boolean {


2
3 menuInflater.inflate(R.menu.main_menu, menu)
4 return super.onCreateOptionsMenu(menu)
5 }
6

Добавьте обработчик нажатия кнопки, во которому будет открываться AboutActivity:

1 override fun onOptionsItemSelected(item: MenuItem?): Boolean {


2
3 when (item!!.itemId) {
4        R.id.action_about -> {
5
6
7 val intent = Intent(this, AboutActivity::class.java)
8 startActivity(intent)
9 return true
10 }
11
12 }
13 return super.onOptionsItemSelected(item)
14 }
15

Теперь запустите приложение на эмуляторе или устройстве и проверьте, что меню


отображается, а при тапе по кнопке меню открывается AboutActivity c информацией о
приложении. В тулбаре AboutActivity должна быть стрелка, ведущая обратно в MainActivity.
В теле функции onCreate() в AboutActivity определите для кнопки рейтинга слушатель,
который при нажатии будет открывать страницу приложения в маркете GooglePlay:

1 buttonRateApp.setOnClickListener {
2    startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?
3 id=${applicationContext.packageName}")))
4 }

Внедрение рекламных баннеров


Для создания рекламных баннеров зарегистрируйтесь в сервисе AdMob

Создайте приложение в консоли AdMob, и скопируйте его идентификатор — он вам


понадобится далее в коде приложения.

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


идентификаторы тоже.
В проекте откройте файл сборки build.gradle (app) и добавьте имплементацию библиотеки
для работы с рекламой.

1 implementation 'com.google.android.gms:play-services-ads:17.1.3'

Также нам нужно добавить компонент стандартного баннера в макеты всех экранов, где мы
хотим отображать рекламу. Это макет activity-about.xml с добавленным баннером:

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


2 <android.support.constraint.ConstraintLayout
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 xmlns:tools="http://schemas.android.com/tools"
5 xmlns:app="http://schemas.android.com/apk/res-auto"
6 android:layout_width="match_parent"
7 android:layout_height="match_parent"
8 tools:context=".activities.AboutActivity">
9
10 <com.google.android.gms.ads.AdView
11 xmlns:ads="http://schemas.android.com/apk/res-auto"
12 android:id="@+id/adView"
13 android:layout_width="wrap_content"
14 android:layout_height="wrap_content"
15 android:layout_centerHorizontal="true"
16 android:layout_alignParentBottom="true"
17 ads:adSize="BANNER"
18 ads:adUnitId="ca-app-pub-3940256099942544/6300978111"
19 android:layout_marginBottom="8dp"
20 ads:layout_constraintBottom_toBottomOf="parent" android:layout_marginStart="8dp"
21 ads:layout_constraintStart_toStartOf="parent" android:layout_marginEnd="8dp"
22 ads:layout_constraintEnd_toEndOf="parent">
23 </com.google.android.gms.ads.AdView>
24
25 <TextView
26 android:text="@string/the_index_is_calculated"
27 android:layout_width="0dp"
28 android:layout_height="wrap_content"
29 app:layout_constraintStart_toStartOf="parent"
30 app:layout_constraintEnd_toEndOf="parent"
31 android:id="@+id/textView" android:layout_marginTop="24dp"
32 app:layout_constraintTop_toTopOf="parent"
33 android:textSize="24sp" android:layout_marginStart="8dp"
34 app:layout_constraintHorizontal_bias="1.0"
35 android:layout_marginEnd="8dp" android:textAlignment="center"/>
36 <ImageView
37 android:layout_width="273dp"
38 android:layout_height="85dp" app:srcCompat="@drawable/coingecko"
39 app:layout_constraintStart_toStartOf="parent"
40 app:layout_constraintEnd_toEndOf="parent" android:id="@+id/imageView"
41 app:layout_constraintTop_toBottomOf="@+id/textView"
42 android:layout_marginStart="8dp" android:layout_marginEnd="8dp"
43 android:layout_marginTop="16dp"/>
44 <Button
45 android:layout_width="wrap_content"
46 android:layout_height="wrap_content"
47 app:layout_constraintStart_toStartOf="parent"
48 app:layout_constraintEnd_toEndOf="parent"
49 android:id="@+id/buttonRateApp" android:layout_marginTop="32dp"
app:layout_constraintTop_toBottomOf="@+id/imageView"
android:text="@string/rate_this_app_button_text"/>

</android.support.constraint.ConstraintLayout>
Параметр баннера ads:adUnitId в кавычках содержит идентификатор тестового баннера.
Замените его идентификатором вашего стандартного баннера.

В теле функции onCreate() AboutActivity инициализируйте баннер:

1 val adRequest = AdRequest.Builder().build()


2 adView.loadAd(adRequest)
3

В файле манифеста добавьте разрешение на доступ в интернет и метаданные для


управления показом рекламы:

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


2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="info.fandroid.topcrypts">
4
5 <uses-permission android:name="android.permission.INTERNET"/>
6
7 <application
8 ...
9
10 ...
11
12 <meta-data
13 android:name="com.google.android.gms.ads.APPLICATION_ID"
14 android:value="[ADMOB_APP_ID]"/>
15 </application>
16 </manifest>
17

Значение [ADMOB_APP_ID] замените на ваш идентификатор приложения, полученный при


создании рекламной кампании в AdMob.

1 class MainActivity : AppCompatActivity() {


2
3 private lateinit var mInterstitialAd: InterstitialAd
4
5
6 override fun onCreate(savedInstanceState: Bundle?) {
7 super.onCreate(savedInstanceState)
8 setContentView(R.layout.activity_main)
9
10 mInterstitialAd = InterstitialAd(this)
11 mInterstitialAd.adUnitId = "ca-app-pub-3940256099942544/1033173712"
12 mInterstitialAd.loadAd(AdRequest.Builder().build())
13
14 }
15
Значение mInterstitialAd.adUnitId замените идентификатором вашего межстраничного
баннера.

В MainActivity объявите и инициализируйте межстраничный баннер:

Ниже в коде MainActivity создайте функцию отображения межстраничного баннера:

1 private fun showAd() {


2 if (mInterstitialAd.isLoaded) {
3 mInterstitialAd.show()
4 }
5 }
6

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


вышеуказанную функцию в переопределенной функции системной кнопки “Назад”:

1 override fun onBackPressed() {


2 super.onBackPressed()
3 showAd()
4 }
5

Теперь запустите приложение на эмуляторе или устройстве. На информационном экране


внизу должен отображаться рекламный баннер. Также должен отображаться
межстраничный баннер при выходе их приложения системной кнопкой “Назад”: