Как сделать API на любое Android приложение. На примере WhatsApp
Приветствую! Нарисовалась у меня задача: нужно интегрировать в CRM систему мессенджеры, а то трудно анализировать работу менеджеров, когда они общаются с клиентами используя один общий «рабочий» телефон. И первым делом нужно было подключить WhatsApp, как один из самых популярных мессенджеров у нашей целевой аудитории.
Анализ ситуации.
Казалось, требуется всего лишь отправлять и принимать сообщения. А столько подводных камней…
1. Официальный API
Официального API в релизе тогда ещё не было. Но Facebook успел прислать ссылку на форму, для подключения официального API, находящегося в тестировании.
2. Сторонний сервис. Подключение через WhatsApp WEB
Рассматривал вариант «серого» способа, использование неофициального сервиса, который отправляет сообщения через WEB интерфейс, подключается сканированием QR кода.
Но это зависимость от чужого API, в любой момент может всё отвалиться, да и передавать чужому сервису номера клиентов не хотелось. А ещё писать под чужой авторский API, да ещё который придётся переписывать, при переезде на другой сервис, тоже такое себе удовольствие.
Ну и ещё требуется держать телефон включенным (хотя некоторые сервисы за доп плату решали эту проблему 🙂
3. Ручной режим
Посадить человека, пускай копипастит сообщения клиентам. Шутки шутками, а из этой идеи родилось решение!
Решение
Отправка сообщения

Есть такая программка для автоматизации действий под Android, называется Tasker, одна из первых подобных программ. Но я в ней не разобрался с первого раза… Поискал аналоги, наткнулся на программу Automagic. В ней события, действия и ветвления рисуются как блок схема.
Оффтоп
Передаю привет конструктору HiAsm, благодаря которому когда то научился понимать концепцию программирования.
И вот в ней я то и придумал решение, root права нам не нужны. Получилось методом научного тыка нарисовать скрипт отправки сообщения, далее буду называть поток, так именуется каждый отдельный нарисованный алгоритм в данной программе. А теперь разберём его работу:
Скриншот потока отправки сообщения в WhatsApp
- Каждые 5 секунд периодичным таймером генерируется событие и передаётся следующему блоку.
- Блок HTTP Request спрашивает у сервера, есть ли в очереди следующее сообщение, которое нужно отправить? Бэкенд написан на PHP.
- Парсим ответ сервера JSON.
- Если от сервера в ответе пришла метка, что нужно отправить сообщение, идём дальше.
- Проверяем, включен ли экран устройства, если нет, отправляем уведомление, с целью разбудить телефон. Если же экран включен, и не выполняется другой поток, проверяющий статус, доставлено ли сообщение, то:
- Генерируем ссылку и открываем её, что бы инициировать диалог с полученным от сервера номером телефона в WhatsApp’е
- Самое интересное. Блок Control UI. В нём в виде кода реализована логика проверки успешности открытия чата (проверка регистрации в мессенджере), вставка текста в окно ввода и клацанье по кнопке Отправить.
Код писал с мобильного, как заработал, больше не трогал
sleep(2000); // 2 секунды на запуск вацапа sle = 200; ch_c = 0; ch = false; is_sended = false; sleep(sle); ch = existsElementById("com.whatsapp:id/entry"); // Проверяем, появилась ли на экране кнопка отправить sleep(sle); if (ch == false) < ch = existsElementById("com.whatsapp:id/entry"); // Снова проверяем ch_c = ch_c + 1; sleep(1500); >if (ch == false) < ch = existsElementById("com.whatsapp:id/entry"); ch_c = ch_c + 1; sleep(5500); >ch = existsElementById("com.whatsapp:id/entry"); sleep(sle); setText2ById("com.whatsapp:id/entry",text); // Вставляем сообщение sleep(sle); clickById("com.whatsapp:id/send"); // Жмём кнопку отправить sleep(sle); back(); sleep(sle); back(); status = 2; if(ch == true) < // Если всё хорошо, запоминаем, для отправки на сервер is_sended = true; status = 1; >
Приём сообщений
Принимать сообщения на много проще. Ставим событие на уведомление от мессенджера. Как только приходит уведомление, помечаем его прочитанным, и отправляем его на сервер как есть. Тот уже спарсит адресата и текст.
Скриншот алгоритма приёма сообщений
Плюсы, минусы, доработка и планы
Основную функцию отправки сообщения алгоритм выполняет отлично. Так как не используется WEB интерфейс, схватить баню от мессенджера тут меньше рисков, как мне кажется. Арендовал слабенький виртуальный сервер, установил туда Android и перенёс всё.
На отправку одного сообщения новому контакту уходит ~5 сек. Для проверки доставки и прочтения сообщения, разработал отдельный поток, но он в черновом варианте и иногда не срабатывает. Поэтому о нём позже.
В данный момент не реализована функция приёма медиа сообщений (фото, аудио, вложения), но это можно выгружать из WhatsApp, используя кнопку поделиться сообщением в будущем.
Чуть позже хочу сверху виртуальной машины, где запущен мессенджер, написать SIP транк, через который можно будет звонить через WhatsApp как через SIP ^.^ что может сэкономить расходы на связь.
Ещё хочу делать скриншоты аватарок и отправлять их на сервер, для прикрепления миниатюры к контакту в CRM системе.
Ну и вообще самое интересное: Данный способ обёртывания в API подойдёт почти для любого приложения под Android 🙂
Всё изначально разрабатывал и запускал на Android 9, xiaomi mi 9 se, root прав нет.
UPD:
Пример на Python3.8 в качестве бекенда доступен на GitHub, доработан алгоритм ловли уведомлений и код отправки из комментариев от ivan909020
Проект API с точки зрения разработчика Android
По словам знакомых бэкенд-разработчиков, проще всего в моем случае начать писать серверное приложение на NodeJS с использованием TypeScript.
Любопытно то, что платформа NodeJS, предназначенная только для работы с JavaScript, не выполняет код TypeScript. В связи с этим требуется преобразовать код TypeScript в JavaScript. Такой процесс называется транспиляцией.
Что касается IDE, я поэкспериментировал с 2 инструментами: Visual Studio Code и WebStorm. В итоге отдал предпочтение второму варианту. Как оказалось, мне намного проще работать с WebStorm, поскольку я привык к Android Studio. Оба эти инструмента входят в число продуктов JetBrains, поэтому обладают схожими принципами разработки.
Структура проекта
Существует множество способов организации файлов в серверном приложении. Рассмотрим один из них, более соответствующий проекту Android:
Прокомментируем эту схему, проводя терминологические параллели с разработкой Android.
- package.json — это своего рода синтез build.gradle и AndroidManifest.xml , если посмотреть на проект с точки зрения разработчика Android. В этом файле мы определяем: имя и версию приложения; главный файл, в котором оно запускается; скрипты, например задачи Gradle ; зависимости; зависимости разработки и другое.
- __test__ — каталог для размещения модульных тестов. На стороне сервера в качестве фреймворка используется Jest, аналог JUnit в разработке Android.
- jest.config.js — файл, в котором мы определяем конфигурацию тестов и способ их выполнения.
- src — каталог для группировки кода, что-то наподобие главного модуля приложения main .
Архитектура
Точки входа
На стороне сервера в качестве точек входа используются не Activity и Fragments , а маршруты (англ. routes). У нас нет UI, которого может коснуться пользователь. Приложения, которые в данном случае являются пользователями, вызывают разные маршруты: GET , POST , PUT и другие. Рассмотрим пример маршрута.
Пример 1. Базовая конфигурация для применения Express с пользовательским объектом Router .
import express, < Request, Response, NextFunction >from "express";
require('express-async-errors');
import < historyRoutes >from "./routes/history.routes";
const app = express();
app.use(express.json());
app.use("/history", historyRoutes);
Express — это фреймворк, упрощающий процесс создания маршрутов. Как видно, файл app.ts импортирует historyRoutes , уже определенный файлом historic.routes.ts . Рассмотрим пример метода POST , делегированного определенному контроллеру, который перенаправляет запрос в конкретный UseCase .
Пример 2. Объект Controller обрабатывает запрос POST .
import < Router >from "express";
import < CreateNewHistoricEntryController >from "../../controllers/CreateNewHistoricEntryController";
const historyRoutes = Router();
const createNewHistoricEntryController = new CreateNewHistoricEntryController();
historyRoutes.post("/historic", createNewHistoricEntryController.handle);
export < historyRoutes >;
Внедрение зависимостей
Если вы с удовольствием работаете с Koin и Kodein в мире Android, то с легкостью освоите TSyringe в качестве библиотеки для внедрения зависимостей.
Следующий код отображает файл server.ts , в котором мы регистрируем ссылку на Singleton для FirestoreDataSource , реализующего интерфейс ISisOrgRepository . Этот файл подобен классу Application и является точкой входа приложения.
Пример 3. Добавление экземпляра репозитория Application , который будет доступен для всего приложения.
import < container >from "tsyringe";
.
function setup() container.registerSingleton(
"ISisOrgRepository",
FirestoreDataSource
);
>
.
app.listen(port, () => setup();
console.log("Server is running. ");
>);
Библиотека TSyringe знает, что если кому-то потребуется ссылка на ISisOrgRepository , она обязана предоставить экземпляр FirestoreDataSource . В этом случае класс CreateNewHistoricEntryController должен создать CreateNewHistoricEntryUseCase . Но для этого необходимо попросить TSyringe разрешить зависимости (аргумент конструктора ISisOrgRepository ).
Пример 4. UseCase с аннотациями, помогающими библиотеке для внедрения зависимостей.
@injectable()
class CreateNewHistoricEntryUseCase constructor(
@inject("ISisOrgRepository")
private sisOrgRepository: ISisOrgRepository
) >
async execute(request: IRequest): Promise const historicEntries: IHistoricEntry[] = [];
.
await this.sisOrgRepository.createHistoricEntry(historicEntries);
return historicEntries;
>
>
export < CreateNewHistoricEntryUseCase >;
Внутри CreateNewHistoricEntryController мы можем попросить библиотеку для внедрения зависимостей о содействии в создании объекта CreateNewHistoricEntryUseCase .
Пример 5. Контроллер запрашивает ссылку на контейнер UseCase .
import < Request, Response >from "express";
import < container >from "tsyringe";
import < CreateNewHistoricEntryUseCase >from "../domain/useCases/CreateNewHistoricEntryUseCase";
class CreateNewHistoricEntryController async handle(request: Request, response: Response): Promise const < beds, activity, crop, variety, resultIndicator, input >= request.body;
const useCase = container.resolve(CreateNewHistoricEntryUseCase);
const result = await useCase.execute( beds, activity, crop, variety, resultIndicator: resultIndicator, input
>);
return response.status(201).json(result);
>
>
export < CreateNewHistoricEntryController >;
Тесты
Я опробовал две очень похожие библиотеки: Jasmine и Jest. В итоге выбрал Jest, поскольку она предоставляет отличный формат вывода результатов.
Пример 6. Отчет о результатах выполнения от Jest.
Синтаксис сильно отличается от тестов JUnit, использующих Kotlin. Однако все проясняется, если понимать describe как имя набора тестов, а it — как имя модульного теста. Часть, касающаяся утверждений, не представляет сложности и напоминает принцип работы с библиотекой Truth.
Пример 7. Тест с применением Jest в TypeScript — класс TimeHelper .
mport < TimeHelper >from "util/TimeHelper"
describe("Time Helper", () => it("should get total minutes from 3h", () => const totalMinutes = TimeHelper.getTotalMinutes("3h")
expect(totalMinutes).toBe(180)
>)
it("should get total minutes from 3h 15min", () => const totalMinutes = TimeHelper.getTotalMinutes("3h 15min")
expect(totalMinutes).toBe(195)
>)
>)
Дополнительные рекомендации
- Heroku — отличная платформа для размещения API. Она предоставляет удобный CLI. Если package.json в порядке, то при каждой отправке кода CLI автоматически выполняет скрипты (транспиляцию, установку зависимостей, запуск сервера).
- Insomnia — превосходный инструмент для тестирования маршрутов. С его помощью можно создавать различные среды (разработки, продакшн и т.д.)
- Swagger позволяет создавать содержательную документацию, в которой можно запускать маршруты (пример по ссылке).
Заключение
Если вы начинаете задействовать новые технологии, советую обращаться к опыту специалистов и обсуждать с ними технические вопросы. Их оперативные рекомендации помогут сэкономить время и быстрее научиться всему необходимому.
- Kotlin Coroutines для Android — Прощай RxJava?
- Как работают обобщения в Kotlin
- Автоматизация создания файлов для нового экрана с плагином для Android Studio
Читайте нас в Telegram, VK и Дзен
Как подключаться к веб-API из Android-приложения
В этой статья я расскажу, как подключиться к веб-API из приложения Android с помощью Retrofit!
Содержание показать
Веб-API — это интерактивный «интерфейс прикладного программирования», который позволяет разработчикам взаимодействовать с внешними службами. Это команды, которые, по мнению разработчика службы, будут использоваться для доступа к определенным функциям их программы. Он называется интерфейсом, потому что в хорошем API должны быть команды, делающие его интуитивно понятным для взаимодействия.
Примером этого может быть случай, когда мы хотим получить информацию о пользователе из его учетной записи в социальной сет. Эта платформа социальных сетей, скорее всего, будет иметь веб-API, который разработчики будут использовать для запроса этих данных. Другие часто используемые API обрабатывают такие вещи, как реклама (AdMob), машинное обучение ( ML Kit ) и облачное хранилище.
Легко увидеть, как взаимодействие с этими типами служб может расширить функциональность приложения. Фактически, подавляющее большинство успешных приложений в Play Store используют хотя бы один веб-API!
В этом посте мы рассмотрим, как использовать веб-API из приложения для Android.
Как работает веб-API
Большинство API работают с использованием XML или JSON. Эти языки позволяют нам отправлять и получать большие объемы полезной информации в виде объектов.
XML — это расширяемый язык разметки. Если вы разработчик Android, то вы, вероятно, уже знакомы с XML по созданию макетов и сохранению переменных.
XML прост для понимания и обычно помещает ключи в треугольные скобки, за которыми следуют их значения. Он немного похож на HTML:
Александр 41
JSON означает «Нотация объектов Javascript». Это сокращение для отправки данных в Интернете. Подобно XML или CSV-файлу, его можно использовать для отправки «пар значение/атрибут».
Однако здесь синтаксис выглядит немного иначе:
Это «объекты данных» в том смысле, что они являются концептуальными сущностями (в данном случае людьми), которые могут быть описаны парами ключ/значение. Мы используем их в наших приложениях для Android, превращая их в объекты, как обычно, с использованием классов.
Чтобы увидеть это в действии, нам нужно найти веб-API, который мы сможем легко использовать. В этом примере мы будем использовать заполнитель JSON. Это бесплатный REST API специально для тестирования и создания прототипов, который идеально подходит для изучения нового навыка! REST — это особый архитектурный «стиль», ставший стандартом для связи по сетям. REST-совместимые системы называются «RESTful» и обладают определенными характеристиками. Однако вам не нужно сейчас об этом беспокоиться.
Настройка нашего проекта для Retrofit 2
В этом примере мы также будем использовать REST-клиент под названием Retrofit 2. Это очень полезный HTTP-клиент для Android, который позволяет приложениям безопасно подключаться к веб-API с существенно меньшим количеством кода. Затем его можно использовать, например, для отображения твитов из Twitter или для проверки погоды. Он значительно сокращает объем работы, которую разработчику нужно сделать, чтобы все работало.
Во-первых, нам нужно добавить разрешение для доступа в Интернет в наш файл манифеста Android, чтобы убедиться, что нашему приложению разрешено выходить в Интернет. Вот что вам нужно включить:
Нам также необходимо добавить зависимость, если мы собираемся заставить Retrofit 2 работать в нашем приложении. Итак, в вашем файле build.gradle на уровне модуля добавьте:
Нам также понадобится что-то под названием Gson:
Gson — будет преобразовывать данные JSON в объект Java для нас (процесс, называемый десериализацией). Мы могли бы сделать это вручную, но использование подобных инструментов значительно упрощает жизнь!
На самом деле существуют более поздние версии Retrofit, в которые внесены некоторые изменения. Если вы хотите быть в курсе событий, загляните на официальный сайт.
Преобразование JSON в объект Java
«Route» — это URL-адрес, представляющий конечную точку для API. Если мы посмотрим на заполнитель JSON, вы увидите, что у нас есть такие параметры, как «/posts» и «/comments?postId=1». Скорее всего, вы сами видели такие URL-адреса при просмотре веб-страниц!
Щелкните на /posts, и вы увидите большой объем данных в формате JSON. Это фиктивный текст, который имитирует внешний вид страницы, полной сообщений в социальных сетях. Это информация, которую мы хотим получить из нашего приложения и затем отобразить на экране.
Для обработки этой информации нам понадобится класс, который может создавать объекты из десериализованных данных. Для этого создайте в своем проекте новый класс и назовите его «PlaceholderPost». Для этого потребуются переменные, соответствующие данным, которые мы получаем со страницы /posts («body», «ID» и т.д.). Мы будем получать эту информацию из веб-API, поэтому нам нужен геттер для каждого из них.
Итоговый класс должен выглядеть так:
public class PlaceholderPost < private int userID; private int id; private String title; private String body; public int getUserId() < return userID; >public int getId() < return id; >public String getTitle() < return title; >public String getBody() < return body; >>
С таким же успехом это могут быть пользователи Twitter, сообщения в Facebook или информация о погоде!
Файлы интерфейса
Далее нам понадобится новый интерфейсный файл. Вы создаете его так же, как и класс: щелкая имя вашего пакета в окне проекта и выбирая «New>Class», но здесь вы выбираете «Interface» под тем местом, где вы вводите имя. Файл интерфейса содержит методы, которые позже реализуются классом. Я назвал свой «PlaceholderAPI».
Этому интерфейсу нужен только один метод для извлечения всех данных из «/Post». Если вы еще раз взглянете на этот JSON, вы заметите, что фигурные скобки находятся внутри квадратных скобок. Это означает, что у нас есть массив объектов, поэтому мы хотим создать для них список. Объекты — это экземпляры нашего «PlaceholderPost», которые мы только что создали, вот что мы и помещаем сюда!
Для тех, кто новичок в программировании, помните, что любые красные линии, означают, что вы не импортировали класс. Просто щелкните выделенный оператор и нажмите alt+return, чтобы сделать это автоматически.
(Я не могу представить, чтобы кто-то использовал это урок как первый в программирования, но как знать!)
Это выглядит так:
import java.util.List; import retrofit2.Call; import retrofit2.http.GET; public interface PlaceholderAPI < @GET("posts") CallgetPosts(); >
Показ содержимого
Теперь вернитесь к своему основному занятию. Мы могли бы создать причудливый макет для отображения всех этих данных, но, чтобы все было красиво и просто, я просто буду придерживаться макета как есть.
Чтобы использовать Retrofit, нам нужно создать новый класс Retrofit Factory, который даст вам один и тот же объект Retrofit всякий раз, когда вы его попросите. В результате должно получиться вот так:
package ru.xpcom.retrofit2; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class RetrofitFactory < private static Retrofit retrofit = null; private RetrofitFactory () <>// class should not be initialized public static Retrofit getRetrofit(String baseUrl) < if(retrofit == null) < retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) .build(); >return retrofit; > >
Как видите, здесь мы передаем остальную часть URL-адреса. Затем мы будем использовать наш интерфейс:
Call call = placeholderAPI.getPosts();
Теперь нам просто нужно вызвать метод в классе MainActivity! Поскольку до сих пор все было слишком просто, Android не дает вам сделать это в основном потоке. Причина, конечно же, в том, что если процесс займет слишком много времени, приложение зависнет! Это актуально при использовании любого веб-API. В этом есть смысл, но это не очень удобно, когда мы просто хотим создать учебник. К счастью, нам не нужно создавать второй поток самостоятельно, поскольку Retrofit фактически делает все это за нас.
Теперь мы получим обратные вызовы onResponse и onFailure. onFailure — это то место, где нужно обрабатывать любые ошибки.
Однако onResponse не означает, что все прошло гладко. Это просто означает, что был ответ; что сайт существует. Если мы получим сообщение 404, это все равно будет считаться «ответом». Таким образом, нам нужно еще раз проверить, прошел ли процесс гладко, с помощью isSuccessful() , который проверяет, не является ли код HTTP ошибкой.
Для простоты я собираюсь отобразить только один фрагмент данных одного из объектов, которые мы получили. Для этого я переименовал textView в файле макета, присвоив ему идентификатор «текст». Вы можете поэкспериментировать с этим сами.
Полный код выглядит так:
package ru.xpcom.retrofit2; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; public class MainActivity extends AppCompatActivity < public final String URL_API = "https://jsonplaceholder.typicode.com/"; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getDataFromApi (); >private void getDataFromApi () < Retrofit retrofit = RetrofitFactory.getRetrofit(URL_API); PlaceholderAPI placeholderAPI = retrofit.create(PlaceholderAPI.class); Callcall = placeholderAPI.getPosts(); call.enqueue(new Callback() < @Override public void onResponse(Callcall, Response response) < if (response.isSuccessful()) < List posts = response.body(); Log.d("Success", posts.get(3).getBody().toString()); TextView textView = findViewById(R.id.text); textView.setText(posts.get(3).getBody().toString()); >else < Log.d("Ей", "Вау!"); return; >> @Override public void onFailure(Call call, Throwable t) < Log.d("Ей", "Ошибка!!"); >>); Log.d("Эй","Привет!"); > >
Подведем итог
На этом этапе у вас должно быть хорошее представление о том, как работает веб-API и почему он вам нужен. Вы бы также создали свое первое приложение, которое использует веб-API для выполнения чего-то потенциально полезного.
Конечно, существует бесчисленное множество других веб-API, и каждый работает по-своему. Некоторым потребуются дополнительные SDK или другие библиотеки. Точно так же есть много других действий помимо запроса «GET», который мы продемонстрировали здесь. Например, вы можете использовать «POST» для отправки данных на сервер, что полезно, если вы хотите, чтобы ваши пользователи могли публиковать сообщения в социальных сетях из ваших приложений.
Возможности безграничны, если объединить мощь и гибкость Android с огромными ресурсами, доступными в Интернете.
Изучение Android Studio за одну статью! Создание программы с API

ОС Андроид – одна из самых популярных ОС в мире. Мы подготовили большой урок по изучению программы Android Studio и построению полноценного Андроид приложения. За урок мы сделаем программу с API.
Информация про Андроид
На ОС Андроид сегодня работают не только мобильные и планшетные устройства, но также всевозможные часы, телевизоры, компьютеры и даже, как бы это не звучало, холодильники.

Несмотря на огромное множество устройств разработка под многие из них происходит через одну общую программу – Android Studio . Конечно же, у каждой платформы будут свои особенности: размер экрана, характеристики устройства и так далее. Тем не менее, общий процесс создания будет примерно схожим.
Таким образом, изучив Андроид Студио вы сможете в будущем спокойно переходить от одной платформы к другой. Напомним, на сегодняшний день только мобильные устройства на ОС Андроид занимают примерно 85% всего рынка смартфонов.
Языки программирования для Андроид
Разрабатывать под Андроид можно за использованием нескольких разных языков программирования. Зачастую все разрабатывают на основе языка Java, но помимо него можно использовать язык Kotlin, Python, React Native, Flutter и даже на HTML и CSS можно делать проекты.
Ниже видео на тему разработки Андроид проекта на HTML и CSS:
Вы можете использовать разные языки, но наиболее часто используется Джава или его более молодой собрат – Kotlin . В любом случае, если вы только приступаете к Андроид, то ни про какой другой язык помимо Джава вам не стоит думать. Если в будущем нужно будет писать на Котлин, то вам все равно знания разработки Андроид проектов на Джава будут нужны.
Установка всего необходимого
Для разработки под Андроид требуется всего две вещи. Во-первых, вам нужно скачать на компьютер Джава JDK. Это можно сделать через официальный сайт Oracle.
Во-вторых, вам потребуется программа Андроид Студио. Именно она является наиболее популярной программой для разработки приложений под Андроид. Скачать бесплатно эту программу можно также с ее официального сайта . После скачивания Джава и Андроид Студио выполните их установку и далее мы сможем приступить к разработке проекта.
Создание функций
Теперь нам нужно создать весь функционал для приложения.
В приложении мы будем получать данные о погоде. Чтобы это делать сперва зарегистрируйтесь и получите API ключ на сайте OpenWeaterMap .
Теперь остается прописать весь код. Код класса «MainActivity» представлен ниже вместе с комментариями.
Дополнительно скачать полностью весь проект можно по этой ссылке .
package com.itproger.weatherapp; import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class MainActivity extends AppCompatActivity < // Поля, что будут ссылаться на объекты из дизайна private EditText user_field; private Button main_btn; private TextView result_info; @Override protected void onCreate(Bundle savedInstanceState) < // Сработает при создании Activity super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Устанавливаем ссылки на объекты из дизайна user_field = findViewById(R.id.user_field); main_btn = findViewById(R.id.main_btn); result_info = findViewById(R.id.result_info); // Обработчик нажатия на кнопку main_btn.setOnClickListener(new View.OnClickListener() < @Override public void onClick(View view) < // Если ничего не ввели в поле, то выдаем всплывающую подсказку if(user_field.getText().toString().trim().equals("")) Toast.makeText(MainActivity.this, R.string.no_user_input, Toast.LENGTH_LONG).show(); else < // Если ввели, то формируем ссылку для получения погоды String city = user_field.getText().toString(); String key = "ваш ключ здесь"; String url = "https://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=" + key + "&units=metric&lang=ru"; // Запускаем класс для получения погоды new GetURLData().execute(url); >> >); > @SuppressLint("StaticFieldLeak") private class GetURLData extends AsyncTask < // Будет выполнено до отправки данных по URL protected void onPreExecute() < super.onPreExecute(); result_info.setText("Ожидайте. "); >// Будет выполняться во время подключения по URL @Override protected String doInBackground(String. strings) < HttpURLConnection connection = null; BufferedReader reader = null; try < // Создаем URL подключение, а также HTTP подключение URL url = new URL(strings[0]); connection = (HttpURLConnection) url.openConnection(); connection.connect(); // Создаем объекты для считывания данных из файла InputStream stream = connection.getInputStream(); reader = new BufferedReader(new InputStreamReader(stream)); // Генерируемая строка StringBuilder buffer = new StringBuilder(); String line = ""; // Считываем файл и записываем все в строку while((line = reader.readLine()) != null) buffer.append(line).append("\n"); // Возвращаем строку return buffer.toString(); >catch (MalformedURLException e) < e.printStackTrace(); >catch (IOException e) < e.printStackTrace(); >finally < // Закрываем соединения if(connection != null) connection.disconnect(); try < if (reader != null) reader.close(); >catch (IOException e) < e.printStackTrace(); >> return null; > // Выполняется после завершения получения данных @SuppressLint("SetTextI18n") @Override protected void onPostExecute(String result) < super.onPostExecute(result); // Конвертируем JSON формат и выводим данные в текстовом поле try < JSONObject jsonObject = new JSONObject(result); result_info.setText("Температура: " + jsonObject.getJSONObject("main").getDouble("temp")); >catch (JSONException e) < e.printStackTrace(); >> > >
Видео на эту тему
Также вы можете просмотреть детальное видео по разработке данного приложения:
Дополнительный курс
На нашем сайте также есть углубленный курс по изучению языка Java . В ходе огромной программы вы изучите не только язык Java, но также научитесь создавать веб сайты, программы под ПК, приложения под Андроид и многое другое. За курс вы изучите массу нового и к концу программы будете уметь работать с языком Java и создавать на нём полноценные проекты.
Больше интересных новостей

10 фильмов про искусственный интеллект

Стоит ли в настоящее время становиться Java-разработчиком?

6 неявных ошибок новичков в Pandas

Программа на Python для управления компьютером / PyAutoGui
Комментарии (4)
Роман 20 мая 2023 в 16:56
Приложение вылетает
Аки 05 марта 2023 в 12:31
«Этот файл нельзя открыть, так как он нарушает Условия использования.»
При открытие ссылки проекта вот что показывает
Алекс 31 октября 2022 в 06:35
Падает при кривом вводе названия города )
Нужно с исключениями ещё поработать
Прохор 13 января 2023 в 19:25
А у меня вылетает при введении города, не знаю в чём проблема, вроде делал как на видио.
Роман 06 августа 2022 в 00:10