Разработка ИИ запросов (AI Prompts) для генерации кода.
https://oflameron.ru/Valery_Shmelev_5eng.pdf
AI-powered Code Generation
Разработаем запрос к ИИ для генерирования Android Studio Java кода генератора энтропии - гигантского псевдослучайного числа.
В запросе длина числа ограничена размером файла - 10124000 байт. Можно поменять на большее значение.
Генератор использует случайность младшего разряда данных от канада X акселерометра смартфона.
Принципиально возможно значительно повысить эффективность такой генерации случайных чисел используя добавление значений от
криптографических алгоритмов (например Блюма-Блюма-Шуба), из потока разговорного Интернет-радио, данных от микрофона, многочисленных преобразований "Текст В Голос" и т.д.
Запрос проверялся в бесплатном чате chat.deepseek.com Приложение тестировалось на смартфоне Samsung S23 под Android 14.
Файл с псевдослучайным числом записывается в папку Download смартфона и может быть скопирован на второй смартфон, после чего
может быть организован обмен защищёнными сообщениями с использованием кода Вернама (XOR преобразования)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Техническое задание (prompt) для приложения "LargeEntropy"
1. ОСНОВНЫЕ ХАРАКТЕРИСТИКИ
-Цель: Генерация файла энтропии на основе данных акселерометра/гироскопа
-Платформа: Android 14 (API 33), минимальная поддержка Android 5.0 (API 21)
-Язык: Java
-Архитектура: Single Activity с простой MVP структурой
-Требования к производительности: Минимальное потребление ресурсов, фоновая работа сенсоров
2. ТЕХНОЛОГИИ И БИБЛИОТЕКИ
- Android SDK 33
- AndroidX: AppCompat, Core, Activity
- Sensor API (Hardware Sensor Framework)
- File I/O (java.io)
- BigInteger для обработки числовых данных
- Handler для периодических задач
- AlertDialog для пользовательских сообщений
- Logging для отладки
- Permission Handling для Android 11+
3. РАЗРЕШЕНИЯ (PERMISSIONS)
3.1 Необходимые разрешения:
AndroidManifest.xml:
xml
3.2 Логика запроса разрешений:
1. Проверка версии Android:
- API >= 30: Использовать MANAGE_EXTERNAL_STORAGE
- API < 30: Использовать WRITE_EXTERNAL_STORAGE
2. Процесс запроса:
a) Проверить текущие разрешения
b) Если нет разрешения -> показать диалог с объяснением
c) Для MANAGE_EXTERNAL_STORAGE: открыть системные настройки
d) Для WRITE_EXTERNAL_STORAGE: стандартный запрос разрешений
3. Обработка результата:
- Успех: продолжить инициализацию
- Отказ: показать сообщение и завершить приложение
4. ПЕРЕМЕННЫЕ И ТИПЫ В MainActivity.java
4.1 Константы (Constants):
java
private static final String TAG = "LargeEntropy"; // Тег для логирования
private static final int FSize = 1024000; // Целевой размер файла (1MB)
private static final int PERMISSION_REQUEST_LEGACY = 100; // Код запроса для API < 30
private static final int MANAGE_STORAGE_REQUEST = 101; // Код запроса для API >= 30
4.2 Ссылки на UI компоненты (UI References):
java
private TextView tvStatus; // TextView для отображения статуса и размера файла
private Button btnExit; // Кнопка для завершения приложения
4.3 Объекты сенсоров (Sensor Objects):
java
private SensorManager sensorManager; // Менеджер сенсоров для доступа к аппаратным датчикам
private Sensor sensor; // Текущий активный сенсор (акселерометр или гироскоп)
private SensorEventListener sensorListener; // Слушатель событий сенсора
4.4 Файловые объекты (File Objects):
java
private File dataFile; // Объект файла czechentropy.mp4
private FileOutputStream fos; // Поток для записи в файл
4.5 Переменные обработки данных (Data Processing Variables):
java
private char LeastSignificantDigit = '0'; // Текущая цифра (последняя записанная)
private char LeastSignificantDigit2 = '0'; // Новая цифра (полученная с сенсора)
4.6 Флаги состояния (State Flags):
java
private boolean isRunning = true; // Флаг работы приложения
private boolean hasStoragePermission = false; // Флаг наличия разрешений на хранилище
4.7 Объекты многопоточности (Threading Objects):
java
private Handler handler; // Handler для периодических задач в UI потоке
private Runnable fileCheckRunnable; // Задача для периодической проверки размера файла
5. ЛОГИРОВАНИЕ (LOGGING)
5.1 Уровни логирования:
java
Log.d(TAG, "Информационные сообщения"); // DEBUG - общая информация
Log.i(TAG, "Важные события"); // INFO - ключевые события
Log.w(TAG, "Предупреждения"); // WARN - не критичные ошибки
Log.e(TAG, "Критические ошибки"); // ERROR - критичные ошибки
Log.e(TAG, "=== Least Significant Digit ===" + digit); // Специальный лог для цифр
5.2 Ключевые точки логирования:
1. Инициализация приложения
2. Запрос и получение разрешений
3. Создание/открытие файла
4. Подключение сенсора
5. Получение каждой новой цифры
6. Запись в файл
7. Проверка размера файла
8. Ошибки на всех этапах
6. ПРОВЕРКА ЦИФР (DIGIT VALIDATION)
6.1 Алгоритм проверки:
java
// Шаг 1: Получение значения с сенсора (только ось X)
float xValue = event.values[0];
// Шаг 2: Преобразование float -> строка
String valueStr = Float.toString(xValue);
// Шаг 3: Очистка строки (удаление точки и минуса)
valueStr = valueStr.replace(".", "").replace("-", "");
// Шаг 4: Удаление ведущих нулей
while (valueStr.startsWith("0") && valueStr.length() > 1) {
valueStr = valueStr.substring(1);
}
// Шаг 5: Проверка на пустую строку
if (valueStr.isEmpty()) return;
// Шаг 6: Преобразование в BigInteger
BigInteger bigInt = new BigInteger(valueStr);
String bigIntStr = bigInt.toString();
// Шаг 7: Извлечение последней цифры
if (!bigIntStr.isEmpty()) {
char digit = bigIntStr.charAt(bigIntStr.length() - 1);
// Шаг 8: Валидация цифры (0-9)
if (digit >= '0' && digit <= '9') {
// Шаг 9: Логирование
Log.e(TAG, "=== Least Significant Digit ===" + digit);
// Шаг 10: Сравнение с предыдущей цифрой
if (previousDigit != digit) {
// Шаг 11: Запись в файл
writeDigitToFile(previousDigit);
previousDigit = digit;
}
}
}
7. ОБРАБОТКА ОШИБОК (ERROR HANDLING)
7.1 Уровни обработки ошибок:
1. Уровень разрешений:
- Нет доступа к хранилищу
- Пользователь отказал в разрешениях
2. Уровень файловой системы:
- Хранилище недоступно (не mounted)
- Не удалось создать папку
- Не удалось создать файл
- Ошибка записи в файл
- Ошибка чтения файла
3. Уровень сенсоров:
- Сенсоры недоступны
- Ошибка регистрации слушателя
- Ошибка обработки данных сенсора
4. Уровень данных:
- Некорректные данные с сенсора
- Ошибка преобразования типов
- Ошибка валидации цифр
7.2 Механизмы обработки:
java
// 1. Try-Catch для критичных операций
try {
// Критичный код
} catch (IOException e) {
Log.e(TAG, "Ошибка ввода-вывода", e);
showErrorToUser("Ошибка работы с файлом: " + e.getMessage());
} catch (SecurityException e) {
Log.e(TAG, "Ошибка безопасности", e);
showErrorToUser("Нет разрешения: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Неизвестная ошибка", e);
showErrorToUser("Произошла ошибка: " + e.getMessage());
}
// 2. Проверки перед выполнением операций
if (!isStorageAvailable()) {
showErrorToUser("Хранилище недоступно");
return;
}
// 3. Graceful degradation
if (sensor == null) {
Log.w(TAG, "Сенсор недоступен, работа без генерации данных");
tvStatus.setText("Сенсоры недоступны - сбор данных невозможен");
// Приложение продолжает работать, но без генерации
}
8. ПОЛЬЗОВАТЕЛЬСКИЕ СООБЩЕНИЯ (USER MESSAGES)
8.1 Типы сообщений:
java
// 1. Toast - краткие уведомления
Toast.makeText(context, "Сообщение", Toast.LENGTH_SHORT).show();
// 2. AlertDialog - важные сообщения, требующие внимания
new AlertDialog.Builder(context)
.setTitle("Заголовок")
.setMessage("Подробное сообщение")
.setPositiveButton("OK", null)
.show();
// 3. TextView статуса - постоянная информация
tvStatus.setText("Текущий статус: " + status);
// 4. Log - для разработчиков
Log.d(TAG, "Отладочная информация");
8.2 Ключевые сообщения для пользователя:
1. Начальные:
- "Проверка разрешений..."
- "Запуск приложения..."
2. Разрешения:
- "Доступ к хранилищу необходим для создания файла czechentropy.mp4"
- "Доступ отклонен. Приложение закроется."
3. Файловая система:
- "Хранилище недоступно"
- "Файл создан"
- "Файл найден. Размер: X байт"
4. Сенсоры:
- "Акселерометр подключен"
- "Гироскоп подключен"
- "Нет доступных датчиков"
5. Процесс генерации:
- "Размер файла: X / 1024000 байт"
- "Maximum Entropy Maked"
6. Ошибки:
- "Ошибка создания файла"
- "Ошибка сенсора: [описание]"
- "Не удалось получить доступ к хранилищу"
9. ОСНОВНЫЕ МЕТОДЫ MainActivity
9.1 Методы жизненного цикла:
java
onCreate() - Инициализация UI, запрос разрешений
onDestroy() - Освобождение ресурсов, отписка от сенсоров
onRequestPermissionsResult() - Обработка результата запроса разрешений
onActivityResult() - Обработка результата системного запроса (MANAGE_EXTERNAL_STORAGE)
9.2 Методы разрешений:
java
checkPermissions() - Определение необходимых разрешений
requestManageExternalStorage() - Запрос MANAGE_EXTERNAL_STORAGE (API 30+)
setupApp() - Инициализация после получения разрешений
9.3 Методы файловой системы:
java
isStorageAvailable() - Проверка доступности хранилища
setupFile() - Создание/открытие файла czechentropy.mp4
loadLastDigit() - Загрузка последней цифры из файла
startFileCheck() - Запуск периодической проверки размера файла
stopEverything() - Корректное завершение работы с файлом
9.4 Методы работы с сенсорами:
java
setupSensor() - Инициализация акселерометра/гироскопа
SensorEventListener - Обработчик данных с сенсора (внутренний класс)
9.5 Методы пользовательского интерфейса:
java
showErrorToUser() - Отображение ошибок пользователю
updateFileSize() - Обновление отображения размера файла
exitApp() - Корректный выход из приложения
10. ТРЕБОВАНИЯ К КОДУ
10.1 Структура кода:
1. Импорты (сгруппированы по типам)
2. Константы и статические переменные
3. Переменные экземпляра
4. Методы жизненного цикла Activity
5. Методы разрешений
6. Методы инициализации
7. Методы работы с файлами
8. Методы работы с сенсорами
9. Методы UI и обработки ошибок
10. Вспомогательные методы
10.2 Правила именования:
- Константы: UPPER_SNAKE_CASE
- Переменные: camelCase
- Методы: camelCase()
- Классы: PascalCase
- Теги логирования: "ClassName"
10.3 Обработка null и исключений:
- Все внешние объекты проверяются на null
- Критические операции в try-catch
- Ресурсы освобождаются в finally или onDestroy
Итоговый запрос для генерации кода:
Сгенерируйте полный Java-код для MainActivity.java, activity_main.xml и AndroidManifest.xml на основе приведенных выше спецификаций.
Требования:
1. Код должен быть максимально простым и понятным
2. Все переменные должны быть явно типизированы
3. Обязательно включить все описанные проверки и обработку ошибок
4. Реализовать логирование как описано в разделе 5
5. Добавить проверку цифр как в разделе 6
6. Реализовать обработку ошибок как в разделе 7
7. Включить пользовательские сообщения как в разделе 8
8. Соблюдать структуру методов как в разделе 9
9. Следовать требованиям к коду из раздела 10
Особое внимание уделить:
- Корректной работе с разрешениями на Android 14
- Стабильной работе сенсоров
- Надежной обработке файловых операций
- Понятным сообщениям для пользователя
- Полному логированию для отладки
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(c) by Valery Shmelev
https://oflameron.ru/Valery_Shmelev_5eng.pdf
AI-powered Code Generation
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Листинг проекта
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MainActivity.java
package com.example.largeentropy;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "LargeEntropy";
private static final int FSize = 1024000;
private SensorManager sensorManager;
private Sensor sensor;
private TextView tvStatus;
private Button btnExit;
private File dataFile;
private FileOutputStream fos;
private char LeastSignificantDigit = '0';
private char LeastSignificantDigit2 = '0';
private boolean isRunning = true;
private Handler handler = new Handler();
private Runnable fileCheckRunnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "Приложение запущено");
tvStatus = findViewById(R.id.tvStatus);
btnExit = findViewById(R.id.btnExit);
tvStatus.setText("Проверка разрешений...");
btnExit.setOnClickListener(v -> {
Log.d(TAG, "Нажата кнопка Exit");
stopEverything();
finish();
System.exit(0);
});
// Проверяем и запрашиваем разрешения
checkPermissions();
}
private void checkPermissions() {
// Для Android 11+ используем MANAGE_EXTERNAL_STORAGE
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
Log.d(TAG, "MANAGE_EXTERNAL_STORAGE уже есть");
setupApp();
} else {
requestManageExternalStorage();
}
} else {
// Для старых версий
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
setupApp();
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
100);
}
}
}
private void requestManageExternalStorage() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Доступ к хранилищу");
builder.setMessage("Приложению нужен доступ к хранилищу для работы с файлом czechentropy.mp4");
builder.setPositiveButton("Разрешить", (dialog, which) -> {
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(android.net.Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 101);
} catch (Exception e) {
Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, 101);
}
});
builder.setNegativeButton("Отмена", (dialog, which) -> {
tvStatus.setText("Доступ отклонен. Приложение закроется.");
Toast.makeText(this, "Доступ отклонен", Toast.LENGTH_LONG).show();
finish();
});
builder.setCancelable(false);
builder.show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 101) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
setupApp();
} else {
tvStatus.setText("Доступ не предоставлен");
Toast.makeText(this, "Доступ к хранилищу не предоставлен", Toast.LENGTH_LONG).show();
}
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100 && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setupApp();
} else {
tvStatus.setText("Разрешение отклонено");
Toast.makeText(this, "Разрешение отклонено", Toast.LENGTH_LONG).show();
}
}
private void setupApp() {
Log.d(TAG, "Настройка приложения");
// Проверка хранилища
String storageState = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(storageState)) {
tvStatus.setText("Хранилище недоступно: " + storageState);
Toast.makeText(this, "Хранилище недоступно", Toast.LENGTH_LONG).show();
return;
}
// Настройка файла
if (!setupFile()) {
return;
}
// Настройка сенсора
setupSensor();
// Запуск проверки файла
startFileCheck();
}
private boolean setupFile() {
try {
File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
Log.d(TAG, "Папка Download: " + downloadDir.getAbsolutePath());
if (!downloadDir.exists()) {
if (!downloadDir.mkdirs()) {
tvStatus.setText("Ошибка: не могу создать папку Download");
return false;
}
}
dataFile = new File(downloadDir, "czechentropy.mp4");
Log.d(TAG, "Файл: " + dataFile.getAbsolutePath());
if (dataFile.exists()) {
long fileSize = dataFile.length();
Log.d(TAG, "Файл существует, размер: " + fileSize + " байт");
tvStatus.setText("Файл найден. Размер: " + fileSize + " байт");
if (fileSize >= FSize) {
tvStatus.setText("Maximum Entropy Maked");
isRunning = false;
return true;
} else {
fos = new FileOutputStream(dataFile, true);
}
} else {
if (dataFile.createNewFile()) {
Log.d(TAG, "Файл создан");
fos = new FileOutputStream(dataFile, true);
tvStatus.setText("Файл создан");
} else {
tvStatus.setText("Ошибка создания файла");
return false;
}
}
// Загружаем последнюю цифру
loadLastDigit();
return true;
} catch (Exception e) {
Log.e(TAG, "Ошибка настройки файла", e);
tvStatus.setText("Ошибка файла: " + e.getMessage());
return false;
}
}
private void loadLastDigit() {
try {
if (dataFile.exists() && dataFile.length() > 0) {
FileInputStream fis = new FileInputStream(dataFile);
fis.skip(dataFile.length() - 1);
int lastByte = fis.read();
fis.close();
if (lastByte != -1) {
LeastSignificantDigit = (char) lastByte;
Log.d(TAG, "Загружена последняя цифра: " + LeastSignificantDigit);
}
}
} catch (Exception e) {
Log.e(TAG, "Ошибка загрузки последней цифры", e);
}
}
private void setupSensor() {
try {
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
// Сначала пробуем акселерометр
Sensor accelSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (accelSensor != null) {
sensor = accelSensor;
sensorManager.registerListener(sensorListener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
Log.d(TAG, "Акселерометр подключен");
tvStatus.append("\nАкселерометр подключен");
return;
}
// Если нет акселерометра, пробуем гироскоп
Sensor gyroSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
if (gyroSensor != null) {
sensor = gyroSensor;
sensorManager.registerListener(sensorListener, gyroSensor, SensorManager.SENSOR_DELAY_NORMAL);
Log.d(TAG, "Гироскоп подключен");
tvStatus.append("\nГироскоп подключен");
return;
}
tvStatus.append("\nНет доступных датчиков");
Log.e(TAG, "Нет доступных датчиков");
} catch (Exception e) {
Log.e(TAG, "Ошибка настройки сенсора", e);
tvStatus.append("\nОшибка сенсора: " + e.getMessage());
}
}
private SensorEventListener sensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (!isRunning || fos == null) return;
try {
// Берем только значение по оси X (первый элемент массива)
float xValue = event.values[0];
// Преобразуем float в строку, убираем точку и минус
String valueStr = Float.toString(xValue);
valueStr = valueStr.replace(".", "").replace("-", "");
// Убираем ведущие нули
if (valueStr.length() > 1) {
while (valueStr.startsWith("0") && valueStr.length() > 1) {
valueStr = valueStr.substring(1);
}
}
// Если строка пустая, пропускаем
if (valueStr.isEmpty()) return;
// Преобразуем в BigInteger
BigInteger bigInt = new BigInteger(valueStr);
String bigIntStr = bigInt.toString();
// Берем последнюю цифру
if (!bigIntStr.isEmpty()) {
LeastSignificantDigit2 = bigIntStr.charAt(bigIntStr.length() - 1);
// Логируем
Log.e(TAG, "=== Least Significant Digit ===" + LeastSignificantDigit2);
// Проверяем, что это цифра
if (LeastSignificantDigit2 >= '0' && LeastSignificantDigit2 <= '9') {
// Если цифра изменилась - записываем в файл
if (LeastSignificantDigit != LeastSignificantDigit2) {
try {
fos.write(LeastSignificantDigit);
fos.flush();
Log.d(TAG, "Записана цифра: " + LeastSignificantDigit);
LeastSignificantDigit = LeastSignificantDigit2;
} catch (IOException e) {
Log.e(TAG, "Ошибка записи в файл", e);
}
}
}
}
} catch (Exception e) {
Log.e(TAG, "Ошибка обработки сенсора", e);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Не используется
}
};
private void startFileCheck() {
fileCheckRunnable = new Runnable() {
@Override
public void run() {
if (!isRunning) return;
try {
if (dataFile != null && dataFile.exists()) {
long fileSize = dataFile.length();
runOnUiThread(() -> {
tvStatus.setText("Размер файла: " + fileSize + " / " + FSize + " байт");
});
if (fileSize >= FSize) {
runOnUiThread(() -> {
tvStatus.setText("Maximum Entropy Maked");
});
stopEverything();
}
}
} catch (Exception e) {
Log.e(TAG, "Ошибка проверки файла", e);
}
// Повторяем каждую секунду
if (isRunning) {
handler.postDelayed(this, 1000);
}
}
};
handler.post(fileCheckRunnable);
}
private void stopEverything() {
Log.d(TAG, "Остановка всего");
isRunning = false;
// Останавливаем проверку файла
if (handler != null && fileCheckRunnable != null) {
handler.removeCallbacks(fileCheckRunnable);
}
// Отключаем сенсор
if (sensorManager != null && sensorListener != null) {
sensorManager.unregisterListener(sensorListener);
}
// Закрываем файл
if (fos != null) {
try {
fos.close();
Log.d(TAG, "Файл закрыт");
} catch (IOException e) {
Log.e(TAG, "Ошибка закрытия файла", e);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
stopEverything();
}
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Activity_main.xml
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
AndroidManifest.xml
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
build.gradle (Module :app)
plugins {
id 'com.android.application'
}
android {
namespace 'com.example.largeentropy'
compileSdk 33
defaultConfig {
applicationId "com.example.largeentropy"
minSdk 30
targetSdk 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0'
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
December 2025
(c) by Valery Shmelev
https://t.me/s/llmsource/
Direct Link: https://chat.deepseek.com/share/rnwf36crlakewgtm6j