bridge

webtunnel [2001:db8:945c:e0b9:7e4c:c974:ff00:d4c5]:443 91937F3EFB3BE5169788AC7C8BF07460B7E306DB url=https://kabel.entreri.de/YXbp1dNrJeOF8giAFFYWxvmf ver=0.0.4
webtunnel [2001:db8:11d3:d5e7:2939:8453:7baf:868f]:443 531640559965FB7501EB5C006018F61D1E9FA1BB url=https://cdn-34.triplebit.dev/Aec3euCh4ux3deij ver=0.0.2

Hackintosh AMD

 

@@@vmware 

hw.model = "MacBookPro16,4"
board-id = "Mac-A61BADE1FDAD7B05"
smc.version = "0"
cpuid.0.eax = "0000:0000:0000:0000:0000:0000:0000:1011"
cpuid.0.ebx = "0111:0101:0110:1110:0110:0101:0100:0111"
cpuid.0.ecx = "0110:1100:0110:0101:0111:0100:0110:1110"
cpuid.0.edx = "0100:1001:0110:0101:0110:1110:0110:1001"
cpuid.1.eax = "0000:0000:0000:0001:0000:0110:0111:0001"
cpuid.1.ebx = "0000:0010:0000:0001:0000:1000:0000:0000"
cpuid.1.ecx = "1000:0010:1001:1000:0010:0010:0000:0011"
cpuid.1.edx = "0000:0111:1000:1011:1111:1011:1111:1111"

Although i’d advise changing the first two lines to;

hw.model = "iMac20,2"
board-id = "Mac-AF89B6D9451A490B"

 

 

 

@@@@virtualbox

TechWise Youtube Channel 

************ To Disable Hyper-V ************

bcdedit /set hypervisorlaunchtype off



************ To Increase Display Resolution & Memory ************

cd "C:\Program Files\Oracle\VirtualBox\"

VBoxManage setextradata “VM Name” VBoxInternal2/EfiGraphicsResolution 1920x1080


Choose a Resolution:
  1280x720 | 1920x1080 | 2560x1440 | 2048x1080 | 3840x2160
    HD         FHD          QHD         2K          4K



************ To Patch Virtual Machine ************

**** For AMD Processor ***

cd "C:\Program Files\Oracle\VirtualBox\"

VBoxManage.exe modifyvm "VM Name" --cpuidset 00000001 000106e5 00100800 0098e3fd bfebfbff

VBoxManage setextradata "VM Name" "VBoxInternal/Devices/efi/0/Config/DmiSystemProduct" "iMac19,3"

VBoxManage setextradata "VM Name" "VBoxInternal/Devices/efi/0/Config/DmiSystemVersion" "1.0"

VBoxManage setextradata "VM Name" "VBoxInternal/Devices/efi/0/Config/DmiBoardProduct" "Iloveapple"

VBoxManage setextradata "VM Name" "VBoxInternal/Devices/smc/0/Config/DeviceKey" "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc"

VBoxManage setextradata "VM Name" "VBoxInternal/Devices/smc/0/Config/GetKeyFromRealSMC" 0

VBoxManage modifyvm "VM Name" --cpu-profile "Intel Core i7-6700K"

VBoxManage setextradata "VM Name" "VBoxInternal/TM/TSCMode" "RealTSCOffset"


*** For Intel Processor ***

cd "C:\Program Files\Oracle\VirtualBox\"

VBoxManage.exe modifyvm "VM Name" --cpuidset 00000001 000106e5 00100800 0098e3fd bfebfbff

VBoxManage setextradata "VM Name" "VBoxInternal/Devices/efi/0/Config/DmiSystemProduct" "iMac19,3"

VBoxManage setextradata "VM Name" "VBoxInternal/Devices/efi/0/Config/DmiSystemVersion" "1.0"

VBoxManage setextradata "VM Name" "VBoxInternal/Devices/efi/0/Config/DmiBoardProduct" "Iloveapple"

VBoxManage setextradata "VM Name" "VBoxInternal/Devices/smc/0/Config/DeviceKey" "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc"

VBoxManage setextradata "VM Name" "VBoxInternal/Devices/smc/0/Config/GetKeyFromRealSMC" 0

VBoxManage setextradata "VM Name" "VBoxInternal/TM/TSCMode" "RealTSCOffset"

 

LazyVerticalGrid restore focus

 


const val GRID_COLUMN_COUNT = 4


@OptIn(ExperimentalTvMaterial3Api::class, ExperimentalComposeUiApi::class)
@Composable
fun MoviesScreenTv(
viewModel: MoviesViewModel = koinViewModel(),
onMovieClick: (MovieItem) -> Unit,
onFocusBackToTab: FocusRequester? = null,
//contentEntryRequester: FocusRequester,
homeLeft: FocusRequester?,
homeRight: FocusRequester? = null

//onShowFilters: () -> Unit
) {
val uiState by viewModel.uiState.collectAsState()
val gridState = rememberLazyGridState()
val scope = rememberCoroutineScope()

val shouldLoadMore = remember {
derivedStateOf {
if (uiState.movies.size < 4) {
false
} else {
val lastVisibleItem = gridState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0
val totalItems = uiState.movies.size
lastVisibleItem >= totalItems - 4
}
}
}

LaunchedEffect(shouldLoadMore.value) {
val canLoad = uiState.canLoadMore && !uiState.isLoading && !uiState.isLoadingMore
if (shouldLoadMore.value && canLoad) {
viewModel.loadMoreMovies()
}
}

//ALL CONTAINER FOCUS HANDLE
// 1. Создаем FocusRequester'ы
val parentFocusRequester = remember { FocusRequester() }
val childFocusRequester = remember { FocusRequester() }

// 2. Модификатор для родительского контейнера
val parentModifier = Modifier
.focusRequester(parentFocusRequester)
.focusProperties {
onExit = {
parentFocusRequester.saveFocusedChild() // Сохраняем текущий фокус при выходе
FocusRequester.Default
}
enter = {
if (parentFocusRequester.restoreFocusedChild()) {
FocusRequester.Cancel // Если восстановили фокус - отменяем стандартное поведение
} else {
childFocusRequester // Иначе фокусируемся на дочернем элементе
}
}
}

// 3. Модификатор для дочернего элемента
val childModifier = Modifier.focusRequester(childFocusRequester)

val x2 = FocusRequesterModifiers(parentModifier, childModifier)
//ALL CONTAINER FOCUS HANDLE



Column(modifier = x2.parentModifier.fillMaxSize().focusGroup()/*FOCUS_GROUP*/) {
if (uiState.isLoading && uiState.movies.isEmpty()) {
LoadingViewTv(modifier = Modifier.fillMaxSize())
} else if (uiState.error != null && uiState.movies.isEmpty()) {

val backToUpOrHomeModifier = Modifier.focusProperties {
onFocusBackToTab?.let { up = it }
homeLeft?.let { left = it }
}

ErrorViewTv(
modifier = backToUpOrHomeModifier,
message = uiState.error ?: "",
onRetry = {
viewModel.refreshMovies()
})
} else {


var lastFocusedIndex by remember { mutableStateOf<Int?>(0) }

LazyVerticalGrid(
columns = GridCells.Fixed(GRID_COLUMN_COUNT),
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxSize().focusGroup(),//@@@@
content = {
itemsIndexed(uiState.movies) { index, movie ->

val modifier = Modifier.focusEdges(
index = index,
gridColumnCount = GRID_COLUMN_COUNT,
homeLeft = homeLeft,
homeRight = homeRight,
scope = scope,
onFocusBackToTab = onFocusBackToTab
)

AnimatedVisibility(
visible = true,
enter = fadeIn(
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
),
exit = fadeOut()
) {


MovieCardTv(
modifier = modifier.then(if (index == lastFocusedIndex) x2.childModifier else Modifier)
.onFocusChanged { state ->
if (state.isFocused) {
lastFocusedIndex = index
}
},
movie = movie,
onClick = { onMovieClick(movie) }
)


// LaunchedEffect(lastFocusedIndex) {
// if (lastFocusedIndex == index) {
// itemFocusRequester.requestFocus()
// }
// }
}
}

if (uiState.isLoadingMore) {
item(span = { GridItemSpan(maxLineSpan) }) {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
contentAlignment = Alignment.Center
) {
LoadingViewTv(
style = MaterialTheme.typography.bodyLarge
)
}
}
}
},
state = gridState
)

LaunchedEffect(Unit) {
parentFocusRequester.requestFocus(scope = scope)
}
}
}
}

fun Modifier.focusEdges(
index: Int,
gridColumnCount: Int,
homeLeft: FocusRequester? = null,
homeRight: FocusRequester? = null,
scope: CoroutineScope,
onFocusBackToTab: FocusRequester? = null
): Modifier {
var m = this

if (onFocusBackToTab != null && index < gridColumnCount) {
m = m.focusProperties { up = onFocusBackToTab }
}

m = m.onKeyEvent { keyEvent ->
if (keyEvent.type != KeyEventType.KeyDown) return@onKeyEvent false

when (keyEvent.key) {
Key.DirectionLeft -> {
if (index % gridColumnCount == 0 && homeLeft != null) {
homeLeft.requestFocus(scope = scope)
true
} else false
}

Key.DirectionRight -> {
if ((index + 1) % gridColumnCount == 0 && homeRight != null) {
homeRight.requestFocus(scope = scope)
true
} else false
}

else -> false
}
}

return m
}

//@Composable
//fun <T>CG0(
// state: LazyGridState,
// items: List<T>,
// content: LazyGridScope.() -> Unit
//) {
// LazyVerticalGrid(
// columns = GridCells.Fixed(GRID_COLUMN_COUNT),
// contentPadding = PaddingValues(16.dp),
// verticalArrangement = Arrangement.spacedBy(16.dp),
// horizontalArrangement = Arrangement.spacedBy(16.dp),
// modifier = Modifier.fillMaxSize(),
// state = state,
// content = content
// )
//}
@Composable
fun CinemaLazyVerticalGrid(
state: LazyGridState,
content: LazyGridScope.() -> Unit
) {
LazyVerticalGrid(
columns = GridCells.Fixed(GRID_COLUMN_COUNT),
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxSize(),
state = state,
content = content
)
}
//@Composable
//fun TvAdaptiveGrid(
// items: List<Any>,
// state: LazyGridState,
// content: @Composable (item: Any, index: Int) -> Unit,
// home: FocusRequester? = null,
//) {
// CG0(state = state) {
// itemsIndexed(items) { index, item ->
// content(item, index)
// }
// }
//}

/**
* Стандартная адаптивная сетка для TV
*/
@Composable
fun TvAdaptiveGridDefault(
items: List<Any>,
modifier: Modifier = Modifier,
contentPadding: PaddingValues = tvScreenPadding,
horizontalArrangement: androidx.compose.foundation.layout.Arrangement.Horizontal = androidx.compose.foundation.layout.Arrangement.spacedBy(
tvCardSpacing
),
verticalArrangement: androidx.compose.foundation.layout.Arrangement.Vertical = androidx.compose.foundation.layout.Arrangement.spacedBy(
tvCardSpacing
),
content: @Composable (item: Any, index: Int) -> Unit
) {
LazyVerticalGrid(
columns = GridCells.Adaptive(minSize = TvSizes.GRID_MIN_SIZE.dp),
contentPadding = contentPadding,
horizontalArrangement = horizontalArrangement,
verticalArrangement = verticalArrangement,
modifier = modifier
) {
itemsIndexed(items) { index, item ->
content(item, index)
}
}
}

Run this build using a Java 11 or newer JVM

 
FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring root project 'PillIdentifier'.
> Could not resolve all artifacts for configuration ':classpath'.
   > Could not resolve com.android.tools.build:gradle:8.8.2.
     Required by:
         root project : > com.android.application:com.android.application.gradle.plugin:8.8.2
         root project : > com.android.library:com.android.library.gradle.plugin:8.8.2
      > Dependency requires at least JVM runtime version 11. This build uses a Java 8 JVM.
   > Could not resolve com.google.gms:google-services:4.4.2.
     Required by:
         root project : > com.google.gms.google-services:com.google.gms.google-services.gradle.plugin:4.4.2
      > Dependency requires at least JVM runtime version 11. This build uses a Java 8 JVM.
   > Could not resolve com.google.firebase:firebase-crashlytics-gradle:3.0.3.
     Required by:
         root project : > com.google.firebase.crashlytics:com.google.firebase.crashlytics.gradle.plugin:3.0.3
      > Dependency requires at least JVM runtime version 17. This build uses a Java 8 JVM.

* Try:
> Run this build using a Java 11 or newer JVM.
> Run this build using a Java 17 or newer JVM.
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

Ошибка возникает из-за того, что ваша сборка использует Java 8, а для работы с Gradle 8.8.2, Google Services 4.4.2 и Firebase Crashlytics 3.0.3 требуется Java 11+ (а для Crashlytics — даже Java 17)
>gradlew --version        

------------------------------------------------------------
Gradle 8.10.2
------------------------------------------------------------

Build time:    2024-09-23 21:28:39 UTC
Revision:      415adb9e06a516c44b391edff552fd42139443f7

Kotlin:        1.9.24
Groovy:        3.0.22
Ant:           Apache Ant(TM) version 1.10.14 compiled on August 16 2023
Launcher JVM:  1.8.0_431 (Oracle Corporation 25.431-b10)
Daemon JVM:    C:\Program Files\Java\jdk-1.8 (no JDK specified, using current Java home) @@@@@@@@@@@@@ JAVA_HOME path
OS:            Windows 10 10.0 amd64



taskkill /F /IM java.exe

 

 

Modify  JAVA_HOME path
Or set gradle.properties

org.gradle.java.home=C:\\Program Files\\Java\\jdk-17.0.11

Моделирование состояния ViewModel в Android: Руководство по чистым и масштабируемым паттернам

 


Плохо спроектированные модели создают каскад проблем для каждого компонента, который от них зависит. В случае моделей представления, если они не соответствуют реальным потребностям экрана, другие компоненты (например, ViewModel) вынуждены обходить эти ограничения, что приводит к раздутым, трудным в сопровождении классам, заполненным хаками и обходными путями. Это несоответствие вносит неясность и путаницу, делая код неочевидным и подверженным ошибкам, что увеличивает затраты на его поддержку.

Рассмотрим два популярных способа моделирования состояния ViewModel:

//🎯 Подход 1
data class ScreenState(
    val isLoading: Boolean,
    val isError: Boolean,
    val data: Data?
)

//🎯 Подход 2
sealed interface ScreenState {
    data object Loading : ScreenState
    data object Error : ScreenState
    data class Content(val data: Data) : ScreenState
}

Оба подхода имеют значительные ограничения и часто требуют множества обходных решений. Давайте разберём их плюсы и минусы, а затем рассмотрим третий, более простой и универсальный вариант.

Подход 1: Простые дата-классы

data class ProductListScreenState(
    val isLoading: Boolean,
    val isError: Boolean,
    val productResults: ProductResults?
)

data class ProductResults(
    val products: List<Product>, 
    val canLoadMore: Boolean
)

Представьте страницу со списком товаров, где данные загружаются из удалённого источника. Во время загрузки отображается спиннер, в случае ошибки показывается экран ошибки с возможностью повторной попытки. Это стандартный сценарий «Загрузка-Контент-Ошибка».

Минусы этого подхода:

  • Модель допускает противоречивые состояния: например, isLoading и isError могут быть true одновременно, что приведёт к отображению двух экранов сразу.
  • Если добавить дополнительные состояния (например, isRefreshing или isPaginating), можно получить 2⁴ возможных комбинаций булевых значений, тогда как реально экран поддерживает только 5 состояний.
  • Каждый раз, когда мы обновляем состояние, приходится сбрасывать все остальные флаги, создавая лишний код.
  • Разработчики, работающие с UI, могут запутаться, какие состояния действительно возможны, и будут вынуждены заглядывать в код ViewModel для уточнения.

Улучшение через enum

data class ProductListScreenState(
    val displayState: DisplayState,
    val productResults: ProductResults?
)

enum class DisplayState {
    LOADING, CONTENT, ERROR
}

Этот подход значительно улучшает ситуацию, но всё ещё имеет недостатки. Например, CONTENT подразумевает, что productResults не должен быть null, но это никак не контролируется.

Подход 2: sealed interface

sealed interface ProductListScreenState {
    data object Loading : ProductListScreenState
    data object Error : ProductListScreenState
    data class Content(val productResults: ProductResults) : ProductListScreenState
}

Этот вариант решает проблему противоречивых состояний, так как каждое состояние явно представлено. Однако он затрудняет совместное использование данных между состояниями.

Проблема: если нам нужно отображать приветственное сообщение с именем пользователя, нам придётся хранить это значение отдельно и вручную синхронизировать его со всеми состояниями.

sealed interface ProductListScreenState {
    val fullName: String
    data class Loading(override val fullName: String) : ProductListScreenState
    data class Error(override val fullName: String) : ProductListScreenState
    data class Content(override val fullName: String, val productResults: ProductResults) : ProductListScreenState
}

Такой код становится громоздким и сложным в обслуживании.

Финальный подход: Объединение data class и sealed interface

Используем дата-класс для данных, присутствующих во всех состояниях, и sealed interface для состояний, которые взаимоисключаемы.

data class ProductListScreenState(
    val fullName: String,
    val displayState: DisplayState
)

sealed interface DisplayState {
    data object Loading : DisplayState
    data object Error : DisplayState
    data class Content(val productResults: ProductResults) : DisplayState
}

Масштабируемость модели

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

  • Перезагрузки данных при повороте экрана.
  • Pull-to-refresh с индикатором загрузки вверху.
  • Пагинации с индикатором загрузки внизу.

Обновленная модель состояния:

data class ProductListScreenState(
    val fullName: String,
    val displayState: DisplayState? = null
)

sealed interface DisplayState {
    data object Loading : DisplayState
    data object Error : DisplayState
    data class Content(
        val productResults: ProductResults,
        val contentDisplayState: ContentDisplayState? = null
    ) : DisplayState
}

sealed interface ContentDisplayState {
    data object Refreshing : ContentDisplayState
    data object Paginating : ContentDisplayState
    data object PaginationError : ContentDisplayState
}

Теперь состояния чётко структурированы и масштабируемы, а код ViewModel остаётся простым и лаконичным.

Вывод:

Этот гибридный подход объединяет лучшие качества data class и sealed interface, обеспечивая чистоту, масштабируемость и удобочитаемость кода. 🎯

B-USB

Volume: F:
Controller: Silicon Motion SM3257 ENAA   {CHIPSET 3257ENAA}
Possible Memory Chip(s):
  Samsung K9ACGD8U0Ax2 *2
Memory Type: TLC
Flash ID: ECDE98CE 74C4
Flash CE: 4
Flash Channels: Single
Chip F/W: ISP 140704-AA-
MP: N0708V1
MPTOOL Ver.: 2.05.36
VID: 090C
PID: 1000

Manufacturer: SMI Corporation
Product: USB DISK
Query Vendor ID: SMI     
Query Product ID: USB DISK        
Query Product Revision: 1100
Physical Disk Capacity: 32463912960 Bytes
Windows Disk Capacity:  32462860288 Bytes
Internal Tags: QT2R-TZ2L
File System: NTFS
Relative Offset: 1024 KB
USB Version: 2.00
Declared Power: 300 mA
ContMeas ID: 1DA7-04-FF
Microsoft Windows 10 x64 Build 19045
------------------------------------
http://www.antspec.com/usbflashinfo/
Program Version: 9.4.0.645

psw: 320

DependencyMerger.kt toml

 

import java.io.File
import com.akuleshov7.ktoml.Toml
import com.akuleshov7.ktoml.TomlInputConfig
import kotlinx.serialization.Serializable

@Serializable
data class TomlConfig(
val versions: Map<String, String> = emptyMap(),
val libraries: Map<String, Map<String, Map<String, Map<String, Long>>>> = emptyMap(), // Изменено для поддержки вложенных таблиц
val plugins: Map<String, Map<String, Map<String, Map<String, Long>>>> = emptyMap()
)


fun main(args: Array<String>) {
try {
val sourceFile =
if (args.isNotEmpty()) File(args[0]) else File("C:\\Users\\combo\\Desktop\\Новая папка\\1.toml")
val targetFile = if (args.size > 1) File(args[1]) else File("C:\\Users\\combo\\Desktop\\Новая папка\\2.toml")
val targetFile1 = if (args.size > 1) File(args[1]) else File("C:\\Users\\combo\\Desktop\\Новая папка\\3.toml")

println("🔍 Исходный файл: ${sourceFile.absolutePath}")
println("📝 Целевой файл: ${targetFile.absolutePath}")

// Проверяем наличие файлов
if (!sourceFile.exists()) throw IllegalArgumentException("Исходный файл не найден")
if (!targetFile.exists()) throw IllegalArgumentException("Целевой файл не найден")

// Проверяем права доступа
if (!sourceFile.canRead()) throw SecurityException("Нет прав на чтение исходного файла")
if (!targetFile.canWrite()) throw SecurityException("Нет прав на запись в целевой файл")

// Создаем экземпляр Toml с конфигурацией
val toml = Toml(TomlInputConfig(ignoreUnknownNames = true))

// Читаем TOML файлы
val sourceToml = try {
toml.decodeFromString(
TomlConfig.serializer(),
sourceFile.readText()
)
} catch (e: Exception) {
throw IllegalStateException("Ошибка при чтении исходного TOML: ${e.message}")
}

val targetToml = try {
toml.decodeFromString(
TomlConfig.serializer(),
targetFile.readText()
)
} catch (e: Exception) {
throw IllegalStateException("Ошибка при чтении целевого TOML: ${e.message}")
}

// Получаем секции с версиями, библиотеками и плагинами
val sourceDeps = sourceToml.versions
val targetDeps = targetToml.versions.toMutableMap()

// Добавляем недостающие зависимости и обновляем существующие
var changed = false
var addedCount = 0
sourceDeps.forEach { (key, value) ->
if (key !in targetDeps) {
targetDeps[key] = value
println("✅ Добавлена версия: $key = $value")
changed = true
addedCount++
} else {
// Если зависимость уже существует, обновляем её версию
if (targetDeps[key] != value) {
println("🔄 Обновлена версия: $key = $value")
targetDeps[key] = value
changed = true
}
}
}

// Сохраняем обновленный TOML
if (changed) {
try {
val tomlContent = buildString {
appendLine("[versions]")
targetDeps.forEach { (key, value) ->
appendLine("$key = \"$value\"")
}
// Добавляем секции libraries и plugins
appendLine("[libraries]")
sourceToml.libraries.forEach { (libName, libConfig) ->
append("$libName = {")
val entries = libConfig.entries.toList()
entries.forEachIndexed { index, entry ->
if (entry.value is LinkedHashMap) {
var o = entry.key

entry.value.entries.forEachIndexed { innerIndex, innerEntry ->
o += "." + innerEntry.key
append(" $o = \"${innerEntry.value}\"${if ((innerIndex < entry.value.entries.size - 1)&&index < entries.size - 1) "," else ","}")
}
} else {
append(" ${entry.key} = \"${entry.value}\"${if (index < entries.size - 1) "," else ""}")
}
}
append("}\n")
}
appendLine("[plugins]")
sourceToml.plugins.forEach { (libName, libConfig) ->
append("$libName = {")
val entries = libConfig.entries.toList()
entries.forEachIndexed { index, entry ->
if (entry.value is LinkedHashMap) {
var o = entry.key

entry.value.entries.forEachIndexed { innerIndex, innerEntry ->
o += "." + innerEntry.key
append(" $o = \"${innerEntry.value}\"${if ((innerIndex < entry.value.entries.size - 1)&&index < entries.size - 1) "," else ","}")
}
} else {
append(" ${entry.key} = \"${entry.value}\"${if (index < entries.size - 1) "," else ""}")
}
}
append("}\n")
}
}
targetFile1.writeText(tomlContent)
println("🎉 Файл успешно обновлен! Добавлено версий: $addedCount")
} catch (e: Exception) {
throw IllegalStateException("Ошибка при сохранении TOML: ${e.message}")
}
} else {
println("ℹ️ Новых версий не найдено")
}
} catch (e: Exception) {
println("❌ Ошибка: ${e.message}")
System.exit(1)
}
}

 
gradlew build --warning-mode all --info
gradlew clean build --stacktrace



gradlew build
gradlew build -Xlint:deprecation
gradlew assembleRelease
gradlew build --warning-mode all
./gradlew debugBuild --scan


banner_ad_unit_id

build.gradle (project-level)

    Add Firebase Gradle buildscript dependency
        classpath 'com.google.gms:google-services:3.2.1'


 
app/build.gradle

    Add Firebase plugin for Gradle
        apply plugin: 'com.google.gms.google-services'



======================================================================

apply plugin: 'com.android.application'

android {

    lintOptions{
        disable 'MissingTranslation'
    }

    signingConfigs {
//        config {
//            keyAlias 'isaidit'
//            keyPassword 'isaidit'
//            storeFile file('../keystore/1016_isaidit.key')
//            storePassword 'isaidit'
//        }



        config {
            keyAlias 'origami'
            keyPassword '@!sfuQ123zpc'
            storeFile file('D:/walhalla/keystore.jks')
            storePassword '@!sfuQ123zpc'
        }
    }


    compileSdkVersion 27
    buildToolsVersion '28.0.2'

    defaultConfig {
        applicationId "com.walhalla.pocketinstructor"

        minSdkVersion 16
        targetSdkVersion 27

        versionCode 1
        versionName versionCode + "-" + getTimestamp()
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        vectorDrawables.useSupportLibrary = true
        // Enabling multidex support.
        multiDexEnabled false
    }
    buildTypes {

        debug {
            multiDexEnabled false
            debuggable true
            jniDebuggable true
            minifyEnabled false
        }

        release {
            minifyEnabled true
            //proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            //best obfuscation -> -optimize
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

            debuggable false
            jniDebuggable false
            signingConfig signingConfigs.config
            renderscriptDebuggable false
            pseudoLocalesEnabled true
//            applicationIdSuffix '.a'
            versionNameSuffix 'b'
//            zipAlignEnabled true
//             Enabling multidex support.
            multiDexEnabled false
        }
    }


    flavorDimensions 'W'

    productFlavors {

        googleplay {
            //versionName = "gp"
            project.ext.set("archivesBaseName", "gp-" + defaultConfig.versionName);
            flavorDimensions 'W'
            resValue 'string', 'market_rate_url', 'market://details?id=%1$s'
        }
        amazon {
            //versionName = "a"
            project.ext.set("archivesBaseName", "a-" + defaultConfig.versionName);
            flavorDimensions 'W'
            resValue 'string', 'market_rate_url', 'http://www.amazon.com/gp/mas/dl/android?p=%1$s'
        }
    }


    dexOptions {
        preDexLibraries = false
        //fail>javaMaxHeapSize "2g"
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

def FOO = '27.1.1'

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    implementation "com.android.support:appcompat-v7:$FOO"
    implementation "com.android.support:design:$FOO"
    implementation('uk.co.chrisjenx:calligraphy:2.2.0') {
        exclude group: 'com.android.support', module: 'support-v4'
    }
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    implementation 'com.jakewharton:butterknife:8.6.0'

//    implementation('com.google.android.gms:play-services-ads:15.0.1') {
//        exclude group: 'com.android.support'
//    }


    implementation("com.google.firebase:firebase-ads:15.0.1") {
        exclude group: 'com.android.support'
    }

    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.arello-mobile:moxy-app-compat:1.5.3'
    implementation 'com.arello-mobile:moxy:1.5.3'
    implementation 'com.github.bumptech.glide:glide:4.3.1'
    testImplementation 'junit:junit:4.12'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'
    annotationProcessor 'com.arello-mobile:moxy-compiler:1.5.3'
    implementation 'com.google.dagger:dagger:2.11'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
    implementation('com.github.piasy:BigImageViewer:1.4.0') {
        exclude group: 'com.android.support', module: 'support-v4'
    }
    // load with glide
    //    implementation 'com.github.piasy:GlideImageLoader:1.4.0'
    //
    //    // progress pie indicator
    //    implementation 'com.github.piasy:ProgressPieIndicator:1.4.0'
    //@    implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0';

    //Themes
    implementation 'com.52inc:scoops:1.0.0'
    implementation project(':ui')
    implementation project(':wads')
}

static def getTimestamp() {
    def date = new Date()
    return date.format('yyyyMMdd.HHmm')
}









//implementation files('../libs/game_lib.jar')



@@@@@@@@@@@@@ ROOM @@@@@@@@@@@@@
 implementation "android.arch.persistence.room:runtime:1.1.1"
 annotationProcessor "android.arch.persistence.room:compiler:1.1.1"




No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android



// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.0-rc03'
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

==============================================================================s






=============
FreeOpenVPN.Org config fil












MultiDex -> 65536


android{
    useLibrary 'org.apache.http.legacy'

sourceSets { main { assets.srcDirs = ['src/main/assets', 'src/main/assets/'] } }
}


@dependency{
compile 'com.android.volley:volley:1.1.0'
}

-encoding UTF-8 -docencoding utf-8 -charset utf-8



gradlew assembleDebug --stacktrace
gradlew assembleDebug --stacktrace

gradlew clean


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=

   implementation("com.google.firebase:firebase-ads:${GOO}") {
        exclude group: 'com.android.support'
    }

implementation ('com.google.android.gms:play-services-ads:15.0.1') {
        exclude group: 'com.android.support', module: 'support-v4'
    }

 compile(project(':react-native-maps')){
      exclude group: 'com.google.android.gms', module: 'play-services-base'
      exclude group: 'com.google.android.gms', module: 'play-services-maps'
   }

C:\Users\combo\.gradle\wrapper\dists
./gradlew wrapper --gradle-version=4.1 --distribution-type=bin

-Xmx768m


gradlew -info
gradlew -stacktrace

gradlew app:dependencies //<----------------------------------------------------------------
gradlew clean



gradlew -q dependencies app:dependencies --configuration implementation        #Просмотр
gradlew -q dependencies
 зависимостей
мастер оф паппетс
================================================================================================

gradlew htmlDependencyReport

gradlew app:dependencies @@@@@@@@@@@@@@@@@@@@@@@@@@
gradlew app:dependencies @@@@@@@@@@@@@@@@@@@@@@@@@@

gradlew -q dependencies Bitrix:dependencies --configuration implementation
gradlew Bitrix:dependencies > 1.txt
gradlew -q dependencies app:dependencies --configuration implementation  > 1.txt
gradlew :app:dependencies --configuration implementation  > 1.txt

gradlew task ':app:transformClassesWithDexForDebug' --stacktrace
gradlew app:transformClassesWithDexForRelease --stacktrace
gradlew task

gradlew --help task

gradlew --help task --all

gradlew task ':app:compile' -Xlint:deprecation


gradlew task ':app:compile' --stacktrace

gradlew task ':app:processDebugGoogleServices' --stacktrace




gradle wrapper
With gradle 2.4 (or higher) you can set up a wrapper without adding a dedicated task:

gradle wrapper --gradle-version 2.3

./gradlew assembleRelease



gradlew :app:assembleDebug --stacktrace -Xlint





===================================
BASE APP
===================================
    //di
    compile 'com.google.dagger:dagger:2.11'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.11'




=============================================================================
include ':FragmentNavigator'
project(':FragmentNavigator').projectDir = new File(settingsDir, '../../Libraries/FragmentNavigator/library')

include ':app'
include ':mcsoxford_rss'
project(':mcsoxford_rss').projectDir = new File('C:\\android\\ANDROID_TUTORIAL\\$Modules\\android-rss')


compile project(path: ':FragmentNavigator')

----------------
Gradle library
----------------

build.gradle

apply plugin: 'java'
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

----------

build.gradle

apply plugin: 'com.android.library'
android {
    compileSdkVersion 23    buildToolsVersion "23.0.3"
    defaultConfig {
        minSdkVersion 14        targetSdkVersion 23        versionCode 1        versionName "1.0"    }
    buildTypes {
        release {
            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.4.0'}

settings.gradle

include ':app', ':lib', ':mylibrary' //Include library




local.properties


ndk.dir=D\:\\Android\\AndroidSDK\\ndk-bundlesdk.dir=D\:\\Android\\AndroidSDK

================================================================


apply from: 'C:\\android\\versions.gradle'


android {
    compileSdkVersion versionCompile
    buildToolsVersion versionBuildTool
...
minSdkVersion versionMin
targetSdkVersion versionTarget


${versionSupportLib}
compile "com.android.support:design:${versionSupportLib}"
    compile "com.android.support:palette-v7:${versionSupportLib}"
    compile "com.android.support:cardview-v7:${versionSupportLib}"


=====================


project build.gradle

ext{
    versionCompile = 26
    versionBuildTool = '26.0.0 rc2'

    versionMin = 15
    versionTarget = 26
    versionSupportLib = '26.0.0-alpha1'


    okhttpVersion = '3.4.1'
    retrofitVersion = '2.1.0'
    rxandroidVersion = '1.2.1'
    rxjavaVersion = '1.1.10'
    rxLoaderVersion = '0.1.2'
    butterKnifeVersion = '8.3.0'
    hawkVersion = '1.23'

    junitVersion = '4.12'
    mockitoVersion = '1.10.19'
    powerMockVersion = '1.6.5'
    robolectricVersion = '3.1.2'
}


build.gradle
-- core

apply plugin: 'java'

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.google.code.gson:gson:2.8.0'
    compile 'com.google.code.findbugs:findbugs:3.0.1'
}

gradle.properties
# org.gradle.parallel=true
org.gradle.jvmargs=-Xmx1024m


gradlew build --stacktrace > logs.txt 2>logErrors.txt

🎭 Набор инструментов техномага

🛠 Инструменты разработки

  • Android Studio Portable - для быстрого доступа к Android разработке
  • VSCode Portable - легковесный редактор с поддержкой множества расширений
  • Git Portable - для контроля версий
  • Postman Portable - тестирование API
  • DBeaver Portable - универсальный инструмент для работы с БД

🔮 Утилиты для повышения продуктивности

  • AutoHotkey - автоматизация рутинных задач
  • Everything - мгновенный поиск файлов
  • Keypirinha - продвинутый лаунчер
  • ShareX - продвинутые скриншоты и запись экрана
  • SumatraPDF - быстрый просмотр PDF и технической документации

🧙‍♂️ Специальные инструменты техномага

  • WireShark Portable - анализ сетевого трафика
  • ProcessHacker - продвинутый диспетчер задач
  • RegShot - отслеживание изменений в системе
  • NirSoft Suite - набор системных утилит
  • PowerToys - расширенные возможности Windows

📱 Мобильная разработка

  • Scrcpy - управление Android устройством с ПК
  • ADB Platform Tools - отладка Android приложений
  • Charles Proxy - перехват и анализ HTTP/HTTPS трафика

🔐 Безопасность

  • KeePass - менеджер паролей
  • VeraCrypt - шифрование данных
  • OpenVPN - безопасное соединение

📊 Производительность

  • Obsidian Portable - создание базы знаний
  • Notion - организация проектов
  • Anki - система интервального повторения для изучения нового

🎨 Креативные инструменты

Это базовый набор, который можно дополнять специфическими инструментами под ваши конкретные задачи. Помните, что истинная сила техномага не в количестве инструментов, а в умении эффективно их использовать! 🧙‍♂️✨

android - ktor

 fun main() = runBlocking {
    val client = HttpClient(CIO) {
        install(ContentNegotiation)
        install(Logging) {
            level = LogLevel.ALL
        }
    }

    val filesToUpload = listOf(
        "/path/to/file1.jpg",
        "/path/to/file2.pdf"
    )

    val response: HttpResponse = client.post("https://example.com/upload") {
        setBody(
            MultiPartFormDataContent(
                formData {
                    filesToUpload.forEachIndexed { index, filePath ->
                        val file = java.io.File(filePath)
                        append(
                            key = "file$index",
                            value = file.readBytes(),
                            headers = Headers.build {
                                append(HttpHeaders.ContentDisposition, "form-data; name=\"file$index\"; filename=\"${file.name}\"")
                            }
                        )
                    }
                }
            )
        )
    }

    println("Response: ${response.status}, body: ${response.bodyAsText()}")

    client.close()
}

===
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.client.request.forms.*
import kotlinx.coroutines.*
import kotlinx.serialization.*
import java.io.File

// Пример POJO-класса (используем kotlinx.serialization для сериализации)
@Serializable
data class MyPojo(
    val id: Int,
    val name: String
)

fun main() = runBlocking {
    val client = HttpClient(CIO) {
        install(ContentNegotiation) {
            json() // Подключение JSON-сериализации
        }
    }

    val filesToUpload = listOf(
        File("/path/to/file1.jpg"),
        File("/path/to/file2.pdf")
    )

    // Создаем экземпляр POJO
    val myPojo = MyPojo(id = 123, name = "Example Name")

    val response: HttpResponse = client.post("https://example.com/upload") {
        setBody(
            MultiPartFormDataContent(
                formData {
                    // Добавляем JSON как часть формы
                    append(
                        key = "json",
                        value = kotlinx.serialization.json.Json.encodeToString(MyPojo.serializer(), myPojo),
                        headers = Headers.build {
                            append(HttpHeaders.ContentType, ContentType.Application.Json.toString())
                        }
                    )

                    // Добавляем файлы как части формы
                    filesToUpload.forEachIndexed { index, file ->
                        append(
                            key = "file$index",
                            value = file.readBytes(),
                            headers = Headers.build {
                                append(HttpHeaders.ContentDisposition, "form-data; name=\"file$index\"; filename=\"${file.name}\"")
                            }
                        )
                    }
                }
            )
        )
    }

    println("Response: ${response.status}, body: ${response.bodyAsText()}")

    client.close()
}
====


fun main() = runBlocking {
    val client = HttpClient(CIO) {
        install(ContentNegotiation) {
            json()
        }
    }

    val filesToUpload = listOf(
        File("/path/to/largefile1.mp4"),
        File("/path/to/largefile2.zip")
    )

    val myPojo = MyPojo(id = 123, name = "Example Data")

    val response: HttpResponse = client.post("https://example.com/upload") {
        setBody(
            MultiPartFormDataContent(
                formData {
                    // Добавляем JSON как часть формы
                    append(
                        key = "json",
                        value = kotlinx.serialization.json.Json.encodeToString(MyPojo.serializer(), myPojo),
                        headers = Headers.build {
                            append(HttpHeaders.ContentType, ContentType.Application.Json.toString())
                        }
                    )

                    // Добавляем файлы с использованием потоков
                    filesToUpload.forEachIndexed { index, file ->
                        appendInput(
                            key = "file$index",
                            headers = Headers.build {
                                append(HttpHeaders.ContentDisposition, "form-data; name=\"file$index\"; filename=\"${file.name}\"")
                            },
                            size = file.length()
                        ) {
                            file.inputStream() // Поток файла
                        }
                    }
                }
            )
        )
    }

    println("Response: ${response.status}, body: ${response.bodyAsText()}")

    client.close()
}



===

val response: HttpResponse = client.post("https://example.com/upload") {
        setBody(
            MultiPartFormDataContent(
                formData {
                    // Добавляем JSON как часть формы
                    append(
                        key = "json",
                        value = kotlinx.serialization.json.Json.encodeToString(MyPojo.serializer(), myPojo),
                        headers = Headers.build {
                            append(HttpHeaders.ContentType, ContentType.Application.Json.toString())
                        }
                    )

                    // Добавляем файлы с использованием массива ключей files[]
                    filesToUpload.forEach { file ->
                        appendInput(
                            key = "files[]", // Массив файлов с ключом files[]
                            headers = Headers.build {
                                append(HttpHeaders.ContentDisposition, "form-data; name=\"files[]\"; filename=\"${file.name}\"")
                            },
                            size = file.length()
                        ) {
                            file.inputStream()
                        }
                    }
                }
            )
        )
    }
    
    
    ===
    
    
    <?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Чтение JSON
    $json = json_decode($_POST['json'], true);
    print_r($json); // Данные JSON

    // Обработка файлов
    foreach ($_FILES['files']['name'] as $index => $name) {
        $tmpName = $_FILES['files']['tmp_name'][$index];
        $size = $_FILES['files']['size'][$index];
        $error = $_FILES['files']['error'][$index];

        if ($error === UPLOAD_ERR_OK) {
            $destination = "uploads/" . basename($name);
            move_uploaded_file($tmpName, $destination);
            echo "Файл $name успешно загружен в $destination\n";
        } else {
            echo "Ошибка при загрузке файла $name\n";
        }
    }
}
?>
===
передача JSON в теле запроса (body) несовместима с форматом multipart/form-data

===

Если сервер поддерживает multipart/form-data


"""
Speech to Text
Speech to Text

ACTION_RECOGNIZE_SPEECH


private const val BASE_URL = "https://jsonplaceholder.typicode.com/"

private const val TIME_OUT = 6000

suspend fun makeRequest() {


    val client = HttpClient(Android) {

        install(Logging) {
            logger = object : Logger {
                override fun log(message: String) {
                    Log.d("@@@:", message)
                }
            }
        }

        engine {
            // this: AndroidEngineConfig
            connectTimeout = 100_000
            socketTimeout = 100_000
            //proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("localhost", 8080))
        }
    }

    val client0 = HttpClient(CIO) {

    }

    val response: HttpResponse = client.request("https://ktor.io/") {
        // Configure request parameters exposed by HttpRequestBuilder
    }
    println("======"+response.bodyAsText())
}

=====

dependencies {
    implementation "androidx.compose.material:material-icons-extended:$compose_ui_version"
}

Step 3: Working with the MainActivity.kt file

Go to the MainActivity.kt file and refer to the following code. Below is the code for the MainActivity.kt file. Comments are added inside the code to understand the code in more detail.
Kotlin




package com.geeksforgeeks.passwordtoggle
 
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
 
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
 
            // Creating a Simple Scaffold
            // Layout for the application
            Scaffold(
 
                // Creating a Top Bar
                topBar = { TopAppBar(title = { Text("GFG | Toggle Password", color = Color.White) }, backgroundColor = Color(0xff0f9d58)) },
 
                // Creating Content
                content = {
 
                    // Creating a Column Layout
                    Column(Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) {
 
                        // Creating a variable to store password
                        var password by remember { mutableStateOf("") }
                         
                        // Creating a variable to store toggle state
                        var passwordVisible by remember { mutableStateOf(false) }
 
                        // Create a Text Field for giving password input
                        TextField(
                            value = password,
                            onValueChange = { password = it },
                            label = { Text("Password") },
                            singleLine = true,
                            placeholder = { Text("Password") },
                            visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
                            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
                            trailingIcon = {
                                val image = if (passwordVisible)
                                    Icons.Filled.Visibility
                                else Icons.Filled.VisibilityOff
 
                                // Localized description for accessibility services
                                val description = if (passwordVisible) "Hide password" else "Show password"
 
                                // Toggle button to hide or display password
                                IconButton(onClick = {passwordVisible = !passwordVisible}){
                                    Icon(imageVector  = image, description)
                                }
                            }
                        )
 
                    }
                }
            )
        }
    }
}
 
/*
Note: to use Icons.Filled.Visibility and Icons.Filled.VisibilityOff
add in the dependencies: implementation "androidx.compose.material:material-icons-extended:$compose_version"
*/
===

https://www.youtube.com/watch?app=desktop&v=4MJFmhcONfI&ab_channel=PhilippLackner

implementation "androidx.compose.material:material-icons-extended:1.3.1"
https://medium.com/google-developer-experts/how-to-create-a-composable-password-with-jetpack-compose-f1be2d48d9f0