mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 11:05:59 +00:00
feat: app groups importing and exporting (#222)
Show group name in app group operation dialog (#224)
This commit is contained in:
@@ -642,7 +642,7 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
|||||||
}
|
}
|
||||||
composable<ManageAppGroups> {
|
composable<ManageAppGroups> {
|
||||||
ManageAppGroupsScreen(
|
ManageAppGroupsScreen(
|
||||||
vm.appGroups,
|
vm.appGroups, vm::exportAppGroups, vm::importAppGroups,
|
||||||
{ id, name, apps -> navController.navigate(EditAppGroup(id, name, apps)) },
|
{ id, name, apps -> navController.navigate(EditAppGroup(id, name, apps)) },
|
||||||
::navigateUp
|
::navigateUp
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ import com.bintianqi.owndroid.dpm.ApnProtocol
|
|||||||
import com.bintianqi.owndroid.dpm.AppGroup
|
import com.bintianqi.owndroid.dpm.AppGroup
|
||||||
import com.bintianqi.owndroid.dpm.AppRestriction
|
import com.bintianqi.owndroid.dpm.AppRestriction
|
||||||
import com.bintianqi.owndroid.dpm.AppStatus
|
import com.bintianqi.owndroid.dpm.AppStatus
|
||||||
|
import com.bintianqi.owndroid.dpm.BasicAppGroup
|
||||||
import com.bintianqi.owndroid.dpm.CaCertInfo
|
import com.bintianqi.owndroid.dpm.CaCertInfo
|
||||||
import com.bintianqi.owndroid.dpm.CreateUserResult
|
import com.bintianqi.owndroid.dpm.CreateUserResult
|
||||||
import com.bintianqi.owndroid.dpm.CreateWorkProfileOptions
|
import com.bintianqi.owndroid.dpm.CreateWorkProfileOptions
|
||||||
@@ -119,6 +120,10 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.addJsonObject
|
||||||
|
import kotlinx.serialization.json.buildJsonArray
|
||||||
|
import kotlinx.serialization.json.put
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.security.cert.CertificateException
|
import java.security.cert.CertificateException
|
||||||
@@ -632,6 +637,20 @@ class MyViewModel(application: Application): AndroidViewModel(application) {
|
|||||||
group.filter { it.id != id }
|
group.filter { it.id != id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun exportAppGroups(uri: Uri) {
|
||||||
|
application.contentResolver.openOutputStream(uri)!!.use {
|
||||||
|
val list: List<BasicAppGroup> = appGroups.value
|
||||||
|
it.write(Json.encodeToString(list).encodeToByteArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun importAppGroups(uri: Uri) {
|
||||||
|
application.contentResolver.openInputStream(uri)!!.use {
|
||||||
|
Json.decodeFromString<List<BasicAppGroup>>(it.readBytes().decodeToString())
|
||||||
|
}.forEach {
|
||||||
|
myRepo.setAppGroup(null, it.name, it.apps)
|
||||||
|
}
|
||||||
|
getAppGroups()
|
||||||
|
}
|
||||||
|
|
||||||
@RequiresApi(24)
|
@RequiresApi(24)
|
||||||
fun reboot() {
|
fun reboot() {
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ import android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED
|
|||||||
import android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
|
import android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
|
||||||
import android.app.admin.PackagePolicy
|
import android.app.admin.PackagePolicy
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@@ -904,6 +907,8 @@ fun PackageFunctionScreen(
|
|||||||
if (dialog) AlertDialog(
|
if (dialog) AlertDialog(
|
||||||
text = {
|
text = {
|
||||||
Column {
|
Column {
|
||||||
|
Text(selectedGroup!!.name, style = typography.titleLarge)
|
||||||
|
Spacer(Modifier.height(6.dp))
|
||||||
Button({
|
Button({
|
||||||
onSet(selectedGroup!!.apps, true)
|
onSet(selectedGroup!!.apps, true)
|
||||||
dialog = false
|
dialog = false
|
||||||
@@ -927,22 +932,68 @@ fun PackageFunctionScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppGroup(val id: Int, val name: String, val apps: List<String>)
|
@Serializable
|
||||||
|
open class BasicAppGroup(open val name: String, open val apps: List<String>)
|
||||||
|
|
||||||
|
class AppGroup(
|
||||||
|
val id: Int, override val name: String, override val apps: List<String>
|
||||||
|
) : BasicAppGroup(name, apps)
|
||||||
|
|
||||||
@Serializable object ManageAppGroups
|
@Serializable object ManageAppGroups
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ManageAppGroupsScreen(
|
fun ManageAppGroupsScreen(
|
||||||
appGroups: StateFlow<List<AppGroup>>,
|
appGroups: StateFlow<List<AppGroup>>, exportData: (Uri) -> Unit, importData: (Uri) -> Unit,
|
||||||
navigateToEditScreen: (Int?, String, List<String>) -> Unit, navigateUp: () -> Unit
|
navigateToEditScreen: (Int?, String, List<String>) -> Unit, navigateUp: () -> Unit
|
||||||
) {
|
) {
|
||||||
val groups by appGroups.collectAsStateWithLifecycle()
|
val groups by appGroups.collectAsStateWithLifecycle()
|
||||||
|
val exportLauncher = rememberLauncherForActivityResult(
|
||||||
|
ActivityResultContracts.CreateDocument("application/json")
|
||||||
|
) {
|
||||||
|
if (it != null) exportData(it)
|
||||||
|
}
|
||||||
|
val importLauncher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) {
|
||||||
|
if (it != null) importData(it)
|
||||||
|
}
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
{ Text(stringResource(R.string.app_group)) },
|
{ Text(stringResource(R.string.app_group)) },
|
||||||
navigationIcon = { NavIcon(navigateUp) }
|
navigationIcon = { NavIcon(navigateUp) },
|
||||||
|
actions = {
|
||||||
|
var dropdown by remember { mutableStateOf(false) }
|
||||||
|
Box {
|
||||||
|
IconButton({
|
||||||
|
dropdown = true
|
||||||
|
}) {
|
||||||
|
Icon(Icons.Default.MoreVert, null)
|
||||||
|
}
|
||||||
|
DropdownMenu(dropdown, { dropdown = false }) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
{ Text(stringResource(R.string.export)) },
|
||||||
|
{
|
||||||
|
exportLauncher.launch("owndroid_app_groups")
|
||||||
|
dropdown = false
|
||||||
|
},
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(painterResource(R.drawable.file_export_fill0), null)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
DropdownMenuItem(
|
||||||
|
{ Text(stringResource(R.string.import_str)) },
|
||||||
|
{
|
||||||
|
importLauncher.launch(arrayOf("application/json"))
|
||||||
|
dropdown = false
|
||||||
|
},
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(painterResource(R.drawable.file_open_fill0), null)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
|
|||||||
9
app/src/main/res/drawable/file_export_fill0.xml
Normal file
9
app/src/main/res/drawable/file_export_fill0.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960">
|
||||||
|
<path
|
||||||
|
android:pathData="M480,480ZM202,895l-56,-57 118,-118h-90v-80h226v226h-80v-89L202,895ZM480,880v-80h240v-440L520,360v-200L240,160v400h-80v-400q0,-33 23.5,-56.5T240,80h320l240,240v480q0,33 -23.5,56.5T720,880L480,880Z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/file_open_fill0.xml
Normal file
9
app/src/main/res/drawable/file_open_fill0.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960">
|
||||||
|
<path
|
||||||
|
android:pathData="M240,880q-33,0 -56.5,-23.5T160,800v-640q0,-33 23.5,-56.5T240,80h320l240,240v240h-80v-200L520,360v-200L240,160v640h360v80L240,880ZM878,895L760,777v89h-80v-226h226v80h-90l118,118 -56,57ZM240,800v-640,640Z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</vector>
|
||||||
@@ -376,6 +376,7 @@
|
|||||||
<string name="search">搜索</string>
|
<string name="search">搜索</string>
|
||||||
<string name="app_group">应用组</string>
|
<string name="app_group">应用组</string>
|
||||||
<string name="manage_app_groups">管理组</string>
|
<string name="manage_app_groups">管理组</string>
|
||||||
|
<string name="import_str">导入</string>
|
||||||
<string name="edit_app_group">编辑组</string>
|
<string name="edit_app_group">编辑组</string>
|
||||||
<string name="add_to_list">添加到列表</string>
|
<string name="add_to_list">添加到列表</string>
|
||||||
<string name="remove_from_list">从列表中移除</string>
|
<string name="remove_from_list">从列表中移除</string>
|
||||||
|
|||||||
@@ -410,6 +410,7 @@
|
|||||||
<string name="search">Search</string>
|
<string name="search">Search</string>
|
||||||
<string name="app_group">App group</string>
|
<string name="app_group">App group</string>
|
||||||
<string name="manage_app_groups">Manage groups</string>
|
<string name="manage_app_groups">Manage groups</string>
|
||||||
|
<string name="import_str">Import</string>
|
||||||
<string name="edit_app_group">Edit group</string>
|
<string name="edit_app_group">Edit group</string>
|
||||||
<string name="add_to_list">Add to list</string>
|
<string name="add_to_list">Add to list</string>
|
||||||
<string name="remove_from_list">Remove from list</string>
|
<string name="remove_from_list">Remove from list</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user