Начну с обязательного предисловия.
Я ни в коем случае не являюсь разработчиком приложений для операционной системы Android. Более того, на момент написания поста я видел Android Studio третий раз в жизни и никогда не занимался созданием программ для Android. Пришлось штудировать матчасть.
Теперь по теме поста.
Попался мне в руки безымянный электронный замок с вызывной панелью, камерой и простым веб-сервером. На основной веб-странице, помимо фрейма с видеопотоком и настройками устройства, присутствует интересная кнопка. С её помощью можно открыть замок пройдя парольную авторизацию.
Мне стало интересно — а можно ли открывать замок, выполняя запрос напрямую из адресной строки браузера? Спустя пару чашек кофе, я откопал в коде ссылку на cgi-скрипт, открывающий дверь. Именно в этот момент мне пришла в голову идея создания приложения-ключа для Android.
Установив на компьютер Android Studio, я принялся за создание приложения с условным названием — OpenDoor. Коротко и ясно, — думалось мне.
А потом случилось это:
— А чего ты не назвал приложение Аллохомора?
VoatiK (но уже постфактум)
Как-то не вспомнилось… А ведь какое было бы название! И работает по тому же принципу, и звучит красиво, и отсылка опять же…

Продолжим! Языком разработки я выбрал Java. В качестве шаблона взял «Empty Activity» и Android 5.0 Lollipop — минимальной совместимой версией ОС. Так как OpenDoor будет работать с сетью, добавил в файл манифеста (AndroidManifest.xml) строку:
<uses-permission android:name="android.permission.INTERNET" />
Во многих источниках упоминалось, что если приложение будет сталкиваться именно с http (открытый текстовый трафик), нужно добавить в манифест еще и это:
android:usesCleartextTraffic="true"
Итоговый файл AndroidManifest.xml выглядел вот так:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:usesCleartextTraffic="true"
android:supportsRtl="true"
android:theme="@style/Theme.OpenDoor"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Теперь про дизайн. В Android Studio за размещение элементов управления отвечает файл activity_main.xml. А раскрасить элементы можно, используя файлы со стилями, цветами и темами. Например, отключить action-bar приложения можно через themes.xml с помощью строки:
<style name="Theme.OpenDoor" parent="Theme.AppCompat.Light.NoActionBar">
В файл colors.xml можно вносить цвета и давать им имена, чтобы ссылаться именно на название цвета, а не его код. Очень удобно — особенно — когда нужно что-то централизовано перекрасить.
Стоит заметить, что представление файла activity_main.xml очень сильно напоминает старый добрый WYSIWYG редактор из тех времён, когда они ещё были в моде.
Для работы заветного приложения была нужна всего одна кнопка с надписью «Открыть дверь» и расположить её хотелось по самому центру экрана. Фон приложения мне виделся исключительно белым, что создавало бы эффект эмуляции фонарика в темное время суток.
Кнопку (объект Button) я разместил в LinearLayout с вертикальной ориентацией (android:orientation=»vertical») и центральной гравитацией объектов (android:gravity=»center»).
Чтобы прикрутить к нажатию кнопки функцию — я использовал конструкцию android:onClick=»OpenDoor», где OpenDoor — это имя вызываемой функции из файла MainActivity.java, но об этом чуть ниже.
Итоговый код activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<Button
android:id="@+id/opendoorbtn"
android:layout_width="266dp"
android:layout_height="94dp"
android:backgroundTint="@color/purple_700"
android:onClick="OpenDoor"
android:text="Открыть дверь"
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="20sp"
android:tooltipText="Нажмите для открытия двери" />
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="bottom|end">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="code by ngdream"
android:textAlignment="center"
android:textColor="@color/gray" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
В нижний LinearLayout добавил надпись «code by ngdream«, установив гравитацию по нижнему краю с помощью конструкции: android:gravity=»bottom|end».
С дизайном более-менее разобрались. Кнопку нарисовали, раскрасили и разместили. Теперь оживим приложение.
Все методы я запихнул в файл — MainActivity.java.
Обращение к http сформировал на основе библиотеки Volley. Здесь (тык) можно подсмотреть пример простого запроса и подогнать его под свои нужды. Установку библиотеки в проект можно осуществить, добавив в файл build.gradle(:app) новую зависимость (блок dependencies):
dependencies {
...
implementation 'com.android.volley:volley:1.2.1'
...
}
Как только библиотека установится — можно писать код. Даже если залить в java-файл копипасту из официальной документации Volley и уже на месте править, Android Studio очень тонко намекнёт на импорт нужных классов.
Итоговый вариант MainActivity.java получился таким:
package ru.ngdream.opendoor;
// Импорт модулей в проект
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
public class MainActivity extends AppCompatActivity {
// Действие при запуске приложения
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// Действие по кнопке
public void OpenDoor(View view) {
httpCall("http://192.168.0.100/web/cgi-bin/hi3510/doorUnlock.cgi");
}
// Всплывающее сообщение
public void MessageView(String text) {
Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
toast.show();
}
// HTTP запрос
public void httpCall(String url) {
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
MessageView("Дверь открыта!");
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
MessageView("Что-то пошло не так...");
}
});
queue.add(stringRequest);
}
}
Для понимания логики: я добавил метод вывода всплывающих сообщений MessageView и прицепил его к событиям в методе httpCall, который, в свою очередь, выполняется в методе OpenDoor. Именно OpenDoor является титулярным методом и вызывается при нажатии на единственную кнопку.
Если всё прошло успешно и httpCall получил данные от заданного url — дверь откроется и внизу появится соответствующее сообщение. В противном случае вылезет надпись «что-то пошло не так…».
А теперь немного про иконку приложения. Android Studio умеет делать отличные иконки без использования графических редакторов.
Достаточно указать цвет фона и выбрать из обширной коллекции клип-арта нужную пиктограмму. Также среда разработки умеет создавать вариации формы иконок для разных оболочек операционных систем.

Резюмируя, скажу, что порог вхождения в разработку приложений для Android крайне низок и за вечер можно спокойно собрать что-то подобное даже не разбираясь в дебрях и тонкостях Android Studio. Для разработки простого приложения хватит базовых знаний Java. Единственный очевидный минус этой среды разработки, с которым придётся мириться — это требования к железу.
P.S.: работа приложения гарантируется только если смартфон и электронный замок находятся в одной сети.





