Drop force activating feature, close #114

Update README files
Add AppLockDialog to DhizukuActivity
Improve UI
Upgrade dependencies
This commit is contained in:
BinTianqi
2025-06-01 12:36:25 +08:00
parent 21ddb5a98d
commit fb40708f0d
22 changed files with 175 additions and 307 deletions

View File

@@ -8,6 +8,8 @@ import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.size
import androidx.compose.material3.AlertDialog
@@ -16,11 +18,14 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
import com.google.accompanist.drawablepainter.rememberDrawablePainter
import com.rosan.dhizuku.aidl.IDhizukuClient
import com.rosan.dhizuku.aidl.IDhizukuRequestPermissionListener
@@ -97,43 +102,52 @@ class DhizukuActivity : ComponentActivity() {
if (grantPermission) PackageManager.PERMISSION_GRANTED else PackageManager.PERMISSION_DENIED
)
}
val vm by viewModels<MyViewModel>()
enableEdgeToEdge()
setContent {
AlertDialog(
icon = {
Image(rememberDrawablePainter(icon), null, Modifier.size(35.dp))
},
title = {
Text(stringResource(R.string.request_permission))
},
text = {
Text("$label\n($packageName)")
},
confirmButton = {
var time by remember { mutableIntStateOf(3) }
LaunchedEffect(Unit) {
(1..3).forEach {
delay(1000)
time -= 1
var appLockDialog by remember { mutableStateOf(false) }
val theme by vm.theme.collectAsStateWithLifecycle()
OwnDroidTheme(theme) {
if (!appLockDialog) AlertDialog(
icon = {
Image(rememberDrawablePainter(icon), null, Modifier.size(35.dp))
},
title = {
Text(stringResource(R.string.request_permission))
},
text = {
Text("$label\n($packageName)")
},
confirmButton = {
var time by remember { mutableIntStateOf(3) }
LaunchedEffect(Unit) {
(1..3).forEach {
delay(1000)
time -= 1
}
}
}
TextButton({
close(true)
}, enabled = time == 0) {
val append = if (time > 0) " (${time}s)" else ""
Text(stringResource(R.string.allow) + append)
}
},
dismissButton = {
TextButton({
close(false)
}) {
Text(stringResource(R.string.reject))
}
},
onDismissRequest = {
finish()
}
)
TextButton({
if (SharedPrefs(this).lockPasswordHash.isNullOrEmpty()) {
close(true)
} else {
appLockDialog = true
}
}, enabled = time == 0) {
val append = if (time > 0) " (${time}s)" else ""
Text(stringResource(R.string.allow) + append)
}
},
dismissButton = {
TextButton({
close(false)
}) {
Text(stringResource(R.string.reject))
}
},
onDismissRequest = { close(false) }
)
else AppLockDialog({ close(true) }) { close(false) }
}
}
}
}

View File

@@ -12,9 +12,10 @@ import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@@ -48,7 +49,6 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
@@ -249,7 +249,6 @@ import java.util.Locale
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
val context = applicationContext
if (VERSION.SDK_INT >= 28) HiddenApiBypass.setHiddenApiExemptions("")
@@ -309,7 +308,6 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
modifier = Modifier
.fillMaxSize()
.background(colorScheme.background)
.imePadding()
.pointerInput(Unit) { detectTapGestures(onTap = { focusMgr.clearFocus() }) },
enterTransition = Animations.navHostEnterTransition,
exitTransition = Animations.navHostExitTransition,
@@ -514,7 +512,8 @@ private fun HomeScreen(onNavigate: (Any) -> Unit) {
},
scrollBehavior = sb
)
}
},
contentWindowInsets = WindowInsets.ime
) {
Column(Modifier.fillMaxSize().padding(it).verticalScroll(rememberScrollState())) {
if(privilege.device || privilege.profile) {

View File

@@ -10,16 +10,18 @@ import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
@@ -75,6 +77,7 @@ class PackageChooserActivity: ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val vm by viewModels<MyViewModel>()
enableEdgeToEdge()
setContent {
val theme by vm.theme.collectAsStateWithLifecycle()
OwnDroidTheme(theme) {
@@ -177,7 +180,8 @@ fun AppChooserScreen(params: ApplicationsList, onChoosePackage: (String?) -> Uni
},
colors = TopAppBarDefaults.topAppBarColors(MaterialTheme.colorScheme.surfaceContainer)
)
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
LazyColumn(Modifier.fillMaxSize().padding(paddingValues)) {
if (progress < 1F) stickyHeader {

View File

@@ -12,8 +12,10 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.rememberScrollState
@@ -116,7 +118,8 @@ fun SettingsScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
}
}
)
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
Column(
modifier = Modifier

View File

@@ -23,8 +23,10 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyItemScope
@@ -172,7 +174,8 @@ fun ApplicationsFeaturesScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Un
},
scrollBehavior = sb
)
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
Column(
Modifier

View File

@@ -520,6 +520,7 @@ fun handlePrivilegeChange(context: Context) {
val privilege = myPrivilege.value
val activated = privilege.device || privilege.profile
val sp = SharedPrefs(context)
sp.dhizukuServer = false
if(activated) {
createShortcuts(context)
if(!privilege.dhizuku) {

View File

@@ -51,8 +51,10 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
@@ -239,7 +241,8 @@ fun WifiScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit, onNavigateTo
navigationIcon = { NavIcon(onNavigateUp) },
colors = TopAppBarDefaults.topAppBarColors(MaterialTheme.colorScheme.surfaceContainer)
)
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
var wifiMacDialog by remember { mutableStateOf(false) }
Column(

View File

@@ -1,19 +1,10 @@
package com.bintianqi.owndroid.dpm
import android.annotation.SuppressLint
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager
import android.os.Build.VERSION
import android.os.Bundle
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.os.Message
import android.os.Messenger
import android.os.PersistableBundle
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.annotation.Keep
@@ -29,13 +20,14 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.text.selection.SelectionContainer
@@ -44,6 +36,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.outlined.Edit
@@ -55,6 +48,7 @@ import androidx.compose.material3.Checkbox
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme.colorScheme
@@ -86,7 +80,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.core.os.bundleOf
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bintianqi.owndroid.ChoosePackageContract
import com.bintianqi.owndroid.DHIZUKU_CLIENTS_FILE
@@ -114,14 +107,10 @@ import com.google.accompanist.drawablepainter.rememberDrawablePainter
import com.rosan.dhizuku.api.Dhizuku
import com.rosan.dhizuku.api.DhizukuRequestPermissionListener
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ipc.RootService
import dalvik.system.DexClassLoader
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import java.lang.invoke.MethodHandles
import java.lang.reflect.Proxy
@Serializable data class WorkModes(val canNavigateUp: Boolean)
@@ -134,7 +123,7 @@ fun WorkModesScreen(
val context = LocalContext.current
val coroutine = rememberCoroutineScope()
val privilege by myPrivilege.collectAsStateWithLifecycle()
/** 0: none, 1: device owner, 2: circular progress indicator, 3: result, 4: deactivate, 5: command, 6: force activating warning */
/** 0: none, 1: device owner, 2: circular progress indicator, 3: result, 4: deactivate, 5: command */
var dialog by remember { mutableIntStateOf(0) }
Scaffold(
topBar = {
@@ -162,21 +151,24 @@ fun WorkModesScreen(
{
expanded = false
dialog = 4
}
},
leadingIcon = { Icon(Icons.Default.Close, null) }
)
if (VERSION.SDK_INT >= 26) DropdownMenuItem(
{ Text(stringResource(R.string.delegated_admins)) },
{
expanded = false
onNavigate(DelegatedAdmins)
}
},
leadingIcon = { Icon(painterResource(R.drawable.admin_panel_settings_fill0), null) }
)
if (!privilege.dhizuku && VERSION.SDK_INT >= 28) DropdownMenuItem(
{ Text(stringResource(R.string.transfer_ownership)) },
{
expanded = false
onNavigate(TransferOwnership)
}
},
leadingIcon = { Icon(painterResource(R.drawable.swap_horiz_fill0), null) }
)
}
}
@@ -185,7 +177,8 @@ fun WorkModesScreen(
}
}
)
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
var navigateUpOnSucceed by remember { mutableStateOf(true) }
var operationSucceed by remember { mutableStateOf(false) }
@@ -198,6 +191,7 @@ fun WorkModesScreen(
updatePrivilege(context)
handlePrivilegeChange(context)
} else {
dialog = 0
context.showOperationResultToast(false)
}
}
@@ -315,12 +309,6 @@ fun WorkModesScreen(
}
Spacer(Modifier.padding(horizontal = 2.dp))
Button({ dialog = 5 }) { Text(stringResource(R.string.adb_command)) }
Spacer(Modifier.padding(horizontal = 2.dp))
if (VERSION.SDK_INT >= 33) Button({
dialog = 6
}) {
Text(stringResource(R.string.root_force_activate))
}
}
},
confirmButton = {
@@ -386,23 +374,6 @@ fun WorkModesScreen(
},
onDismissRequest = { dialog = 0 }
)
if (dialog == 6) AlertDialog(
title = { Text(stringResource(R.string.warning)) },
text = { Text(stringResource(R.string.info_force_activate)) },
confirmButton = {
TextButton({
dialog = 2
navigateUpOnSucceed = false
forceActivateUsingRoot(context, ::handleResult)
}) {
Text(stringResource(R.string.continue_str))
}
},
dismissButton = {
TextButton({ dialog = 0 }) { Text(stringResource(R.string.cancel)) }
},
onDismissRequest = { dialog = 0 }
)
}
}
@@ -469,75 +440,6 @@ fun activateUsingDhizuku(context: Context, callback: (Boolean, Boolean, String?)
}
}
fun forceActivateUsingRoot(context: Context, callback: (Boolean, Boolean, String?) -> Unit) {
val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val handler = Handler(Looper.getMainLooper()) { msg ->
RootService.unbind(this)
val data = msg.data
val output = if (data.getBoolean("succeed")) context.getString(R.string.please_reboot) else null
callback(!data.getBoolean("error"), data.getBoolean("succeed"), output)
return@Handler true
}
val msg = Message()
msg.replyTo = Messenger(handler)
Messenger(service).send(msg)
}
override fun onServiceDisconnected(name: ComponentName?) {}
}
val intent = Intent(context, ForceActivateService::class.java)
RootService.bind(intent, connection)
}
@RequiresApi(26)
class ForceActivateService(): RootService() {
override fun onBind(intent: Intent): IBinder = messenger.binder
val handler = Handler(Looper.getMainLooper()) { msg ->
val replyMessage = Message()
try {
replyMessage.data = activateDeviceOwnerAsRoot(getReceiver()).apply { putBoolean("error", false) }
} catch (e: Exception) {
e.printStackTrace()
replyMessage.data = bundleOf("error" to true, "succeed" to false)
}
msg.replyTo.send(replyMessage)
return@Handler false
}
val messenger = Messenger(handler)
}
@SuppressLint("PrivateApi")
@RequiresApi(26)
fun activateDeviceOwnerAsRoot(cn: ComponentName): Bundle {
val dcl = DexClassLoader(
"/system/framework/services.jar", "/data/local/tmp", null, ClassLoader.getSystemClassLoader()
)
val ppp = dcl.loadClass("com.android.server.devicepolicy.PolicyPathProvider")
val pppProxy = Proxy.newProxyInstance(ppp.classLoader, arrayOf(ppp)) { obj, method, args ->
method.isAccessible = true
val mh = MethodHandles.lookup().`in`(ppp).unreflectSpecial(method, ppp).bindTo(obj)
return@newProxyInstance if (args == null) {
mh.invokeWithArguments()
} else {
mh.invokeWithArguments(*args)
}
}
val od = dcl.loadClass("com.android.server.devicepolicy.OwnersData")
val odIns = od.getConstructor(ppp).apply { isAccessible = true }.newInstance(pppProxy)
val oi = dcl.loadClass("com.android.server.devicepolicy.OwnersData\$OwnerInfo")
val oiIns = oi.constructors[0].apply { isAccessible = true }.newInstance(cn, null, null, true)
od.getField("mDeviceOwner").apply { isAccessible = true }.set(odIns, oiIns)
od.getField("mDeviceOwnerUserId").apply { isAccessible = true }.set(odIns, 0)
val setDoResult = od.getMethod("writeDeviceOwner").apply { isAccessible = true }.invoke(odIns) as Boolean
return if (setDoResult) {
val proc = Runtime.getRuntime().exec("dpm set-active-admin ${cn.flattenToShortString()}")
proc.waitFor()
bundleOf("succeed" to true)
} else {
bundleOf("succeed" to false)
}
}
fun activateDhizukuMode(context: Context, callback: (Boolean, Boolean, String?) -> Unit) {
fun onSucceed() {
SharedPrefs(context).dhizuku = true
@@ -589,7 +491,7 @@ fun DhizukuServerSettingsScreen(onNavigateUp: () -> Unit) {
MyLazyScaffold(R.string.dhizuku_server, onNavigateUp) {
item {
SwitchItem(R.string.enable, getState = { sp.dhizukuServer }, onCheckedChange = ::changeEnableState)
Spacer(Modifier.padding(vertical = 8.dp))
HorizontalDivider(Modifier.padding(vertical = 8.dp))
}
if (enabled) itemsIndexed(clients) { index, client ->
val name = pm.getNameForUid(client.uid)
@@ -599,16 +501,13 @@ fun DhizukuServerSettingsScreen(onNavigateUp: () -> Unit) {
} else {
val info = pm.getApplicationInfo(name, 0)
Row(
Modifier
.fillMaxWidth().padding(8.dp)
.background(colorScheme.surfaceVariant, RoundedCornerShape(8.dp))
.padding(8.dp),
Modifier.fillMaxWidth().padding(HorizontalPadding, 8.dp),
Arrangement.SpaceBetween, Alignment.CenterVertically
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Image(
rememberDrawablePainter(info.loadIcon(pm)), null,
Modifier.padding(end = 12.dp).size(50.dp)
Modifier.padding(end = 16.dp).size(50.dp)
)
Text(info.loadLabel(pm).toString(), style = typography.titleLarge)
}

View File

@@ -47,8 +47,10 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
@@ -1104,7 +1106,8 @@ fun LockTaskModeScreen(onNavigateUp: () -> Unit) {
navigationIcon = { NavIcon(onNavigateUp) },
colors = TopAppBarDefaults.topAppBarColors(colorScheme.surfaceContainer)
)
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
Column(
modifier = Modifier
@@ -1405,7 +1408,8 @@ fun CaCertScreen(onNavigateUp: () -> Unit) {
}) {
Icon(Icons.Default.Add, stringResource(R.string.install))
}
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
LazyColumn(
Modifier

View File

@@ -12,8 +12,11 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
@@ -101,7 +104,8 @@ fun UserRestrictionScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
},
scrollBehavior = sb
)
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
Column(
modifier = Modifier
@@ -299,7 +303,8 @@ fun UserRestrictionEditorScreen(onNavigateUp: () -> Unit) {
title = { Text(stringResource(R.string.edit)) },
navigationIcon = { NavIcon(onNavigateUp) }
)
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
LazyColumn(Modifier.fillMaxSize().padding(paddingValues)) {
items(list, { it }) {

View File

@@ -10,8 +10,10 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
@@ -294,7 +296,8 @@ fun MyScaffold(
navigationIcon = { NavIcon(onNavIconClicked) },
scrollBehavior = sb
)
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
Column(
modifier = Modifier
@@ -325,7 +328,8 @@ fun MyLazyScaffold(
navigationIcon = { NavIcon(onNavIconClicked) },
scrollBehavior = sb
)
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
LazyColumn(Modifier.fillMaxSize().padding(paddingValues), content = content)
}
@@ -346,7 +350,8 @@ fun MySmallTitleScaffold(
navigationIcon = { NavIcon(onNavIconClicked) },
colors = TopAppBarDefaults.topAppBarColors(colorScheme.surfaceContainer)
)
}
},
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
Column(
modifier = Modifier

View File

@@ -3,7 +3,11 @@ package com.bintianqi.owndroid.ui.theme
import android.app.Activity
import android.os.Build.VERSION
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.Color
@@ -106,7 +110,7 @@ fun OwnDroidTheme(
}
val view = LocalView.current
SideEffect {
val window = (view.context as Activity).window
val window = (context as Activity).window
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
}
MaterialTheme(